From abf6b971fa074182cfe789bc58f6d6ae8440a6ce Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Tue, 11 Apr 2023 13:40:18 +0200 Subject: [PATCH 01/65] Refactor media API and add a new audio navigator (#345) --- docs/guides/tts.md | 2 + gradle/libs.versions.toml | 2 +- .../r2/navigator/media3/api/AudioNavigator.kt | 93 +++++++ .../media3/api/DefaultMediaMetadataFactory.kt | 47 ++-- .../api/DefaultMediaMetadataProvider.kt | 3 +- .../r2/navigator/media3/api/MediaNavigator.kt | 66 ++++- .../media3/api/SynchronizedMediaNavigator.kt | 33 --- .../media3/api/TextAwareMediaNavigator.kt | 126 +++++++++ .../r2/navigator/media3/audio/AudioEngine.kt | 94 ++++++- .../media3/audio/AudioEngineProvider.kt | 12 +- .../navigator/media3/audio/AudioNavigator.kt | 70 ----- .../media3/audio/AudioNavigatorFactory.kt | 59 ++++ .../media3/audio/AudiobookNavigator.kt | 227 +++++++++++++++ .../media3/audio/DurationSerializer.kt | 28 -- .../media3/audio/MetadataRetriever.kt | 76 +++++ .../r2/navigator/media3/audio/SmartSeeker.kt | 62 +++++ .../media3/exoplayer/ExoAudiobookPlayer.kt | 68 +++++ .../media3/exoplayer/ExoPlayerAliases.kt | 17 ++ .../media3/exoplayer/ExoPlayerDataSource.kt | 4 +- .../media3/exoplayer/ExoPlayerDefaults.kt | 28 ++ .../media3/exoplayer/ExoPlayerEngine.kt | 221 +++++++++++++-- .../exoplayer/ExoPlayerEngineProvider.kt | 64 ++++- .../media3/exoplayer/ExoPlayerPreferences.kt | 12 +- .../exoplayer/ExoPlayerPreferencesEditor.kt | 66 ++++- .../exoplayer/ExoPlayerPreferencesFilters.kt | 30 -- .../media3/exoplayer/ExoPlayerSettings.kt | 8 +- .../exoplayer/ExoPlayerSettingsResolver.kt | 10 +- .../media3/syncmedia/GuidedAudioNavigator.kt | 137 +++++++++ .../r2/navigator/media3/tts/TtsEngine.kt | 2 +- .../r2/navigator/media3/tts/TtsNavigator.kt | 109 +++++--- .../r2/navigator/media3/tts/TtsPlayer.kt | 43 +++ .../media3/tts/android/AndroidTtsEngine.kt | 262 ++++++++++++++---- .../tts/android/AndroidTtsSettingsResolver.kt | 4 +- .../media3/tts/session/TtsSessionAdapter.kt | 15 +- .../media3/tts/session/TtsTimeline.kt | 5 +- .../r2/navigator/audio/SmartSeekerTest.kt | 108 ++++++++ .../org/readium/r2/shared/extensions/Flow.kt | 22 +- .../java/org/readium/r2/shared/units/Hertz.kt | 12 + test-app/src/main/AndroidManifest.xml | 19 +- .../r2/testapp/reader/AudioReaderFragment.kt | 95 ++++--- .../readium/r2/testapp/reader/MediaService.kt | 115 ++++---- ...ServiceFacade.kt => MediaServiceFacade.kt} | 29 +- .../r2/testapp/reader/ReaderInitData.kt | 28 +- .../r2/testapp/reader/ReaderRepository.kt | 67 ++--- .../r2/testapp/reader/ReaderViewModel.kt | 1 - .../reader/preferences/PreferencesManagers.kt | 6 +- .../reader/preferences/UserPreferences.kt | 86 +++--- .../preferences/UserPreferencesViewModel.kt | 19 +- .../r2/testapp/reader/tts/TtsControls.kt | 3 - .../reader/tts/TtsPreferencesEditor.kt | 1 - .../r2/testapp/reader/tts/TtsService.kt | 185 ------------- .../r2/testapp/reader/tts/TtsViewModel.kt | 45 +-- test-app/src/main/res/values/strings.xml | 1 - 53 files changed, 2130 insertions(+), 817 deletions(-) create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/AudioNavigator.kt delete mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/SynchronizedMediaNavigator.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt delete mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt delete mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/DurationSerializer.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/SmartSeeker.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDefaults.kt delete mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesFilters.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt create mode 100644 readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/units/Hertz.kt rename test-app/src/main/java/org/readium/r2/testapp/reader/{tts/TtsServiceFacade.kt => MediaServiceFacade.kt} (66%) delete mode 100644 test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsService.kt diff --git a/docs/guides/tts.md b/docs/guides/tts.md index 5a15ead559..3b7b80b471 100644 --- a/docs/guides/tts.md +++ b/docs/guides/tts.md @@ -14,6 +14,8 @@ Text-to-speech can be used to read aloud a publication using a synthetic voice. ## Reading a publication aloud +Apps targeting Android 11 that use text-to-speech should declare INTENT_ACTION_TTS_SERVICE in the queries elements of their manifest. + To read a publication, you need to create an instance of `PublicationSpeechSynthesizer`. It orchestrates the rendition of a publication by iterating through its content, splitting it into individual utterances using a `ContentTokenizer`, then using a `TtsEngine` to read them aloud. Not all publications can be read using TTS, therefore the constructor returns a nullable object. You can also check whether a publication can be played beforehand using `PublicationSpeechSynthesizer.canSpeak(publication)`. ```kotlin diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a32be7e185..8118c15a0b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ androidx-lifecycle = "2.5.1" androidx-lifecycle-extensions = "2.2.0" androidx-media = "1.6.0" androidx-media2 = "1.2.1" -androidx-media3 = "1.0.0-rc01" +androidx-media3 = "1.0.0" androidx-navigation = "2.5.2" androidx-paging = "3.1.1" androidx-recyclerview = "1.2.1" diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/AudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/AudioNavigator.kt new file mode 100644 index 0000000000..41227cacb4 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/AudioNavigator.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.api + +import kotlin.time.Duration +import kotlinx.coroutines.flow.StateFlow +import org.readium.r2.shared.ExperimentalReadiumApi + +/** + * A [MediaNavigator] which can play audio files. + */ +@ExperimentalReadiumApi +interface AudioNavigator : MediaNavigator { + + /** + * Location of the navigator. + */ + interface Location : MediaNavigator.Location { + + /** + * The duration offset in the resource. + */ + val offset: Duration + } + + /** + * State of the playback. + */ + interface Playback : MediaNavigator.Playback { + + /** + * Position of the playback in the current item. + */ + val offset: Duration + + /** + * Position in the current item until which the content is buffered. + */ + val buffered: Duration? + } + + /** + * Data about the content to play. + */ + interface ReadingOrder : MediaNavigator.ReadingOrder { + + /** + * Total duration of the content to play. + */ + val duration: Duration? + + /** + * List of items to play. + */ + override val items: List + + /** + * A piece of the content to play. + */ + interface Item : MediaNavigator.ReadingOrder.Item { + + /** + * Duration of the item. + */ + val duration: Duration? + } + } + + /** + * Current state of the playback. + */ + override val playback: StateFlow

+ + /** + * Current location of the navigator. + */ + override val location: StateFlow + + /** + * Reading order being read by this navigator. + */ + override val readingOrder: R + + /** + * Seeks to [offset] in the item at [index]. + */ + fun seek(index: Int, offset: Duration) +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt index 292e585273..17ce648442 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt @@ -6,13 +6,16 @@ package org.readium.r2.navigator.media3.api +import android.graphics.Bitmap +import android.net.Uri +import android.util.Size import androidx.media3.common.MediaMetadata import androidx.media3.common.MediaMetadata.PICTURE_TYPE_FRONT_COVER -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async +import java.io.ByteArrayOutputStream +import kotlinx.coroutines.* +import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.services.coverFitting /** * Builds media metadata using the given title, author and cover, @@ -23,7 +26,7 @@ internal class DefaultMediaMetadataFactory( private val publication: Publication, title: String? = null, author: String? = null, - cover: ByteArray? = null + private val cover: Uri? = null ) : MediaMetadataFactory { private val coroutineScope = @@ -32,15 +35,18 @@ internal class DefaultMediaMetadataFactory( private val title: String = title ?: publication.metadata.title - private val authors: String? = + private val author: String? = author ?: publication.metadata.authors .firstOrNull { it.name.isNotBlank() }?.name - private val cover: Deferred = coroutineScope.async { - cover ?: publication.linkWithRel("cover") - ?.let { publication.get(it) } - ?.read() - ?.getOrNull() + private val coverBytes: Deferred = coroutineScope.async(start = CoroutineStart.LAZY) { + tryOrNull { + val byteStream = ByteArrayOutputStream(4096) + // byte array will go cross processes and should be kept small + publication.coverFitting(Size(400, 400)) + ?.compress(Bitmap.CompressFormat.PNG, 80, byteStream) + byteStream.toByteArray() + } } override suspend fun publicationMetadata(): MediaMetadata { @@ -48,11 +54,10 @@ internal class DefaultMediaMetadataFactory( .setTitle(title) .setTotalTrackCount(publication.readingOrder.size) - authors + author ?.let { builder.setArtist(it) } - cover.await() - ?.let { builder.maybeSetArtworkData(it, PICTURE_TYPE_FRONT_COVER) } + putCover(builder) return builder.build() } @@ -62,12 +67,20 @@ internal class DefaultMediaMetadataFactory( .setTrackNumber(index) .setTitle(title) - authors + author ?.let { builder.setArtist(it) } - cover.await() - ?.let { builder.maybeSetArtworkData(it, PICTURE_TYPE_FRONT_COVER) } + putCover(builder) return builder.build() } + + private suspend fun putCover(builder: MediaMetadata.Builder) { + cover + ?.let { builder.setArtworkUri(it) } + ?: run { + coverBytes.await() + ?.let { builder.setArtworkData(it, PICTURE_TYPE_FRONT_COVER) } + } + } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataProvider.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataProvider.kt index 573bbc2725..447426b46c 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataProvider.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataProvider.kt @@ -6,6 +6,7 @@ package org.readium.r2.navigator.media3.api +import android.net.Uri import org.readium.r2.shared.publication.Publication /** @@ -15,7 +16,7 @@ import org.readium.r2.shared.publication.Publication class DefaultMediaMetadataProvider( private val title: String? = null, private val author: String? = null, - private val cover: ByteArray? = null + private val cover: Uri? = null ) : MediaMetadataProvider { override fun createMetadataFactory(publication: Publication): MediaMetadataFactory { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt index 0947ede120..c7746d049d 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt @@ -11,14 +11,22 @@ import kotlinx.coroutines.flow.StateFlow import org.readium.r2.navigator.Navigator import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.util.Closeable +import org.readium.r2.shared.util.Href +/** + * A [Navigator] which can play multimedia content. + */ @ExperimentalReadiumApi -interface MediaNavigator

: Navigator, Closeable { +interface MediaNavigator : Navigator, Closeable { /** - * Marker interface for the [position] flow. + * Location of the navigator. */ - interface Position + interface Location { + + val href: Href + } /** * State of the player. @@ -48,21 +56,55 @@ interface MediaNavigator

: Navigator, Closeable { /** * State of the playback. - * - * @param state The current state. - * @param playWhenReady If the navigator should play as soon as the state is Ready. */ - data class Playback( - val state: State, + interface Playback { + + /** + * The current state. + */ + val state: State + + /** + * Indicates if the navigator should play as soon as the state is Ready. + */ val playWhenReady: Boolean - ) + + /** + * Index of the reading order item currently being played. + */ + val index: Int + } + + /** + * Data about the content to play. + */ + interface ReadingOrder { + + /** + * List of items to play. + */ + val items: List + + /** + * A piece of the content to play. + */ + interface Item + } /** - * Indicates the current state of the playback. + * Current state of the playback. */ - val playback: StateFlow + val playback: StateFlow

- val position: StateFlow

+ /** + * Current location of the navigator. + */ + val location: StateFlow + + /** + * Reading order being read by this navigator. + */ + val readingOrder: R /** * Resumes the playback at the current location. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/SynchronizedMediaNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/SynchronizedMediaNavigator.kt deleted file mode 100644 index 6b5bbcb8c8..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/SynchronizedMediaNavigator.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.navigator.media3.api - -import kotlinx.coroutines.flow.StateFlow -import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.publication.Locator - -/** - * A [MediaNavigator] aware of the utterances that are being read aloud. - */ -@ExperimentalReadiumApi -interface SynchronizedMediaNavigator

: - MediaNavigator

{ - - interface Utterance

{ - val text: String - - val position: P - - val range: IntRange? - - val utteranceLocator: Locator - - val tokenLocator: Locator? - } - - val utterance: StateFlow> -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt new file mode 100644 index 0000000000..03d38b8fe2 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt @@ -0,0 +1,126 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.api + +import kotlinx.coroutines.flow.StateFlow +import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.publication.Locator + +/** + * A [MediaNavigator] aware of the utterances being read aloud. + */ +@ExperimentalReadiumApi +interface TextAwareMediaNavigator : MediaNavigator { + + /** + * Location of the navigator. + */ + interface Location : MediaNavigator.Location { + + /** + * The utterance being played. + */ + val utterance: String + + /** + * The text right before the utterance being played, if any in the current item. + */ + val textBefore: String? + + /** + * The text right after the utterance being played, if any in the current item. + */ + val textAfter: String? + + /** + * The range of [utterance] being played, if known. + */ + val range: IntRange? + + /** + * A locator pointing to the current utterance. + */ + val utteranceLocator: Locator + + /** + * A locator pointing to the current token, if known. + */ + val tokenLocator: Locator? + } + + /** + * State of the playback. + */ + interface Playback : MediaNavigator.Playback { + + /** + * The utterance being played. + */ + val utterance: String + + /** + * The range of [utterance] being played. + */ + val range: IntRange? + } + + /** + * Data about the content to play. + */ + interface ReadingOrder : MediaNavigator.ReadingOrder { + + /** + * List of items to play. + */ + override val items: List + + /** + * A piece of the content to play.. + */ + interface Item : MediaNavigator.ReadingOrder.Item + } + + /** + * Current state of the playback. + */ + override val playback: StateFlow

+ + /** + * Current location of the navigator. + */ + override val location: StateFlow + + /** + * Reading order being read by this navigator. + */ + override val readingOrder: R + + /** + * Jumps to the previous. + * + * Does nothing if the current utterance is the first one. + */ + fun previousUtterance() + + /** + * Jumps to the next utterance. + * + * Does nothing if the current utterance is the last one. + */ + fun nextUtterance() + + /** + * Whether the current utterance has a previous one or is the first one. + */ + fun hasPreviousUtterance(): Boolean + + /** + * Whether the current utterance has a next utterance or is the last one. + */ + fun hasNextUtterance(): Boolean +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngine.kt index 9c6465b1bc..2be170f46b 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngine.kt @@ -9,38 +9,106 @@ package org.readium.r2.navigator.media3.audio import androidx.media3.common.Player import kotlin.time.Duration import kotlinx.coroutines.flow.StateFlow -import org.readium.r2.navigator.media3.api.MediaNavigator import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.shared.ExperimentalReadiumApi +/** + * An audio engine playing a list of items. + */ @ExperimentalReadiumApi -interface AudioEngine, E : AudioEngine.Error> : +interface AudioEngine> : Configurable { + /** + * Marker interface for the errors that the [AudioEngine] returns. + */ interface Error - data class Playback( - val state: MediaNavigator.State, - val playWhenReady: Boolean, - val error: E? - ) + /** + * State of the player. + */ + sealed class State { + + /** + * The player is ready to play. + */ + object Ready : State() + + /** + * The end of the content has been reached. + */ + object Ended : State() + + /** + * The engine cannot play because the buffer is starved. + */ + object Buffering : State() - data class Position( + /** + * The engine cannot play because an error occurred. + */ + data class Error(val error: AudioEngine.Error) : State() + } + + /** + * State of the playback. + * + * @param state The current state. + * @param playWhenReady Indicates if the navigator should play as soon as the state is Ready. + * @param index Index of the reading order item currently being played. + * @param offset Position of the playback in the current item. + * @param buffered Position in the current item until which the content is buffered. + */ + data class Playback( + val state: State, + val playWhenReady: Boolean, val index: Int, - val duration: Duration + val offset: Duration, + val buffered: Duration? ) - val playback: StateFlow> - - val position: StateFlow + /** + * Current state of the playback. + */ + val playback: StateFlow + /** + * Resumes the playback at the current location. + */ fun play() + /** + * Pauses the playback. + */ fun pause() - fun seek(index: Long, position: Duration) + /** + * Seeks to [position] in the item at [index]. + */ + fun seek(index: Int, position: Duration) + + /** + * Seeks by [offset] either forward or backward if [offset] is negative. + */ + fun seekBy(offset: Duration) + + /** + * Seeks by a small increment forward. + */ + fun seekForward() + + /** + * Seeks by a small increment backward. + */ + fun seekBackward() + /** + * Closes the player. + */ fun close() + /** + * Adapts this engine to the media3 [Player] interface. + */ fun asPlayer(): Player } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt index 4413448bea..39a352c128 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt @@ -9,14 +9,22 @@ package org.readium.r2.navigator.media3.audio import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.navigator.preferences.PreferencesEditor import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Metadata import org.readium.r2.shared.publication.Publication +/** + * To be implemented by adapters for third-party audio engines which can be used with [AudiobookNavigator]. + */ @ExperimentalReadiumApi interface AudioEngineProvider, - E : PreferencesEditor

, F : AudioEngine.Error> { + E : PreferencesEditor

> { - suspend fun createEngine(publication: Publication): AudioEngine + suspend fun createEngine( + publication: Publication, + initialLocator: Locator, + initialPreferences: P + ): AudioEngine? /** * Creates settings for [metadata] and [preferences]. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt deleted file mode 100644 index 69fda4d58d..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.navigator.media3.audio - -import androidx.media3.common.Player -import kotlinx.coroutines.flow.StateFlow -import org.readium.r2.navigator.media3.api.MediaNavigator -import org.readium.r2.navigator.preferences.Configurable -import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication - -@ExperimentalReadiumApi -class AudioNavigator, E : AudioEngine.Error>( - private val mediaEngine: AudioEngine -) : MediaNavigator, Configurable by mediaEngine { - - class Position : MediaNavigator.Position - - class Error : MediaNavigator.State.Error - - override val publication: Publication - get() = TODO("Not yet implemented") - - override val currentLocator: StateFlow - get() = TODO("Not yet implemented") - - override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { - TODO("Not yet implemented") - } - - override fun go(link: Link, animated: Boolean, completion: () -> Unit): Boolean { - TODO("Not yet implemented") - } - - override fun goForward(animated: Boolean, completion: () -> Unit): Boolean { - TODO("Not yet implemented") - } - - override fun goBackward(animated: Boolean, completion: () -> Unit): Boolean { - TODO("Not yet implemented") - } - - override fun close() { - TODO("Not yet implemented") - } - - override val playback: StateFlow - get() = TODO("Not yet implemented") - - override val position: StateFlow - get() = TODO("Not yet implemented") - - override fun play() { - TODO("Not yet implemented") - } - - override fun pause() { - TODO("Not yet implemented") - } - - override fun asPlayer(): Player { - TODO("Not yet implemented") - } -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt new file mode 100644 index 0000000000..2b977e0f3e --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.audio + +import org.readium.r2.navigator.preferences.Configurable +import org.readium.r2.navigator.preferences.PreferencesEditor +import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Publication + +@ExperimentalReadiumApi +class AudioNavigatorFactory, + E : PreferencesEditor

> private constructor( + private val publication: Publication, + private val audioEngineProvider: AudioEngineProvider, +) { + + companion object { + + @Suppress("RedundantSuspendModifier") + suspend operator fun , + E : PreferencesEditor

> invoke( + publication: Publication, + audioEngineProvider: AudioEngineProvider, + ): AudioNavigatorFactory? { + if (!publication.conformsTo(Publication.Profile.AUDIOBOOK)) { + return null + } + + if (publication.readingOrder.any { it.duration == 0.0 }) { + return null + } + + return AudioNavigatorFactory( + publication, audioEngineProvider + ) + } + } + + suspend fun createNavigator( + initialPreferences: P? = null, + initialLocator: Locator? = null + ): AudiobookNavigator? { + return AudiobookNavigator( + publication = publication, + audioEngineProvider = audioEngineProvider, + initialPreferences = initialPreferences, + initialLocator = initialLocator + ) + } + + fun createAudioPreferencesEditor( + currentPreferences: P, + ): E = audioEngineProvider.createPreferenceEditor(publication, currentPreferences) +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt new file mode 100644 index 0000000000..f1022cad16 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt @@ -0,0 +1,227 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.audio + +import android.os.Build +import androidx.media3.common.Player +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds +import kotlin.time.ExperimentalTime +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.flow.StateFlow +import org.readium.r2.navigator.extensions.sum +import org.readium.r2.navigator.extensions.time +import org.readium.r2.navigator.media3.api.AudioNavigator +import org.readium.r2.navigator.media3.api.MediaNavigator +import org.readium.r2.navigator.preferences.Configurable +import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.extensions.mapStateIn +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.Href +import timber.log.Timber + +@ExperimentalReadiumApi +@OptIn(ExperimentalTime::class) +class AudiobookNavigator> private constructor( + override val publication: Publication, + private val audioEngine: AudioEngine, + override val readingOrder: ReadingOrder, +) : AudioNavigator, + Configurable by audioEngine { + + companion object { + + suspend operator fun > invoke( + publication: Publication, + audioEngineProvider: AudioEngineProvider, + readingOrder: List = publication.readingOrder, + initialPreferences: P? = null, + initialLocator: Locator? = null, + ): AudiobookNavigator? { + if (readingOrder.isEmpty()) { + return null + } + + val items = readingOrder.map { ReadingOrder.Item(Href(it.href), duration(it, publication)) } + val totalDuration = publication.metadata.duration?.seconds + ?: items.mapNotNull { it.duration } + .takeIf { it.size == items.size } + ?.sum() + + val actualReadingOrder = ReadingOrder(totalDuration, items) + + val actualInitialLocator = initialLocator + ?: publication.locatorFromLink(publication.readingOrder[0])!! + + val audioEngine = + audioEngineProvider.createEngine( + publication, + actualInitialLocator, + initialPreferences ?: audioEngineProvider.createEmptyPreferences() + ) ?: return null + + return AudiobookNavigator(publication, audioEngine, actualReadingOrder) + } + + private fun duration(link: Link, publication: Publication): Duration? { + var duration: Duration? = link.duration?.seconds + .takeUnless { it == Duration.ZERO } + + if (duration == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + val resource = publication.get(link) + duration = MetadataRetriever(resource).duration() + } + + return duration + } + } + + data class Location( + override val href: Href, + override val offset: Duration, + ) : AudioNavigator.Location + + data class ReadingOrder( + override val duration: Duration?, + override val items: List + ) : AudioNavigator.ReadingOrder { + + data class Item( + val href: Href, + override val duration: Duration? + ) : AudioNavigator.ReadingOrder.Item + } + + data class Playback( + override val state: MediaNavigator.State, + override val playWhenReady: Boolean, + override val index: Int, + override val offset: Duration, + override val buffered: Duration?, + ) : AudioNavigator.Playback + + sealed class State { + + object Ready : MediaNavigator.State.Ready + + object Ended : MediaNavigator.State.Ended + + object Buffering : MediaNavigator.State.Buffering + + data class Error (val error: E) : MediaNavigator.State.Error + } + + private val coroutineScope: CoroutineScope = + MainScope() + + override val currentLocator: StateFlow = + audioEngine.playback.mapStateIn(coroutineScope) { playback -> + val currentItem = readingOrder.items[playback.index] + val link = requireNotNull(publication.linkWithHref(currentItem.href.string)) + val item = readingOrder.items[playback.index] + val itemStartPosition = readingOrder.items + .slice(0 until playback.index) + .mapNotNull { it.duration } + .takeIf { it.size == readingOrder.items.size } + ?.sum() + val totalProgression = + if (itemStartPosition == null) null + else readingOrder.duration?.let { (itemStartPosition + playback.offset) / it } + + val locator = requireNotNull(publication.locatorFromLink(link)) + locator.copyWithLocations( + fragments = listOf("t=${playback.offset.inWholeSeconds}"), + progression = item.duration?.let { playback.offset / it }, + totalProgression = totalProgression + ) + } + + override val playback: StateFlow = + audioEngine.playback.mapStateIn(coroutineScope) { playback -> + Playback( + playback.state.toState(), + playback.playWhenReady, + playback.index, + playback.offset, + playback.buffered + ) + } + + override val location: StateFlow = + audioEngine.playback.mapStateIn(coroutineScope) { + val currentItem = readingOrder.items[it.index] + Location(currentItem.href, it.offset) + } + + override fun play() { + audioEngine.play() + } + + override fun pause() { + audioEngine.pause() + } + + override fun seek(index: Int, offset: Duration) { + audioEngine.seek(index, offset) + } + + fun seekForward() { + audioEngine.seekForward() + } + + fun seekBackward() { + audioEngine.seekBackward() + } + + fun seekBy(offset: Duration) { + audioEngine.seekBy(offset) + } + + override fun close() { + audioEngine.close() + } + + override fun asPlayer(): Player { + return audioEngine.asPlayer() + } + + override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { + val itemIndex = readingOrder.items.indexOfFirst { it.href.string == locator.href } + .takeUnless { it == -1 } + ?: return false + val position = locator.locations.time ?: Duration.ZERO + Timber.v("Go to locator $locator") + audioEngine.seek(itemIndex, position) + return true + } + + override fun go(link: Link, animated: Boolean, completion: () -> Unit): Boolean { + val locator = publication.locatorFromLink(link) ?: return false + return go(locator, animated, completion) + } + + override fun goForward(animated: Boolean, completion: () -> Unit): Boolean { + seekForward() + return true + } + + override fun goBackward(animated: Boolean, completion: () -> Unit): Boolean { + seekBackward() + return true + } + + private fun AudioEngine.State.toState(): MediaNavigator.State = + when (this) { + is AudioEngine.State.Ready -> State.Ready + is AudioEngine.State.Ended -> State.Ended + is AudioEngine.State.Buffering -> State.Buffering + is AudioEngine.State.Error -> State.Error(error) + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/DurationSerializer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/DurationSerializer.kt deleted file mode 100644 index ea9836096b..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/DurationSerializer.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.navigator.media3.audio - -import kotlin.time.Duration -import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -object DurationSerializer : KSerializer { - - private val serializer = Duration.serializer() - - override val descriptor: SerialDescriptor = serializer.descriptor - - override fun deserialize(decoder: Decoder): Duration = - decoder.decodeSerializableValue(serializer) - - override fun serialize(encoder: Encoder, value: Duration) { - encoder.encodeSerializableValue(serializer, value) - } -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt new file mode 100644 index 0000000000..d3c063ccf4 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.audio + +import android.media.MediaDataSource +import android.media.MediaMetadataRetriever +import android.media.MediaMetadataRetriever.METADATA_KEY_DURATION +import android.os.Build +import androidx.annotation.RequiresApi +import java.io.IOException +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds +import kotlinx.coroutines.runBlocking +import org.readium.r2.shared.fetcher.Resource + +@RequiresApi(Build.VERSION_CODES.M) +internal class MetadataRetriever( + private val resource: Resource +) { + + private val retriever: MediaMetadataRetriever = + MediaMetadataRetriever() + .apply { + setDataSource(ResourceMediaDataSource(resource)) + } + + fun duration(): Duration? = + retriever.extractMetadata(METADATA_KEY_DURATION) + ?.toIntOrNull() + ?.takeUnless { it == 0 } + ?.milliseconds + + fun close() { + runBlocking { resource.close() } + } + + class ResourceMediaDataSource( + private val resource: Resource + ) : MediaDataSource() { + + override fun readAt(position: Long, buffer: ByteArray, offset: Int, size: Int): Int { + if (size == 0) { + return 0 + } + + val data = runBlocking { + resource.read(position until position + size) + .mapFailure { IOException("Resource error", it) } + .getOrThrow() + } + + if (data.isEmpty()) { + return -1 + } + + data.copyInto(buffer, offset) + return data.size + } + + override fun getSize(): Long { + return runBlocking { + resource.length() + .mapFailure { IOException("Resource error", it) } + .getOrThrow() + } + } + + override fun close() { + runBlocking { resource.close() } + } + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/SmartSeeker.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/SmartSeeker.kt new file mode 100644 index 0000000000..a5890565b3 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/SmartSeeker.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.audio + +import kotlin.time.Duration +import kotlin.time.ExperimentalTime + +/** + * Computes relative seeks across playlist items. + */ +@ExperimentalTime +internal object SmartSeeker { + + data class Result(val index: Int, val position: Duration) + + fun dispatchSeek( + offset: Duration, + currentPosition: Duration, + currentIndex: Int, + playlist: List + ): Result { + val currentDuration = playlist[currentIndex] + val dummyNewPosition = currentPosition + offset + + return when { + offset == Duration.ZERO -> { + Result(currentIndex, currentPosition) + } + currentDuration > dummyNewPosition && dummyNewPosition > Duration.ZERO -> { + Result(currentIndex, dummyNewPosition) + } + offset.isPositive() && currentIndex == playlist.size - 1 -> { + Result(currentIndex, playlist[currentIndex]) + } + offset.isNegative() && currentIndex == 0 -> { + Result(0, Duration.ZERO) + } + offset.isPositive() -> { + var toDispatch = offset - (currentDuration - currentPosition) + var index = currentIndex + 1 + while (toDispatch > playlist[index] && index + 1 < playlist.size) { + toDispatch -= playlist[index] + index += 1 + } + Result(index, toDispatch.coerceAtMost(playlist[index])) + } + else -> { + var toDispatch = offset + currentPosition + var index = currentIndex - 1 + while (-toDispatch > playlist[index] && index > 0) { + toDispatch += playlist[index] + index -= 1 + } + Result(index, (playlist[index] + toDispatch).coerceAtLeast(Duration.ZERO)) + } + } + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt new file mode 100644 index 0000000000..57902d17e7 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.exoplayer + +import androidx.media3.common.ForwardingPlayer +import androidx.media3.exoplayer.ExoPlaybackException +import androidx.media3.exoplayer.ExoPlayer +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.ExperimentalTime +import org.readium.r2.navigator.media3.audio.SmartSeeker +import timber.log.Timber + +/** + * A wrapper around ExoPlayer to customize some behaviours. + */ +@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) +internal class ExoAudiobookPlayer( + private val player: ExoPlayer, + private val itemDurations: List?, + private val seekForwardIncrement: Duration, + private val seekBackwardIncrement: Duration, +) : ForwardingPlayer(player) { + + fun seekBy(offset: Duration) { + itemDurations + ?.let { smartSeekBy(offset, it) } + ?: dumbSeekBy(offset) + } + + override fun seekForward() { + seekBy(seekForwardIncrement) + } + + override fun seekBack() { + seekBy(-seekBackwardIncrement) + } + + override fun getPlayerError(): ExoPlaybackException? { + return player.playerError + } + + @OptIn(ExperimentalTime::class) + private fun smartSeekBy( + offset: Duration, + durations: List + ) { + val (newIndex, newPosition) = + SmartSeeker.dispatchSeek( + offset, + player.currentPosition.milliseconds, + player.currentMediaItemIndex, + durations + ) + Timber.v("Smart seeking by $offset resolved to item $newIndex position $newPosition") + player.seekTo(newIndex, newPosition.inWholeMilliseconds) + } + + private fun dumbSeekBy(offset: Duration) { + val newIndex = player.currentMediaItemIndex + val newPosition = player.currentPosition + offset.inWholeMilliseconds + player.seekTo(newIndex, newPosition) + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt new file mode 100644 index 0000000000..792af970b5 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.exoplayer + +import org.readium.r2.navigator.media3.audio.AudioNavigatorFactory +import org.readium.r2.navigator.media3.audio.AudiobookNavigator +import org.readium.r2.shared.ExperimentalReadiumApi + +@OptIn(ExperimentalReadiumApi::class) +typealias ExoPlayerNavigatorFactory = AudioNavigatorFactory + +@OptIn(ExperimentalReadiumApi::class) +typealias ExoPlayerNavigator = AudiobookNavigator diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt index c3411199fd..739fa40017 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt @@ -29,7 +29,9 @@ sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : * An ExoPlayer's [DataSource] which retrieves resources from a [Publication]. */ @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) -internal class ExoPlayerDataSource internal constructor(private val publication: Publication) : BaseDataSource(/* isNetwork = */ true) { +internal class ExoPlayerDataSource internal constructor( + private val publication: Publication +) : BaseDataSource(/* isNetwork = */ true) { class Factory( private val publication: Publication, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDefaults.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDefaults.kt new file mode 100644 index 0000000000..dd3f84b175 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDefaults.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.exoplayer + +import org.readium.r2.shared.ExperimentalReadiumApi + +/** + * Default values for the ExoPlayer engine. + * + * These values will be used as a last resort by [ExoPlayerSettingsResolver] + * when no user preference takes precedence. + * + * @see ExoPlayerPreferences + */ +@ExperimentalReadiumApi +data class ExoPlayerDefaults( + val pitch: Double? = null, + val speed: Double? = null +) { + init { + require(pitch == null || pitch > 0) + require(speed == null || speed > 0) + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt index 3022884ce5..a80e16055e 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt @@ -7,34 +7,49 @@ package org.readium.r2.navigator.media3.exoplayer import android.app.Application -import androidx.media3.common.AudioAttributes -import androidx.media3.common.C -import androidx.media3.common.Player +import androidx.media3.common.* import androidx.media3.datasource.DataSource +import androidx.media3.exoplayer.ExoPlaybackException import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.source.DefaultMediaSourceFactory import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import org.readium.r2.navigator.media3.audio.AudioEngine import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.units.Hz +import org.readium.r2.shared.units.hz +/** + * An [AudioEngine] based on Media3 ExoPlayer. + */ @ExperimentalReadiumApi +@OptIn(ExperimentalCoroutinesApi::class) @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) -class ExoPlayerEngine( - private val application: Application, - private val publication: Publication, - private val exoPlayer: ExoPlayer, -) : AudioEngine { +class ExoPlayerEngine private constructor( + private val exoPlayer: ExoAudiobookPlayer, + private val settingsResolver: SettingsResolver, + private val configuration: Configuration, + initialPreferences: ExoPlayerPreferences +) : AudioEngine { companion object { - private fun createExoPlayer( + suspend operator fun invoke( application: Application, - publication: Publication, - ): ExoPlayer { - val dataSourceFactory: DataSource.Factory = ExoPlayerDataSource.Factory(publication) - return ExoPlayer.Builder(application) + settingsResolver: SettingsResolver, + dataSourceFactory: DataSource.Factory, + playlist: Playlist, + configuration: Configuration, + initialIndex: Int, + initialPosition: Duration, + initialPreferences: ExoPlayerPreferences + ): ExoPlayerEngine { + val exoPlayer = ExoPlayer.Builder(application) .setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory)) .setAudioAttributes( AudioAttributes.Builder() @@ -44,35 +59,169 @@ class ExoPlayerEngine( true ) .setHandleAudioBecomingNoisy(true) + .setSeekBackIncrementMs(configuration.seekBackwardIncrement.inWholeMilliseconds) + .setSeekForwardIncrementMs(configuration.seekForwardIncrement.inWholeMilliseconds) .build() + + exoPlayer.setMediaItems( + playlist.items.map { item -> + MediaItem.Builder() + .setUri(item.uri) + .setMediaMetadata(item.mediaMetadata) + .build() + } + ) + + val durations: List? = + playlist.items.mapNotNull { it.duration } + .takeIf { it.size == playlist.items.size } + + exoPlayer.playlistMetadata = playlist.mediaMetadata + + exoPlayer.seekTo(initialIndex, initialPosition.inWholeMilliseconds) + + prepareExoPlayer(exoPlayer) + + val customizedPlayer = + ExoAudiobookPlayer( + exoPlayer, + durations, + configuration.seekForwardIncrement, + configuration.seekBackwardIncrement + ) + + return ExoPlayerEngine( + customizedPlayer, + settingsResolver, + configuration, + initialPreferences + ) + } + + private suspend fun prepareExoPlayer(player: ExoPlayer) { + lateinit var listener: Player.Listener + suspendCancellableCoroutine { continuation -> + listener = object : Player.Listener { + override fun onPlaybackStateChanged(playbackState: Int) { + when (playbackState) { + Player.STATE_READY -> continuation.resume(Unit) {} + Player.STATE_IDLE -> if (player.playerError != null) { + continuation.resume(Unit) {} + } + else -> {} + } + } + } + continuation.invokeOnCancellation { player.removeListener(listener) } + player.addListener(listener) + player.prepare() + } + player.removeListener(listener) } } - class Error : AudioEngine.Error + data class Configuration( + val positionRefreshRate: Hz = 2.0.hz, + val seekBackwardIncrement: Duration = 15.seconds, + val seekForwardIncrement: Duration = 30.seconds + ) - override val playback: StateFlow> - get() = TODO("Not yet implemented") + data class Playlist( + val mediaMetadata: MediaMetadata, + val duration: Duration?, + val items: List + ) { + data class Item( + val uri: String, + val mediaMetadata: MediaMetadata, + val duration: Duration? + ) + } + + fun interface SettingsResolver { + + /** + * Computes a set of engine settings from the engine preferences. + */ + fun settings(preferences: ExoPlayerPreferences): ExoPlayerSettings + } + + private inner class Listener : Player.Listener { - override val position: StateFlow - get() = TODO("Not yet implemented") + override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters) { + submitPreferences( + ExoPlayerPreferences( + pitch = playbackParameters.pitch.toDouble(), + speed = playbackParameters.speed.toDouble() + ) + ) + } + + override fun onEvents(player: Player, events: Player.Events) { + _playback.value = exoPlayer.playback + } + } + + data class Error(val error: ExoPlaybackException) : AudioEngine.Error + + private val coroutineScope: CoroutineScope = + MainScope() + + init { + exoPlayer.addListener(Listener()) + } + + private val _settings: MutableStateFlow = + MutableStateFlow(settingsResolver.settings(initialPreferences)) + + private val _playback: MutableStateFlow = + MutableStateFlow(exoPlayer.playback) + + init { + coroutineScope.launch { + val positionRefreshDelay = (1.0 / configuration.positionRefreshRate.value).seconds + while (isActive) { + delay(positionRefreshDelay) + _playback.value = exoPlayer.playback + } + } + + submitPreferences(initialPreferences) + } + + override val playback: StateFlow + get() = _playback.asStateFlow() override val settings: StateFlow - get() = TODO("Not yet implemented") + get() = _settings.asStateFlow() override fun play() { - TODO("Not yet implemented") + exoPlayer.play() } override fun pause() { - TODO("Not yet implemented") + exoPlayer.pause() + } + + override fun seek(index: Int, position: Duration) { + exoPlayer.seekTo(index, position.inWholeMilliseconds) + } + + override fun seekBy(offset: Duration) { + exoPlayer.seekBy(offset) } - override fun seek(index: Long, position: Duration) { - TODO("Not yet implemented") + override fun seekForward() { + exoPlayer.seekForward() + } + + override fun seekBackward() { + exoPlayer.seekBack() } override fun close() { - TODO("Not yet implemented") + coroutineScope.cancel() + exoPlayer.release() } override fun asPlayer(): Player { @@ -80,6 +229,26 @@ class ExoPlayerEngine( } override fun submitPreferences(preferences: ExoPlayerPreferences) { - TODO("Not yet implemented") + val newSettings = settingsResolver.settings(preferences) + exoPlayer.playbackParameters = PlaybackParameters( + newSettings.speed.toFloat(), newSettings.pitch.toFloat() + ) } + + private val ExoAudiobookPlayer.playback: AudioEngine.Playback get() = + AudioEngine.Playback( + state = engineState, + playWhenReady = playWhenReady, + index = currentMediaItemIndex, + offset = currentPosition.milliseconds, + buffered = bufferedPosition.milliseconds + ) + + private val ExoAudiobookPlayer.engineState: AudioEngine.State get() = + when (this.playbackState) { + Player.STATE_READY -> AudioEngine.State.Ready + Player.STATE_BUFFERING -> AudioEngine.State.Buffering + Player.STATE_ENDED -> AudioEngine.State.Ended + else -> AudioEngine.State.Error(Error(playerError!!)) + } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngineProvider.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngineProvider.kt index bbfa3d9211..c3b3aaba60 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngineProvider.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngineProvider.kt @@ -6,30 +6,84 @@ package org.readium.r2.navigator.media3.exoplayer +import android.app.Application +import androidx.media3.datasource.DataSource +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds +import org.readium.r2.navigator.extensions.time +import org.readium.r2.navigator.media3.api.DefaultMediaMetadataProvider +import org.readium.r2.navigator.media3.api.MediaMetadataProvider import org.readium.r2.navigator.media3.audio.AudioEngineProvider import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Metadata import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.indexOfFirstWithHref +/** + * Main component to use the audio navigator with the ExoPlayer adapter. + * + * Provide [ExoPlayerDefaults] to customize the default values that will be used by + * the navigator for some preferences. + */ @ExperimentalReadiumApi @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) -class ExoPlayerEngineProvider() : AudioEngineProvider { +class ExoPlayerEngineProvider( + private val application: Application, + private val metadataProvider: MediaMetadataProvider = DefaultMediaMetadataProvider(), + private val defaults: ExoPlayerDefaults = ExoPlayerDefaults(), + private val configuration: ExoPlayerEngine.Configuration = ExoPlayerEngine.Configuration() +) : AudioEngineProvider { + + override suspend fun createEngine( + publication: Publication, + initialLocator: Locator, + initialPreferences: ExoPlayerPreferences + ): ExoPlayerEngine { + val metadataFactory = metadataProvider.createMetadataFactory(publication) + val settingsResolver = ExoPlayerSettingsResolver(defaults) + val dataSourceFactory: DataSource.Factory = ExoPlayerDataSource.Factory(publication) + val initialIndex = publication.readingOrder.indexOfFirstWithHref(initialLocator.href) ?: 0 + val initialPosition = initialLocator.locations.time ?: Duration.ZERO + val playlist = ExoPlayerEngine.Playlist( + mediaMetadata = metadataFactory.publicationMetadata(), + duration = publication.metadata.duration?.seconds, + items = publication.readingOrder.mapIndexed { index, link -> + ExoPlayerEngine.Playlist.Item( + uri = link.href, + mediaMetadata = metadataFactory.resourceMetadata(index), + duration = link.duration?.seconds + ) + } + ) - override suspend fun createEngine(publication: Publication): ExoPlayerEngine { - TODO("Not yet implemented") + return ExoPlayerEngine( + application = application, + settingsResolver = settingsResolver, + playlist = playlist, + dataSourceFactory = dataSourceFactory, + configuration = configuration, + initialIndex = initialIndex, + initialPosition = initialPosition, + initialPreferences = initialPreferences + ) } override fun computeSettings( metadata: Metadata, preferences: ExoPlayerPreferences ): ExoPlayerSettings = - ExoPlayerSettingsResolver(metadata).settings(preferences) + ExoPlayerSettingsResolver(defaults).settings(preferences) override fun createPreferenceEditor( publication: Publication, initialPreferences: ExoPlayerPreferences ): ExoPlayerPreferencesEditor = - ExoPlayerPreferencesEditor() + ExoPlayerPreferencesEditor( + initialPreferences, + publication.metadata, + defaults + ) override fun createEmptyPreferences(): ExoPlayerPreferences = ExoPlayerPreferences() diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt index c77c551475..ce048b2a50 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt @@ -9,14 +9,22 @@ package org.readium.r2.navigator.media3.exoplayer import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.shared.ExperimentalReadiumApi +/** + * Preferences for the the ExoPlayer engine. + * + * @param pitch Playback pitch rate. + * @param speed Playback speed rate. + */ @ExperimentalReadiumApi @kotlinx.serialization.Serializable data class ExoPlayerPreferences( - val rateMultiplier: Double? = null, + val pitch: Double? = null, + val speed: Double? = null, ) : Configurable.Preferences { override fun plus(other: ExoPlayerPreferences): ExoPlayerPreferences = ExoPlayerPreferences( - rateMultiplier = other.rateMultiplier ?: rateMultiplier, + pitch = other.pitch ?: pitch, + speed = other.speed ?: speed, ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt index 6cc4efe150..ffe9d8f799 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt @@ -6,16 +6,76 @@ package org.readium.r2.navigator.media3.exoplayer +import org.readium.r2.navigator.extensions.format +import org.readium.r2.navigator.preferences.DoubleIncrement import org.readium.r2.navigator.preferences.PreferencesEditor +import org.readium.r2.navigator.preferences.RangePreference +import org.readium.r2.navigator.preferences.RangePreferenceDelegate import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.publication.Metadata +/** + * Editor for a set of [ExoPlayerPreferences]. + * + * Use [ExoPlayerPreferencesEditor] to assist you in building a preferences user interface or modifying + * existing preferences. It includes rules for adjusting preferences, such as the supported values + * or ranges. + */ @ExperimentalReadiumApi -class ExoPlayerPreferencesEditor : PreferencesEditor { +class ExoPlayerPreferencesEditor( + initialPreferences: ExoPlayerPreferences, + @Suppress("UNUSED_PARAMETER") publicationMetadata: Metadata, + defaults: ExoPlayerDefaults, +) : PreferencesEditor { + + private data class State( + val preferences: ExoPlayerPreferences, + val settings: ExoPlayerSettings + ) + + private val settingsResolver: ExoPlayerSettingsResolver = + ExoPlayerSettingsResolver(defaults) + + private var state: State = + initialPreferences.toState() override val preferences: ExoPlayerPreferences - get() = TODO("Not yet implemented") + get() = state.preferences override fun clear() { - TODO("Not yet implemented") + updateValues { ExoPlayerPreferences() } } + + val pitch: RangePreference = + RangePreferenceDelegate( + getValue = { preferences.pitch }, + getEffectiveValue = { state.settings.pitch }, + getIsEffective = { true }, + updateValue = { value -> updateValues { it.copy(pitch = value) } }, + supportedRange = 0.1..Double.MAX_VALUE, + progressionStrategy = DoubleIncrement(0.1), + valueFormatter = { "${it.format(2)}x" }, + ) + + val speed: RangePreference = + RangePreferenceDelegate( + getValue = { preferences.speed }, + getEffectiveValue = { state.settings.speed }, + getIsEffective = { true }, + updateValue = { value -> updateValues { it.copy(speed = value) } }, + supportedRange = 0.1..Double.MAX_VALUE, + progressionStrategy = DoubleIncrement(0.1), + valueFormatter = { "${it.format(2)}x" }, + ) + + private fun updateValues(updater: (ExoPlayerPreferences) -> ExoPlayerPreferences) { + val newPreferences = updater(preferences) + state = newPreferences.toState() + } + + private fun ExoPlayerPreferences.toState() = + State( + preferences = this, + settings = settingsResolver.settings(this) + ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesFilters.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesFilters.kt deleted file mode 100644 index db3f3b7aad..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesFilters.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.navigator.media3.exoplayer - -import org.readium.r2.navigator.preferences.PreferencesFilter -import org.readium.r2.shared.ExperimentalReadiumApi - -/** - * Suggested filter to keep only shared [ExoPlayerPreferences]. - */ -@ExperimentalReadiumApi -object ExoPlayerSharedPreferencesFilter : PreferencesFilter { - - override fun filter(preferences: ExoPlayerPreferences): ExoPlayerPreferences = - preferences.copy() -} - -/** - * Suggested filter to keep only publication-specific [ExoPlayerPreferences]. - */ -@ExperimentalReadiumApi -object ExoPlayerPublicationPreferencesFilter : PreferencesFilter { - - override fun filter(preferences: ExoPlayerPreferences): ExoPlayerPreferences = - ExoPlayerPreferences() -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettings.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettings.kt index 58bc54b1e5..e43425842d 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettings.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettings.kt @@ -9,7 +9,13 @@ package org.readium.r2.navigator.media3.exoplayer import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.shared.ExperimentalReadiumApi +/** + * Settings values of the ExoPlayer engine. + * + * @see ExoPlayerPreferences + */ @ExperimentalReadiumApi data class ExoPlayerSettings( - val rateMultiplier: Double + val pitch: Double, + val speed: Double ) : Configurable.Settings diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt index b940630a3e..6dcb2aabbc 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt @@ -7,17 +7,17 @@ package org.readium.r2.navigator.media3.exoplayer import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.publication.Metadata @ExperimentalReadiumApi internal class ExoPlayerSettingsResolver( - private val metadata: Metadata, -) { + private val defaults: ExoPlayerDefaults +) : ExoPlayerEngine.SettingsResolver { - fun settings(preferences: ExoPlayerPreferences): ExoPlayerSettings { + override fun settings(preferences: ExoPlayerPreferences): ExoPlayerSettings { return ExoPlayerSettings( - rateMultiplier = preferences.rateMultiplier ?: 1.0, + pitch = preferences.pitch ?: defaults.pitch ?: 1.0, + speed = preferences.speed ?: defaults.speed ?: 1.0, ) } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt new file mode 100644 index 0000000000..36a87bdb9f --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt @@ -0,0 +1,137 @@ +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.media3.syncmedia + +import androidx.media3.common.Player +import kotlin.time.Duration +import kotlinx.coroutines.flow.StateFlow +import org.readium.r2.navigator.media3.api.AudioNavigator +import org.readium.r2.navigator.media3.api.MediaNavigator +import org.readium.r2.navigator.media3.api.TextAwareMediaNavigator +import org.readium.r2.navigator.media3.audio.AudiobookNavigator +import org.readium.r2.navigator.preferences.Configurable +import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.Href + +@ExperimentalReadiumApi +class GuidedAudioNavigator>( + private val audioNavigator: AudiobookNavigator, +) : AudioNavigator, + TextAwareMediaNavigator, + Configurable { + + data class Location( + override val href: Href, + override val offset: Duration, + val fragment: String, + override val textBefore: String?, + override val textAfter: String?, + override val utterance: String, + override val range: IntRange?, + override val utteranceLocator: Locator, + override val tokenLocator: Locator?, + ) : AudioNavigator.Location, + TextAwareMediaNavigator.Location + + data class Playback( + override val state: MediaNavigator.State, + override val playWhenReady: Boolean, + override val index: Int, + override val offset: Duration, + override val buffered: Duration?, + override val utterance: String, + override val range: IntRange?, + ) : AudioNavigator.Playback, TextAwareMediaNavigator.Playback + + data class ReadingOrder( + override val duration: Duration?, + override val items: List + ) : AudioNavigator.ReadingOrder, TextAwareMediaNavigator.ReadingOrder { + + data class Item( + val href: Href, + override val duration: Duration? + ) : AudioNavigator.ReadingOrder.Item, TextAwareMediaNavigator.ReadingOrder.Item + } + + override val publication: Publication = + audioNavigator.publication + + override val currentLocator: StateFlow = + audioNavigator.currentLocator + + override val playback: StateFlow + get() = TODO("Not yet implemented") + + override val location: StateFlow + get() = TODO("Not yet implemented") + + override val readingOrder: ReadingOrder + get() = TODO("Not yet implemented") + + override fun play() { + audioNavigator.play() + } + + override fun pause() { + audioNavigator.pause() + } + + override fun asPlayer(): Player { + return audioNavigator.asPlayer() + } + + override val settings: StateFlow = + audioNavigator.settings + + override fun submitPreferences(preferences: P) { + audioNavigator.submitPreferences(preferences) + } + + override fun close() { + audioNavigator.close() + } + + override fun previousUtterance() { + TODO("Not yet implemented") + } + + override fun nextUtterance() { + TODO("Not yet implemented") + } + + override fun hasPreviousUtterance(): Boolean { + TODO("Not yet implemented") + } + + override fun hasNextUtterance(): Boolean { + TODO("Not yet implemented") + } + + override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { + TODO("Not yet implemented") + } + + override fun go(link: Link, animated: Boolean, completion: () -> Unit): Boolean { + TODO("Not yet implemented") + } + + override fun goForward(animated: Boolean, completion: () -> Unit): Boolean { + TODO("Not yet implemented") + } + + override fun goBackward(animated: Boolean, completion: () -> Unit): Boolean { + TODO("Not yet implemented") + } + + override fun seek(index: Int, offset: Duration) { + TODO("Not yet implemented") + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngine.kt index 36ec182284..b9124d1731 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngine.kt @@ -56,7 +56,7 @@ interface TtsEngine, * An id to identify a request to speak. */ @JvmInline - value class RequestId(val id: String) + value class RequestId(val value: String) /** * TTS engine callbacks. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt index 8240d0573e..00f5d5bf27 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt @@ -15,15 +15,17 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.StateFlow import org.readium.r2.navigator.media3.api.MediaMetadataProvider import org.readium.r2.navigator.media3.api.MediaNavigator -import org.readium.r2.navigator.media3.api.SynchronizedMediaNavigator +import org.readium.r2.navigator.media3.api.TextAwareMediaNavigator import org.readium.r2.navigator.media3.tts.session.TtsSessionAdapter import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.extensions.combineStateIn import org.readium.r2.shared.extensions.mapStateIn import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.content.ContentService +import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.Language import org.readium.r2.shared.util.tokenizer.TextTokenizer @@ -37,7 +39,8 @@ class TtsNavigator, override val publication: Publication, private val player: TtsPlayer, private val sessionAdapter: TtsSessionAdapter, -) : SynchronizedMediaNavigator, Configurable by player { +) : TextAwareMediaNavigator, + Configurable by player { companion object { @@ -123,20 +126,33 @@ class TtsNavigator, fun onStopRequested() } - data class Position( - val resourceIndex: Int, + data class Location( + override val href: Href, val cssSelector: String, - val textBefore: String?, - val textAfter: String?, - ) : MediaNavigator.Position - - data class Utterance( - override val text: String, - override val position: Position, + override val utterance: String, override val range: IntRange?, + override val textBefore: String?, + override val textAfter: String?, override val utteranceLocator: Locator, - override val tokenLocator: Locator? - ) : SynchronizedMediaNavigator.Utterance + override val tokenLocator: Locator?, + ) : TextAwareMediaNavigator.Location + + data class Playback( + override val state: MediaNavigator.State, + override val playWhenReady: Boolean, + override val index: Int, + override val utterance: String, + override val range: IntRange?, + ) : TextAwareMediaNavigator.Playback + + data class ReadingOrder( + override val items: List + ) : TextAwareMediaNavigator.ReadingOrder { + + data class Item( + val href: Href + ) : TextAwareMediaNavigator.ReadingOrder.Item + } sealed class State { @@ -155,15 +171,19 @@ class TtsNavigator, val voices: Set get() = player.voices - override val playback: StateFlow = - player.playback.mapStateIn(coroutineScope) { it.toPlayback() } + override val readingOrder: ReadingOrder = + ReadingOrder( + items = publication.readingOrder.map { ReadingOrder.Item(Href(it.href)) } + ) - override val utterance: StateFlow = - player.utterance.mapStateIn(coroutineScope) { it.toUtterance() } + override val playback: StateFlow = + player.playback.combineStateIn(coroutineScope, player.utterance) { playback, utterance -> + navigatorPlayback(playback, utterance) + } - override val position: StateFlow = - utterance.mapStateIn(coroutineScope) { utterance -> - utterance.position.copy(textAfter = utterance.text + utterance.position.textAfter) + override val location: StateFlow = + player.utterance.mapStateIn(coroutineScope) { playerUtterance -> + playerUtterance.toPosition() } override fun play() { @@ -178,14 +198,22 @@ class TtsNavigator, player.go(locator) } - fun previousUtterance() { + override fun previousUtterance() { player.previousUtterance() } - fun nextUtterance() { + override fun nextUtterance() { player.nextUtterance() } + override fun hasPreviousUtterance(): Boolean { + return player.hasPreviousUtterance() + } + + override fun hasNextUtterance(): Boolean { + return player.hasNextUtterance() + } + override fun asPlayer(): Player = sessionAdapter @@ -194,7 +222,7 @@ class TtsNavigator, } override val currentLocator: StateFlow = - utterance.mapStateIn(coroutineScope) { it.tokenLocator ?: it.utteranceLocator } + location.mapStateIn(coroutineScope) { it.tokenLocator ?: it.utteranceLocator } override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { player.go(locator) @@ -216,10 +244,13 @@ class TtsNavigator, return true } - private fun TtsPlayer.Playback.toPlayback() = - MediaNavigator.Playback( - state = state.toState(), - playWhenReady = playWhenReady, + private fun navigatorPlayback(playback: TtsPlayer.Playback, utterance: TtsPlayer.Utterance) = + Playback( + state = playback.state.toState(), + playWhenReady = playback.playWhenReady, + index = utterance.position.resourceIndex, + utterance = utterance.text, + range = utterance.range ) private fun TtsPlayer.State.toState() = @@ -235,17 +266,12 @@ class TtsNavigator, is TtsPlayer.State.Error.EngineError<*> -> State.Error.EngineError(error) } - private fun TtsPlayer.Utterance.Position.toPosition(): Position = - Position( - resourceIndex = resourceIndex, - cssSelector = cssSelector, - textBefore = textBefore, - textAfter = textAfter - ) + private fun TtsPlayer.Utterance.toPosition(): Location { + + val currentLink = publication.readingOrder[position.resourceIndex] - private fun TtsPlayer.Utterance.toUtterance(): Utterance { val utteranceHighlight = publication - .locatorFromLink(publication.readingOrder[position.resourceIndex])!! + .locatorFromLink(currentLink)!! .copyWithLocations( progression = null, otherLocations = buildMap { @@ -263,12 +289,15 @@ class TtsNavigator, val tokenHighlight = range ?.let { utteranceHighlight.copy(text = utteranceHighlight.text.substring(it)) } - return Utterance( - text = text, - position = position.toPosition(), + return Location( + href = Href(currentLink.href), + cssSelector = position.cssSelector, + textBefore = position.textBefore, + textAfter = position.textAfter, + utterance = text, range = range, utteranceLocator = utteranceHighlight, - tokenLocator = tokenHighlight, + tokenLocator = tokenHighlight ) } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt index d98a450d62..3cfe0511fd 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt @@ -6,6 +6,11 @@ package org.readium.r2.navigator.media3.tts +import android.media.AudioAttributes +import android.media.AudioFormat +import android.media.AudioManager +import android.media.AudioTrack +import android.os.Build import kotlin.coroutines.coroutineContext import kotlinx.coroutines.* import kotlinx.coroutines.flow.MutableStateFlow @@ -185,10 +190,48 @@ internal class TtsPlayer, fun play() { coroutineScope.launch { + // WORKAROUND to get the media buttons correctly working. + fakePlayingAudio() + playAsync() } } + private fun fakePlayingAudio() { + val audioAttributes = + AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_MEDIA) + .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) + .build() + + val audioFormat = + AudioFormat.Builder() + .setEncoding(AudioFormat.ENCODING_PCM_16BIT) + .setSampleRate(44100) + .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO) + .build() + + val bufferSize = 8092 + + val audioTrack = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + AudioTrack.Builder() + .setAudioAttributes(audioAttributes) + .setAudioFormat(audioFormat) + .setBufferSizeInBytes(bufferSize) + .build() + } else { + AudioTrack( + audioAttributes, + audioFormat, + bufferSize, + AudioTrack.MODE_STATIC, + AudioManager.AUDIO_SESSION_ID_GENERATE + ) + } + audioTrack.play() + } + private suspend fun playAsync() = mutex.withLock { if (isPlaying()) { return diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt index 289f46c9ae..244a7e8c08 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt @@ -6,6 +6,7 @@ package org.readium.r2.navigator.media3.tts.android +import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.content.pm.PackageManager @@ -15,7 +16,7 @@ import android.speech.tts.TextToSpeech.* import android.speech.tts.UtteranceProgressListener import android.speech.tts.Voice as AndroidVoice import android.speech.tts.Voice.* -import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.* import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -23,15 +24,25 @@ import org.readium.r2.navigator.media3.tts.TtsEngine import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.util.Language +/* + * On some Android implementations (i.e. on Oppo A9 2020 running Android 11), + * the TextToSpeech instance is often disconnected from the underlying service when the playback + * is paused and the app moves to the background. So we try to reset the TextToSpeech before + * actually returning an error. In the meantime, requests to the engine are queued + * into [pendingRequests]. + */ + /** * Default [TtsEngine] implementation using Android's native text to speech engine. */ @ExperimentalReadiumApi class AndroidTtsEngine private constructor( - private val engine: TextToSpeech, + private val context: Context, + engine: TextToSpeech, private val settingsResolver: SettingsResolver, private val voiceSelector: VoiceSelector, private val listener: Listener?, + override val voices: Set, initialPreferences: AndroidTtsPreferences ) : TtsEngine { @@ -45,23 +56,41 @@ class AndroidTtsEngine private constructor( listener: Listener?, initialPreferences: AndroidTtsPreferences ): AndroidTtsEngine? { + val textToSpeech = initializeTextToSpeech(context) + ?: return null + + val voices = textToSpeech.voices + ?.map { it.toTtsEngineVoice() } + ?.toSet() + .orEmpty() + + return AndroidTtsEngine( + context, + textToSpeech, + settingsResolver, + voiceSelector, + listener, + voices, + initialPreferences + ) + } + private suspend fun initializeTextToSpeech( + context: Context + ): TextToSpeech? { val init = CompletableDeferred() val initListener = OnInitListener { status -> init.complete(status == SUCCESS) } val engine = TextToSpeech(context, initListener) - - return if (init.await()) - AndroidTtsEngine(engine, settingsResolver, voiceSelector, listener, initialPreferences) - else - null + return if (init.await()) engine else null } /** * Starts the activity to install additional voice data. */ + @SuppressLint("QueryPermissionsNeeded") fun requestInstallVoice(context: Context) { val intent = Intent() .setAction(Engine.ACTION_INSTALL_TTS_DATA) @@ -82,6 +111,21 @@ class AndroidTtsEngine private constructor( context.startActivity(intent) } } + + private fun AndroidVoice.toTtsEngineVoice() = + Voice( + id = Voice.Id(name), + language = Language(locale), + quality = when (quality) { + QUALITY_VERY_HIGH -> Voice.Quality.Highest + QUALITY_HIGH -> Voice.Quality.High + QUALITY_NORMAL -> Voice.Quality.Normal + QUALITY_LOW -> Voice.Quality.Low + QUALITY_VERY_LOW -> Voice.Quality.Lowest + else -> throw IllegalStateException("Unexpected voice quality.") + }, + requiresNetwork = isNetworkConnectionRequired + ) } fun interface SettingsResolver { @@ -168,28 +212,59 @@ class AndroidTtsEngine private constructor( fun onLanguageNotSupported(language: Language) } + private data class Request( + val id: TtsEngine.RequestId, + val text: String, + val language: Language? + ) + + private sealed class State { + + data class EngineAvailable( + val engine: TextToSpeech + ) : State() + + data class WaitingForService( + val pendingRequests: MutableList = mutableListOf(), + ) : State() + + data class Error( + val error: AndroidTtsEngine.Error + ) : State() + } + + private val coroutineScope: CoroutineScope = + MainScope() + private val _settings: MutableStateFlow = MutableStateFlow(settingsResolver.settings(initialPreferences)) + .apply { engine.setupPitchAndSpeed(value) } private var utteranceListener: TtsEngine.Listener? = null - override val voices: Set get() = - engine.voices - ?.map { it.toTtsEngineVoice() } - ?.toSet() - .orEmpty() + private var state: State = + State.EngineAvailable(engine) + + private var isClosed: Boolean = + false + + override val settings: StateFlow = + _settings.asStateFlow() + + override fun submitPreferences(preferences: AndroidTtsPreferences) { + val newSettings = settingsResolver.settings(preferences) + _settings.value = newSettings + (state as? State.EngineAvailable) + ?.engine?.setupPitchAndSpeed(newSettings) + } override fun setListener( listener: TtsEngine.Listener? ) { - if (listener == null) { - engine.setOnUtteranceProgressListener(null) - this@AndroidTtsEngine.utteranceListener = null - } else { - this@AndroidTtsEngine.utteranceListener = listener - engine.setOnUtteranceProgressListener(UtteranceListener(listener)) - } + utteranceListener = listener + (state as? State.EngineAvailable) + ?.let { setupListener(it.engine) } } override fun speak( @@ -197,28 +272,116 @@ class AndroidTtsEngine private constructor( text: String, language: Language? ) { - engine.setupVoice(settings.value, language, voices) - val queued = engine.speak(text, QUEUE_ADD, null, requestId.id) - if (queued == ERROR) { - utteranceListener?.onError(requestId, Error(Error.Kind.Unknown.code)) + check(!isClosed) { "Engine is closed." } + val request = Request(requestId, text, language) + + when (val stateNow = state) { + is State.WaitingForService -> { + stateNow.pendingRequests.add(request) + } + is State.Error -> { + tryReconnect(request) + } + is State.EngineAvailable -> { + val result = doSpeak(stateNow.engine, request) + if (result == ERROR) { + cleanEngine(stateNow.engine) + tryReconnect(request) + } + } } } override fun stop() { - engine.stop() + when (val stateNow = state) { + is State.EngineAvailable -> { + stateNow.engine.stop() + } + is State.Error -> { + // Do nothing + } + is State.WaitingForService -> { + for (request in stateNow.pendingRequests) { + utteranceListener?.onFlushed(request.id) + } + stateNow.pendingRequests.clear() + } + } } override fun close() { - engine.shutdown() + if (isClosed) { + return + } + + isClosed = true + coroutineScope.cancel() + + when (val stateNow = state) { + is State.EngineAvailable -> { + cleanEngine(stateNow.engine) + } + is State.Error -> { + // Do nothing + } + is State.WaitingForService -> { + // Do nothing + } + } } - override val settings: StateFlow = - _settings.asStateFlow() + private fun doSpeak( + engine: TextToSpeech, + request: Request + ): Int { + engine.setupVoice(settings.value, request.language, voices) + return engine.speak(request.text, QUEUE_ADD, null, request.id.value) + } - override fun submitPreferences(preferences: AndroidTtsPreferences) { - val newSettings = settingsResolver.settings(preferences) - engine.setupPitchAndSpeed(newSettings) - _settings.value = newSettings + private fun setupListener(engine: TextToSpeech) { + if (utteranceListener == null) { + engine.setOnUtteranceProgressListener(null) + } else { + engine.setOnUtteranceProgressListener(UtteranceListener(utteranceListener)) + } + } + + private fun onReconnectionSucceeded(engine: TextToSpeech) { + val previousState = state as State.WaitingForService + setupListener(engine) + engine.setupPitchAndSpeed(_settings.value) + state = State.EngineAvailable(engine) + if (isClosed) { + engine.shutdown() + } else { + for (request in previousState.pendingRequests) { + doSpeak(engine, request) + } + } + } + + private fun onReconnectionFailed() { + val previousState = state as State.WaitingForService + val error = Error(Error.Kind.Service.code) + state = State.Error(error) + + for (request in previousState.pendingRequests) { + utteranceListener?.onError(request.id, error) + } + } + + private fun tryReconnect(request: Request) { + state = State.WaitingForService(mutableListOf(request)) + coroutineScope.launch { + initializeTextToSpeech(context) + ?.let { onReconnectionSucceeded(it) } + ?: onReconnectionFailed() + } + } + + private fun cleanEngine(engine: TextToSpeech) { + engine.setOnUtteranceProgressListener(null) + engine.shutdown() } private fun TextToSpeech.setupPitchAndSpeed(settings: AndroidTtsSettings) { @@ -235,7 +398,7 @@ class AndroidTtsEngine private constructor( .takeUnless { settings.overrideContentLanguage } ?: settings.language - when (engine.isLanguageAvailable(language.locale)) { + when (isLanguageAvailable(language.locale)) { LANG_MISSING_DATA -> listener?.onMissingData(language) LANG_NOT_SUPPORTED -> listener?.onLanguageNotSupported(language) } @@ -250,36 +413,19 @@ class AndroidTtsEngine private constructor( val voice = preferredVoiceWithRegion ?: preferredVoiceWithoutRegion - ?: defaultVoice(language, voices) + ?: run { + voiceSelector + .voice(language, voices) + ?.let { voiceForName(it.id.value) } + } voice - ?.let { engine.voice = it } - ?: run { engine.language = language.locale } + ?.let { this.voice = it } + ?: run { this.language = language.locale } } - private fun defaultVoice(language: Language?, voices: Set): AndroidVoice? = - voiceSelector - .voice(language, voices) - ?.let { voiceForName(it.id.value) } - - private fun voiceForName(name: String) = - engine.voices - .firstOrNull { it.name == name } - - private fun AndroidVoice.toTtsEngineVoice() = - Voice( - id = Voice.Id(name), - language = Language(locale), - quality = when (quality) { - QUALITY_VERY_HIGH -> Voice.Quality.Highest - QUALITY_HIGH -> Voice.Quality.High - QUALITY_NORMAL -> Voice.Quality.Normal - QUALITY_LOW -> Voice.Quality.Low - QUALITY_VERY_LOW -> Voice.Quality.Lowest - else -> throw IllegalStateException("Unexpected voice quality.") - }, - requiresNetwork = isNetworkConnectionRequired - ) + private fun TextToSpeech.voiceForName(name: String) = + voices.firstOrNull { it.name == name } class UtteranceListener( private val listener: TtsEngine.Listener? diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettingsResolver.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettingsResolver.kt index 5a17cefd8f..5f2655decf 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettingsResolver.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettingsResolver.kt @@ -6,7 +6,7 @@ package org.readium.r2.navigator.media3.tts.android -import androidx.compose.ui.text.intl.Locale +import java.util.* import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.Metadata import org.readium.r2.shared.util.Language @@ -21,7 +21,7 @@ internal class AndroidTtsSettingsResolver( val language = preferences.language ?: metadata.language ?: defaults.language - ?: Language(Locale.current.toLanguageTag()) + ?: Language(Locale.getDefault()) return AndroidTtsSettings( language = language, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt index a50c7ac9f2..86dd383884 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt @@ -65,12 +65,13 @@ internal class TtsSessionAdapter( private val streamVolumeManager = StreamVolumeManager( application, - Handler(applicationLooper), + eventHandler, StreamVolumeManagerListener() ) init { - streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage)) + val streamType = Util.getStreamTypeForAudioUsage(audioAttributes.usage) + streamVolumeManager.setStreamType(streamType) } private val audioFocusManager = AudioFocusManager( @@ -115,8 +116,8 @@ internal class TtsSessionAdapter( ListenerSet( applicationLooper, Clock.DEFAULT, - ) { listener: Listener, flags: FlagSet? -> - listener.onEvents(this, Events(flags!!)) + ) { listener: Listener, flags: FlagSet -> + listener.onEvents(this, Events(flags)) } private val permanentAvailableCommands = @@ -458,7 +459,6 @@ internal class TtsSessionAdapter( } override fun setPlaylistMetadata(mediaMetadata: MediaMetadata) { - throw NotImplementedError() } override fun getCurrentManifest(): Any? { @@ -756,10 +756,7 @@ internal class TtsSessionAdapter( ) { listener: Listener -> listener.onPlayWhenReadyChanged( playbackInfo.playWhenReady, - if (playbackInfo.state == TtsPlayer.State.Ended) - PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM - else - PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST + PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST // PLAYBACK_SUPPRESSION_REASON_NONE // playWhenReadyChangeReason ) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt index 8cfdacad23..14cb1b1980 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt @@ -6,6 +6,7 @@ package org.readium.r2.navigator.media3.tts.session +import androidx.media3.common.C import androidx.media3.common.MediaItem import androidx.media3.common.Timeline import java.util.* @@ -15,7 +16,7 @@ internal class TtsTimeline( private val mediaItems: List, ) : Timeline() { - private val uuids = (0 until windowCount) + private val uuids = mediaItems.indices .map { UUID.randomUUID() } override fun getWindowCount(): Int { @@ -49,6 +50,8 @@ internal class TtsTimeline( override fun getIndexOfPeriod(uid: Any): Int { return uuids.indexOfFirst { it == uid } + .takeUnless { it == -1 } + ?: C.INDEX_UNSET } override fun getUidOfPeriod(periodIndex: Int): Any { diff --git a/readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt b/readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt new file mode 100644 index 0000000000..494e379b6e --- /dev/null +++ b/readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt @@ -0,0 +1,108 @@ +package org.readium.r2.navigator.audio + +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds +import kotlin.time.ExperimentalTime +import org.junit.Assert.assertEquals +import org.junit.Test +import org.readium.r2.navigator.media3.audio.SmartSeeker + +@OptIn(ExperimentalTime::class) +class SmartSeekerTest { + + private val playlist: List = listOf( + 10, 20, 15, 800, 10, 230, 20, 10 + ).map { it.seconds } + + private val forwardOffset = 50.seconds + + private val backwardOffset = (-50).seconds + + @Test + fun `seek forward within current item`() { + val result = SmartSeeker.dispatchSeek( + offset = forwardOffset, + currentPosition = 200.seconds, + currentIndex = 3, + playlist + ) + assertEquals(SmartSeeker.Result(3, 250.seconds), result) + } + + @Test + fun `seek backward within current item`() { + val result = SmartSeeker.dispatchSeek( + offset = backwardOffset, + currentPosition = 200.seconds, + currentIndex = 3, + playlist + ) + assertEquals(SmartSeeker.Result(3, 150.seconds), result) + } + + @Test + fun `seek forward across items`() { + val result = SmartSeeker.dispatchSeek( + offset = forwardOffset, + currentPosition = 780.seconds, + currentIndex = 3, + playlist + ) + assertEquals(SmartSeeker.Result(5, 20.seconds), result) + } + + @Test + fun `seek backward across items`() { + val result = SmartSeeker.dispatchSeek( + offset = backwardOffset, + currentPosition = 10.seconds, + currentIndex = 3, + playlist + ) + assertEquals(SmartSeeker.Result(0, 5.seconds), result) + } + + @Test + fun `positive offset too big within last item`() { + val result = SmartSeeker.dispatchSeek( + offset = forwardOffset, + currentPosition = 5.seconds, + currentIndex = 7, + playlist + ) + assertEquals(SmartSeeker.Result(7, 10.seconds), result) + } + + @Test + fun `positive offset too big across items`() { + val result = SmartSeeker.dispatchSeek( + offset = forwardOffset, + currentPosition = 220.seconds, + currentIndex = 6, + playlist + ) + assertEquals(SmartSeeker.Result(7, 10.seconds), result) + } + + @Test + fun `negative offset too small within first item`() { + val result = SmartSeeker.dispatchSeek( + offset = backwardOffset, + currentPosition = 5.seconds, + currentIndex = 0, + playlist + ) + assertEquals(SmartSeeker.Result(0, 0.seconds), result) + } + + @Test + fun `negative offset too small across items`() { + val result = SmartSeeker.dispatchSeek( + offset = backwardOffset, + currentPosition = 10.seconds, + currentIndex = 2, + playlist + ) + assertEquals(SmartSeeker.Result(0, 0.seconds), result) + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Flow.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Flow.kt index 7d97ff3fc9..2a459af6ec 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Flow.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Flow.kt @@ -7,10 +7,7 @@ package org.readium.r2.shared.extensions import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.* import org.readium.r2.shared.InternalReadiumApi /** @@ -28,3 +25,20 @@ fun StateFlow.mapStateIn( SharingStarted.Eagerly, transform(value) ) + +/** + * Transforms the values of two [StateFlow]s and stores the result in a new [StateFlow] using the + * given [coroutineScope]. + */ +@InternalReadiumApi +fun StateFlow.combineStateIn( + coroutineScope: CoroutineScope, + flow: StateFlow, + transform: (a: T1, b: T2) -> R +): StateFlow = + this.combine(flow, transform) + .stateIn( + coroutineScope, + SharingStarted.Eagerly, + transform(value, flow.value) + ) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/units/Hertz.kt b/readium/shared/src/main/java/org/readium/r2/shared/units/Hertz.kt new file mode 100644 index 0000000000..e6b5fd9fc8 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/units/Hertz.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.units + +@JvmInline +value class Hz(val value: Double) + +val Double.hz get() = Hz(this) diff --git a/test-app/src/main/AndroidManifest.xml b/test-app/src/main/AndroidManifest.xml index 129d540698..8962ce332f 100644 --- a/test-app/src/main/AndroidManifest.xml +++ b/test-app/src/main/AndroidManifest.xml @@ -16,6 +16,12 @@ + + + + + + - - - - - - - - + diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt index a9c0010823..df5b54970c 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt @@ -20,25 +20,28 @@ import androidx.lifecycle.viewModelScope import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import kotlin.time.DurationUnit -import kotlin.time.ExperimentalTime -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import org.readium.navigator.media2.ExperimentalMedia2 -import org.readium.navigator.media2.MediaNavigator +import org.readium.r2.navigator.media3.api.AudioNavigator +import org.readium.r2.navigator.media3.api.MediaNavigator +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPreferences +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerSettings +import org.readium.r2.navigator.preferences.Configurable +import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.services.cover import org.readium.r2.testapp.R import org.readium.r2.testapp.databinding.FragmentAudiobookBinding +import org.readium.r2.testapp.reader.preferences.UserPreferencesViewModel import org.readium.r2.testapp.utils.viewLifecycle import timber.log.Timber -@OptIn(ExperimentalMedia2::class, ExperimentalTime::class, ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalReadiumApi::class) class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListener { - override lateinit var navigator: MediaNavigator + override lateinit var navigator: AudioNavigator<*, *, *> - private lateinit var displayedPlayback: MediaNavigator.Playback private var binding: FragmentAudiobookBinding by viewLifecycle() private var seekingItem: Int? = null @@ -64,6 +67,14 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + @Suppress("Unchecked_cast") + (navigator as? Configurable) + ?.let { navigator -> + @Suppress("Unchecked_cast") + (model.settings as UserPreferencesViewModel) + .bind(navigator, viewLifecycleOwner) + } + binding.publicationTitle.text = model.publication.metadata.title viewLifecycleOwner.lifecycleScope.launch { @@ -72,19 +83,14 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene } } - displayedPlayback = navigator.playback.value - - viewLifecycleOwner.lifecycleScope.launch { - navigator.playback.collectLatest { playback -> - onPlaybackChanged(playback) - } - } + navigator.playback + .onEach { onPlaybackChanged(it) } + .launchIn(viewLifecycleOwner.lifecycleScope) } - private fun onPlaybackChanged(playback: MediaNavigator.Playback) { + private fun onPlaybackChanged(playback: AudioNavigator.Playback) { Timber.v("onPlaybackChanged $playback") - this.displayedPlayback = playback - if (playback.state == MediaNavigator.Playback.State.Error) { + if (playback.state is MediaNavigator.State.Error) { onPlayerError() return } @@ -94,22 +100,24 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene binding.timelineDuration.isEnabled = true binding.timelinePosition.isEnabled = true binding.playPause.setImageResource( - if (playback.state == MediaNavigator.Playback.State.Playing) + if (playback.playWhenReady) R.drawable.ic_baseline_pause_24 else R.drawable.ic_baseline_play_arrow_24 ) + if (seekingItem == null) { - updateTimeline(playback.resource, playback.buffer.position) + updateTimeline(playback) } } - private fun updateTimeline(resource: MediaNavigator.Playback.Resource, buffered: Duration) { - binding.timelineBar.max = resource.duration?.inWholeSeconds?.toInt() ?: 0 - binding.timelineDuration.text = resource.duration?.formatElapsedTime() - binding.timelineBar.progress = resource.position.inWholeSeconds.toInt() - binding.timelinePosition.text = resource.position.formatElapsedTime() - binding.timelineBar.secondaryProgress = buffered.inWholeSeconds.toInt() + private fun updateTimeline(playback: AudioNavigator.Playback) { + val currentItem = navigator.readingOrder.items[playback.index] + binding.timelineBar.max = currentItem.duration?.inWholeSeconds?.toInt() ?: 0 + binding.timelineDuration.text = currentItem.duration?.formatElapsedTime() + binding.timelineBar.progress = playback.offset.inWholeSeconds.toInt() + binding.timelinePosition.text = playback.offset.formatElapsedTime() + binding.timelineBar.secondaryProgress = playback.buffered?.inWholeSeconds?.toInt() ?: 0 } private fun Duration.formatElapsedTime(): String = @@ -139,7 +147,7 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene @Suppress("UNUSED_PARAMETER") private fun forbidUserSeeking(view: View, event: MotionEvent): Boolean = - this.displayedPlayback.state == MediaNavigator.Playback.State.Finished + navigator.playback.value.state is MediaNavigator.State.Ended override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { if (fromUser) { @@ -149,44 +157,35 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene override fun onStartTrackingTouch(seekBar: SeekBar) { Timber.d("onStartTrackingTouch") - seekingItem = this.displayedPlayback.resource.index + seekingItem = navigator.playback.value.index } override fun onStopTrackingTouch(seekBar: SeekBar) { Timber.d("onStopTrackingTouch") - seekingItem?.let { index -> - lifecycleScope.launch { - navigator.seek(index, seekBar.progress.seconds) - // Some timeline updates might have been missed during seeking. - val playbackNow = navigator.playback.value - updateTimeline(playbackNow.resource, playbackNow.buffer.position) - seekingItem = null - } - } + navigator.seek(checkNotNull(seekingItem), seekBar.progress.seconds) + seekingItem = null } private fun onPlayPause(@Suppress("UNUSED_PARAMETER") view: View) { - return when (displayedPlayback.state) { - MediaNavigator.Playback.State.Playing -> { + return when (navigator.playback.value.state) { + is MediaNavigator.State.Ready, is MediaNavigator.State.Buffering -> { model.viewModelScope.launch { - navigator.pause() - } - Unit - } - MediaNavigator.Playback.State.Paused -> { - model.viewModelScope.launch { - navigator.play() + if (navigator.playback.value.playWhenReady) { + navigator.pause() + } else { + navigator.play() + } } Unit } - MediaNavigator.Playback.State.Finished -> { + is MediaNavigator.State.Ended -> { model.viewModelScope.launch { navigator.seek(0, Duration.ZERO) navigator.play() } Unit } - MediaNavigator.Playback.State.Error -> { + is MediaNavigator.State.Error -> { // Do nothing. } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt index 8e420630b4..089419b9ed 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt @@ -13,21 +13,29 @@ import android.content.Intent import android.content.ServiceConnection import android.os.Build import android.os.IBinder -import androidx.lifecycle.lifecycleScope -import androidx.media2.session.MediaSession -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.sample -import org.readium.navigator.media2.ExperimentalMedia2 -import org.readium.navigator.media2.MediaNavigator -import org.readium.r2.testapp.utils.LifecycleMedia2SessionService +import androidx.core.content.ContextCompat +import androidx.media3.session.MediaSession +import androidx.media3.session.MediaSessionService +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.* +import org.readium.r2.navigator.media3.api.MediaNavigator +import org.readium.r2.shared.ExperimentalReadiumApi import timber.log.Timber -@OptIn(ExperimentalMedia2::class) -class MediaService : LifecycleMedia2SessionService() { +@OptIn(ExperimentalReadiumApi::class) +typealias AnyMediaNavigator = MediaNavigator<*, *, *> + +@OptIn(ExperimentalReadiumApi::class) +@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) +class MediaService : MediaSessionService() { + + class Session( + val bookId: Long, + val navigator: AnyMediaNavigator, + val mediaSession: MediaSession, + ) { + val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + } /** * The service interface to be used by the app. @@ -37,38 +45,50 @@ class MediaService : LifecycleMedia2SessionService() { private val app: org.readium.r2.testapp.Application get() = application as org.readium.r2.testapp.Application - private var saveLocationJob: Job? = null - - private var mediaNavigator: MediaNavigator? = null + private val sessionMutable: MutableStateFlow = + MutableStateFlow(null) - var mediaSession: MediaSession? = null + val session: StateFlow = + sessionMutable.asStateFlow() - fun closeNavigator() { + fun closeSession() { stopForeground(true) - mediaSession?.close() - mediaSession = null - saveLocationJob?.cancel() - saveLocationJob = null - mediaNavigator?.close() - mediaNavigator?.publication?.close() - mediaNavigator = null + session.value?.mediaSession?.release() + session.value?.navigator?.close() + session.value?.coroutineScope?.cancel() + sessionMutable.value = null } - @OptIn(FlowPreview::class) - fun bindNavigator(navigator: MediaNavigator, bookId: Long) { + fun openSession( + navigator: AnyMediaNavigator, + bookId: Long + ) { val activityIntent = createSessionActivityIntent() - mediaNavigator = navigator - mediaSession = navigator.session(applicationContext, activityIntent) - .also { addSession(it) } + val mediaSession = MediaSession.Builder(applicationContext, navigator.asPlayer()) + .setSessionActivity(activityIntent) + .setId(bookId.toString()) + .build() + + addSession(mediaSession) + + val session = Session( + bookId, + navigator, + mediaSession + ) + + sessionMutable.value = session /* * Launch a job for saving progression even when playback is going on in the background * with no ReaderActivity opened. */ - saveLocationJob = navigator.currentLocator + navigator.currentLocator .sample(3000) - .onEach { locator -> app.bookRepository.saveProgression(locator, bookId) } - .launchIn(lifecycleScope) + .onEach { locator -> + Timber.d("Saving TTS progression $locator") + app.bookRepository.saveProgression(locator, bookId) + }.launchIn(session.coroutineScope) } private fun createSessionActivityIntent(): PendingIntent { @@ -79,6 +99,7 @@ class MediaService : LifecycleMedia2SessionService() { } val intent = application.packageManager.getLaunchIntentForPackage(application.packageName) + return PendingIntent.getActivity(applicationContext, 0, intent, flags) } } @@ -87,15 +108,10 @@ class MediaService : LifecycleMedia2SessionService() { Binder() } - override fun onCreate() { - super.onCreate() - Timber.d("MediaService created.") - } - - override fun onBind(intent: Intent): IBinder? { + override fun onBind(intent: Intent?): IBinder? { Timber.d("onBind called with $intent") - return if (intent.action == SERVICE_INTERFACE) { + return if (intent?.action == SERVICE_INTERFACE) { super.onBind(intent) // Readium-aware client. Timber.d("Returning custom binder.") @@ -108,19 +124,14 @@ class MediaService : LifecycleMedia2SessionService() { } override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? { - return binder.mediaSession - } - - override fun onDestroy() { - super.onDestroy() - Timber.d("MediaService destroyed.") + return binder.session.value?.mediaSession } override fun onTaskRemoved(rootIntent: Intent) { super.onTaskRemoved(rootIntent) Timber.d("Task removed. Stopping session and service.") // Close the navigator to allow the service to be stopped. - binder.closeNavigator() + binder.closeSession() stopSelf() } @@ -130,10 +141,10 @@ class MediaService : LifecycleMedia2SessionService() { fun start(application: Application) { val intent = intent(application) - application.startService(intent) + ContextCompat.startForegroundService(application, intent) } - suspend fun bind(application: Application): MediaService.Binder { + suspend fun bind(application: Application): Binder { val mediaServiceBinder: CompletableDeferred = CompletableDeferred() @@ -141,12 +152,11 @@ class MediaService : LifecycleMedia2SessionService() { override fun onServiceConnected(name: ComponentName?, service: IBinder) { Timber.d("MediaService bound.") - mediaServiceBinder.complete(service as MediaService.Binder) + mediaServiceBinder.complete(service as Binder) } override fun onServiceDisconnected(name: ComponentName) { - Timber.e("MediaService disconnected.") - + Timber.d("MediaService disconnected.") // Should not happen, do nothing. } @@ -155,7 +165,6 @@ class MediaService : LifecycleMedia2SessionService() { Timber.e(errorMessage) val exception = IllegalStateException(errorMessage) mediaServiceBinder.completeExceptionally(exception) - // Should not happen, do nothing. } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsServiceFacade.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaServiceFacade.kt similarity index 66% rename from test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsServiceFacade.kt rename to test-app/src/main/java/org/readium/r2/testapp/reader/MediaServiceFacade.kt index 7bece6912e..53438c135d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsServiceFacade.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaServiceFacade.kt @@ -1,18 +1,23 @@ -package org.readium.r2.testapp.reader.tts +/* + * Copyright 2022 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.reader import android.app.Application import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import org.readium.r2.navigator.media3.tts.AndroidTtsNavigator import org.readium.r2.shared.ExperimentalReadiumApi /** - * Enables to try to close a session without starting the [TtsService] if it is not started. + * Enables to try to close a session without starting the [MediaService] if it is not started. */ @OptIn(ExperimentalReadiumApi::class) -class TtsServiceFacade( +class MediaServiceFacade( private val application: Application ) { private val coroutineScope: CoroutineScope = @@ -21,21 +26,21 @@ class TtsServiceFacade( private val mutex: Mutex = Mutex() - private var binder: TtsService.Binder? = + private var binder: MediaService.Binder? = null private var bindingJob: Job? = null - private val sessionMutable: MutableStateFlow = + private val sessionMutable: MutableStateFlow = MutableStateFlow(null) - val session: StateFlow = + val session: StateFlow = sessionMutable.asStateFlow() suspend fun openSession( bookId: Long, - navigator: AndroidTtsNavigator + navigator: AnyMediaNavigator ) = mutex.withLock { if (session.value != null) { throw CancellationException("A session is already running.") @@ -43,8 +48,8 @@ class TtsServiceFacade( try { if (binder == null) { - TtsService.start(application) - val binder = TtsService.bind(application) + MediaService.start(application) + val binder = MediaService.bind(application) this.binder = binder bindingJob = binder.session .onEach { sessionMutable.value = it } @@ -53,7 +58,7 @@ class TtsServiceFacade( binder!!.openSession(navigator, bookId) } catch (e: CancellationException) { - TtsService.stop(application) + MediaService.stop(application) throw e } } @@ -68,7 +73,7 @@ class TtsServiceFacade( binder!!.closeSession() sessionMutable.value = null binder = null - TtsService.stop(application) + MediaService.stop(application) } } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt index cf042237f6..45c35dcc95 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt @@ -11,17 +11,17 @@ package org.readium.r2.testapp.reader import org.readium.adapters.pdfium.navigator.PdfiumPreferences import org.readium.adapters.pdfium.navigator.PdfiumPreferencesEditor import org.readium.adapters.pdfium.navigator.PdfiumSettings -import org.readium.navigator.media2.ExperimentalMedia2 -import org.readium.navigator.media2.MediaNavigator import org.readium.r2.navigator.epub.EpubNavigatorFactory import org.readium.r2.navigator.epub.EpubPreferences +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerNavigator +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerNavigatorFactory +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPreferences import org.readium.r2.navigator.media3.tts.AndroidTtsNavigatorFactory import org.readium.r2.navigator.media3.tts.android.AndroidTtsPreferences import org.readium.r2.navigator.pdf.PdfNavigatorFactory import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.* import org.readium.r2.testapp.reader.preferences.PreferencesManager -import org.readium.r2.testapp.reader.tts.TtsServiceFacade sealed class ReaderInitData { abstract val bookId: Long @@ -31,7 +31,7 @@ sealed class ReaderInitData { sealed class VisualReaderInitData( override val bookId: Long, override val publication: Publication, - var initialLocation: Locator?, + val initialLocation: Locator?, val ttsInitData: TtsInitData?, ) : ReaderInitData() @@ -60,14 +60,18 @@ class PdfReaderInitData( ttsInitData: TtsInitData?, ) : VisualReaderInitData(bookId, publication, initialLocation, ttsInitData) -@OptIn(ExperimentalMedia2::class) +class TtsInitData( + val mediaServiceFacade: MediaServiceFacade, + val navigatorFactory: AndroidTtsNavigatorFactory, + val preferencesManager: PreferencesManager, +) + class MediaReaderInitData( override val bookId: Long, override val publication: Publication, - val mediaNavigator: MediaNavigator, - val sessionBinder: MediaService.Binder - // val preferencesManager: PreferencesManager, - // val navigatorFactory: PlayerNavigatorFactory + val mediaNavigator: ExoPlayerNavigator, + val preferencesManager: PreferencesManager, + val navigatorFactory: ExoPlayerNavigatorFactory ) : ReaderInitData() class DummyReaderInitData( @@ -79,9 +83,3 @@ class DummyReaderInitData( ) ) } - -class TtsInitData( - val ttsServiceFacade: TtsServiceFacade, - val ttsNavigatorFactory: AndroidTtsNavigatorFactory, - val preferencesManager: PreferencesManager, -) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt index db187d7d25..9f6596dd14 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt @@ -13,9 +13,9 @@ import androidx.datastore.preferences.core.Preferences as JetpackPreferences import java.io.File import org.json.JSONObject import org.readium.adapters.pdfium.navigator.PdfiumEngineProvider -import org.readium.navigator.media2.ExperimentalMedia2 -import org.readium.navigator.media2.MediaNavigator import org.readium.r2.navigator.epub.EpubNavigatorFactory +import org.readium.r2.navigator.media3.audio.AudioNavigatorFactory +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerEngineProvider import org.readium.r2.navigator.media3.tts.TtsNavigatorFactory import org.readium.r2.navigator.pdf.PdfNavigatorFactory import org.readium.r2.shared.ExperimentalReadiumApi @@ -25,13 +25,12 @@ import org.readium.r2.shared.publication.asset.FileAsset import org.readium.r2.shared.publication.services.isRestricted import org.readium.r2.shared.publication.services.protectionError import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.getOrElse import org.readium.r2.testapp.Readium import org.readium.r2.testapp.bookshelf.BookRepository import org.readium.r2.testapp.reader.preferences.AndroidTtsPreferencesManagerFactory import org.readium.r2.testapp.reader.preferences.EpubPreferencesManagerFactory +import org.readium.r2.testapp.reader.preferences.ExoPlayerPreferencesManagerFactory import org.readium.r2.testapp.reader.preferences.PdfiumPreferencesManagerFactory -import org.readium.r2.testapp.reader.tts.TtsServiceFacade import timber.log.Timber /** @@ -53,8 +52,8 @@ class ReaderRepository( private val repository: MutableMap = mutableMapOf() - private val ttsServiceFacade: TtsServiceFacade = - TtsServiceFacade(application) + private val mediaServiceFacade: MediaServiceFacade = + MediaServiceFacade(application) operator fun get(bookId: Long): ReaderInitData? = repository[bookId] @@ -107,58 +106,29 @@ class ReaderRepository( repository[bookId] = readerInitData } - @OptIn(ExperimentalMedia2::class) private suspend fun openAudio( bookId: Long, publication: Publication, initialLocator: Locator? ): MediaReaderInitData { - val navigator = MediaNavigator.create( - application, - publication, - initialLocator - ).getOrElse { throw Exception("Cannot open audiobook.") } - - MediaService.start(application) - val mediaBinder = MediaService.bind(application) - mediaBinder.bindNavigator(navigator, bookId) - return MediaReaderInitData(bookId, publication, navigator, mediaBinder) - } - - /* private suspend fun openAudio( - bookId: Long, - publication: Publication, - initialLocator: Locator? - ): MediaReaderInitData { - val preferencesManager = ExoPlayerPreferencesManagerFactory(preferencesDataStore) .createPreferenceManager(bookId) - val mediaEngine = ExoPlayerEngineProvider(application) val initialPreferences = preferencesManager.preferences.value - val actualInitialLocator = initialLocator - ?: publication.locatorFromLink(publication.readingOrder[0])!! - val navigatorFactory = PlayerNavigatorFactory( + val navigatorFactory = AudioNavigatorFactory( publication, - mediaEngine, - DefaultMetadataProvider(), - initialPreferences, - actualInitialLocator, - ) + ExoPlayerEngineProvider(application), + ) ?: throw Exception("Cannot open audiobook.") - val navigator = navigatorFactory.getMediaNavigator() - .getOrElse { throw Exception("Cannot open audiobook.") } - - val navigator = MediaNavigator.create( - application, - publication, + val navigator = navigatorFactory.createNavigator( + initialPreferences, initialLocator - ).getOrElse { throw Exception("Cannot open audiobook.") } + ) ?: throw Exception("Cannot open audiobook.") - mediaBinder.bindNavigator(navigator, bookId) - return MediaReaderInitData(bookId, publication,, preferencesManager, navigatorFactory) - } */ + mediaServiceFacade.openSession(bookId, navigator) + return MediaReaderInitData(bookId, publication, navigator, preferencesManager, navigatorFactory) + } private suspend fun openEpub( bookId: Long, @@ -216,19 +186,18 @@ class ReaderRepository( val preferencesManager = AndroidTtsPreferencesManagerFactory(preferencesDataStore) .createPreferenceManager(bookId) val navigatorFactory = TtsNavigatorFactory(application, publication) ?: return null - return TtsInitData(ttsServiceFacade, navigatorFactory, preferencesManager) + return TtsInitData(mediaServiceFacade, navigatorFactory, preferencesManager) } suspend fun close(bookId: Long) { - Timber.d("Closing Publication") + Timber.v("Closing Publication $bookId.") when (val initData = repository.remove(bookId)) { is MediaReaderInitData -> { - initData.sessionBinder.closeNavigator() - MediaService.stop(application) + mediaServiceFacade.closeSession() initData.publication.close() } is VisualReaderInitData -> { - initData.ttsInitData?.ttsServiceFacade?.closeSession() + mediaServiceFacade.closeSession() initData.publication.close() } null, is DummyReaderInitData -> { diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt index 2ddf3868ef..9c050be655 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt @@ -75,7 +75,6 @@ class ReaderViewModel( fun close() { viewModelScope.launch { - tts?.stop() readerRepository.close(bookId) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt index 9cd54fb689..b56ac76cf0 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt @@ -29,8 +29,6 @@ import org.readium.r2.navigator.epub.EpubPublicationPreferencesFilter import org.readium.r2.navigator.epub.EpubSharedPreferencesFilter import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPreferences import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPreferencesSerializer -import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPublicationPreferencesFilter -import org.readium.r2.navigator.media3.exoplayer.ExoPlayerSharedPreferencesFilter import org.readium.r2.navigator.media3.tts.android.AndroidTtsPreferences import org.readium.r2.navigator.media3.tts.android.AndroidTtsPreferencesSerializer import org.readium.r2.navigator.media3.tts.android.AndroidTtsPublicationPreferencesFilter @@ -144,8 +142,8 @@ class ExoPlayerPreferencesManagerFactory( ) : PreferencesManagerFactory( dataStore = dataStore, klass = ExoPlayerPreferences::class, - sharedPreferencesFilter = ExoPlayerSharedPreferencesFilter, - publicationPreferencesFilter = ExoPlayerPublicationPreferencesFilter, + sharedPreferencesFilter = { preferences -> preferences }, + publicationPreferencesFilter = { ExoPlayerPreferences() }, preferencesSerializer = ExoPlayerPreferencesSerializer(), emptyPreferences = ExoPlayerPreferences() ) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt index 88af6ccda2..89f8ffcf35 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt @@ -15,12 +15,12 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import org.readium.adapters.pdfium.navigator.PdfiumPreferencesEditor import org.readium.r2.navigator.epub.EpubPreferencesEditor +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPreferencesEditor import org.readium.r2.navigator.media3.tts.android.AndroidTtsEngine import org.readium.r2.navigator.preferences.* import org.readium.r2.navigator.preferences.TextAlign as ReadiumTextAlign @@ -135,49 +135,62 @@ private fun

, E : PreferencesEditor

> UserPref ) } is TtsPreferencesEditor -> - TtsUserPreferences( + MediaUserPreferences( commit = commit, language = editor.language, voice = editor.voice, speed = editor.speed, pitch = editor.pitch ) + is ExoPlayerPreferencesEditor -> + MediaUserPreferences( + commit = commit, + speed = editor.speed, + pitch = editor.pitch + ) } } } @Composable -private fun ColumnScope.TtsUserPreferences( +private fun MediaUserPreferences( commit: () -> Unit, - language: Preference, - voice: EnumPreference, - speed: RangePreference, - pitch: RangePreference + language: Preference? = null, + voice: EnumPreference? = null, + speed: RangePreference? = null, + pitch: RangePreference? = null ) { Column { - StepperItem( - title = stringResource(R.string.speed_rate), - preference = speed, - commit = commit - ) - StepperItem( - title = stringResource(R.string.pitch_rate), - preference = pitch, - commit = commit - ) - LanguageItem( - preference = language, - commit = commit - ) + if (speed != null) { + StepperItem( + title = stringResource(R.string.speed_rate), + preference = speed, + commit = commit + ) + } - val context = LocalContext.current + if (pitch != null) { + StepperItem( + title = stringResource(R.string.pitch_rate), + preference = pitch, + commit = commit + ) + } + if (language != null) { + LanguageItem( + preference = language, + commit = commit + ) + } - MenuItem( - title = stringResource(R.string.tts_voice), - preference = voice, - formatValue = { it?.value ?: context.getString(R.string.defaultValue) }, - commit = commit - ) + if (voice != null) { + MenuItem( + title = stringResource(R.string.tts_voice), + preference = voice, + formatValue = { it?.value ?: "Default" }, + commit = commit + ) + } } } @@ -185,7 +198,7 @@ private fun ColumnScope.TtsUserPreferences( * User settings for a publication with a fixed layout, such as fixed-layout EPUB, PDF or comic book. */ @Composable -private fun ColumnScope.FixedLayoutUserPreferences( +private fun FixedLayoutUserPreferences( commit: () -> Unit, language: Preference? = null, readingProgression: EnumPreference? = null, @@ -198,12 +211,6 @@ private fun ColumnScope.FixedLayoutUserPreferences( pageSpacing: RangePreference? = null ) { if (language != null || readingProgression != null) { - fun reset() { - language?.clear() - readingProgression?.clear() - commit() - } - if (language != null) { LanguageItem( preference = language, @@ -305,7 +312,7 @@ private fun ColumnScope.FixedLayoutUserPreferences( * a reflowable EPUB, HTML document or PDF with reflow mode enabled. */ @Composable -private fun ColumnScope.ReflowableUserPreferences( +private fun ReflowableUserPreferences( commit: () -> Unit, backgroundColor: Preference? = null, columnCount: EnumPreference? = null, @@ -333,13 +340,6 @@ private fun ColumnScope.ReflowableUserPreferences( wordSpacing: RangePreference? = null, ) { if (language != null || readingProgression != null || verticalText != null) { - fun reset() { - language?.clear() - readingProgression?.clear() - verticalText?.clear() - commit() - } - if (language != null) { LanguageItem( preference = language, diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt index 991639b320..0659661d54 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt @@ -18,13 +18,12 @@ import org.readium.adapters.pdfium.navigator.PdfiumPreferences import org.readium.adapters.pdfium.navigator.PdfiumSettings import org.readium.r2.navigator.epub.EpubPreferences import org.readium.r2.navigator.epub.EpubSettings +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPreferences +import org.readium.r2.navigator.media3.exoplayer.ExoPlayerSettings import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.navigator.preferences.PreferencesEditor import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.testapp.reader.EpubReaderInitData -import org.readium.r2.testapp.reader.PdfReaderInitData -import org.readium.r2.testapp.reader.ReaderInitData -import org.readium.r2.testapp.reader.ReaderViewModel +import org.readium.r2.testapp.reader.* import org.readium.r2.testapp.utils.extensions.mapStateIn /** @@ -36,8 +35,8 @@ import org.readium.r2.testapp.utils.extensions.mapStateIn */ @OptIn(ExperimentalReadiumApi::class) class UserPreferencesViewModel>( - private val bookId: Long, private val viewModelScope: CoroutineScope, + private val bookId: Long, private val preferencesManager: PreferencesManager

, private val createPreferencesEditor: (P) -> PreferencesEditor

) { @@ -68,16 +67,22 @@ class UserPreferencesViewModel with(readerInitData) { UserPreferencesViewModel( - bookId, viewModelScope, preferencesManager, + viewModelScope, bookId, preferencesManager, createPreferencesEditor = navigatorFactory::createPreferencesEditor ) } is PdfReaderInitData -> with(readerInitData) { UserPreferencesViewModel( - bookId, viewModelScope, preferencesManager, + viewModelScope, bookId, preferencesManager, createPreferencesEditor = navigatorFactory::createPreferencesEditor ) } + is MediaReaderInitData -> with(readerInitData) { + UserPreferencesViewModel( + viewModelScope, bookId, preferencesManager, + createPreferencesEditor = navigatorFactory::createAudioPreferencesEditor + ) + } else -> null } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt index a5459d8ba0..445080b1a6 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt @@ -4,8 +4,6 @@ * available in the top-level LICENSE file of the project. */ -@file:OptIn(ExperimentalReadiumApi::class) - package org.readium.r2.testapp.reader.tts import androidx.compose.foundation.layout.Arrangement @@ -23,7 +21,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.testapp.R import org.readium.r2.testapp.utils.extensions.asStateWhenStarted diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsPreferencesEditor.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsPreferencesEditor.kt index 303743b977..5ab076d1ea 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsPreferencesEditor.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsPreferencesEditor.kt @@ -41,7 +41,6 @@ class TtsPreferencesEditor( * TTS default language and to ignore regions. */ val voice: EnumPreference = run { - // Recomposition will be triggered higher if the value changes. val currentLanguage = language.effectiveValue?.removeRegion() editor.voices.map( diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsService.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsService.kt deleted file mode 100644 index b759bfc0e0..0000000000 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsService.kt +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.testapp.reader.tts - -import android.app.Application -import android.app.PendingIntent -import android.content.ComponentName -import android.content.Intent -import android.content.ServiceConnection -import android.os.Build -import android.os.IBinder -import androidx.core.content.ContextCompat -import androidx.media3.session.MediaSession -import androidx.media3.session.MediaSessionService -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.* -import org.readium.r2.navigator.media3.tts.AndroidTtsNavigator -import org.readium.r2.shared.ExperimentalReadiumApi -import timber.log.Timber - -@OptIn(ExperimentalReadiumApi::class) -@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) -class TtsService : MediaSessionService() { - - class Session( - val bookId: Long, - val navigator: AndroidTtsNavigator, - val mediaSession: MediaSession, - ) { - val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) - } - - /** - * The service interface to be used by the app. - */ - inner class Binder : android.os.Binder() { - - private val app: org.readium.r2.testapp.Application - get() = application as org.readium.r2.testapp.Application - - private val sessionMutable: MutableStateFlow = - MutableStateFlow(null) - - val session: StateFlow = - sessionMutable.asStateFlow() - - fun closeSession() { - stopForeground(true) - session.value?.mediaSession?.release() - session.value?.navigator?.close() - session.value?.coroutineScope?.cancel() - sessionMutable.value = null - } - - @OptIn(FlowPreview::class) - fun openSession( - navigator: AndroidTtsNavigator, - bookId: Long - ) { - val activityIntent = createSessionActivityIntent() - val mediaSession = MediaSession.Builder(applicationContext, navigator.asPlayer()) - .setSessionActivity(activityIntent) - .setId(bookId.toString()) - .build() - - addSession(mediaSession) - - val session = Session( - bookId, - navigator, - mediaSession - ) - - sessionMutable.value = session - - /* - * Launch a job for saving progression even when playback is going on in the background - * with no ReaderActivity opened. - */ - navigator.currentLocator - .sample(3000) - .onEach { locator -> - Timber.d("Saving TTS progression $locator") - app.bookRepository.saveProgression(locator, bookId) - }.launchIn(session.coroutineScope) - } - - private fun createSessionActivityIntent(): PendingIntent { - // This intent will be triggered when the notification is clicked. - var flags = PendingIntent.FLAG_UPDATE_CURRENT - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - flags = flags or PendingIntent.FLAG_IMMUTABLE - } - - val intent = application.packageManager.getLaunchIntentForPackage(application.packageName) - - return PendingIntent.getActivity(applicationContext, 0, intent, flags) - } - } - - private val binder by lazy { - Binder() - } - - override fun onBind(intent: Intent?): IBinder? { - Timber.d("onBind called with $intent") - - return if (intent?.action == SERVICE_INTERFACE) { - super.onBind(intent) - // Readium-aware client. - Timber.d("Returning custom binder.") - binder - } else { - // External controller. - Timber.d("Returning MediaSessionService binder.") - super.onBind(intent) - } - } - - override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? { - return binder.session.value?.mediaSession - } - - override fun onTaskRemoved(rootIntent: Intent) { - super.onTaskRemoved(rootIntent) - Timber.d("Task removed. Stopping session and service.") - // Close the navigator to allow the service to be stopped. - binder.closeSession() - stopSelf() - } - - companion object { - - const val SERVICE_INTERFACE = "org.readium.r2.testapp.reader.tts.TtsService" - - fun start(application: Application) { - val intent = intent(application) - ContextCompat.startForegroundService(application, intent) - } - - suspend fun bind(application: Application): TtsService.Binder { - val mediaServiceBinder: CompletableDeferred = - CompletableDeferred() - - val mediaServiceConnection = object : ServiceConnection { - - override fun onServiceConnected(name: ComponentName?, service: IBinder) { - Timber.d("MediaService bound.") - mediaServiceBinder.complete(service as Binder) - } - - override fun onServiceDisconnected(name: ComponentName) { - Timber.d("MediaService disconnected.") - // Should not happen, do nothing. - } - - override fun onNullBinding(name: ComponentName) { - val errorMessage = "Failed to bind to MediaService." - Timber.e(errorMessage) - val exception = IllegalStateException(errorMessage) - mediaServiceBinder.completeExceptionally(exception) - } - } - - val intent = intent(application) - application.bindService(intent, mediaServiceConnection, 0) - - return mediaServiceBinder.await() - } - - fun stop(application: Application) { - val intent = intent(application) - application.stopService(intent) - } - - private fun intent(application: Application) = - Intent(SERVICE_INTERFACE) - // MediaSessionService.onBind requires the intent to have a non-null action - .apply { setClass(application, TtsService::class.java) } - } -} diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt index eac63df43a..5d130ab097 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt @@ -26,11 +26,14 @@ import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.util.Language import org.readium.r2.testapp.R +import org.readium.r2.testapp.reader.MediaService +import org.readium.r2.testapp.reader.MediaServiceFacade import org.readium.r2.testapp.reader.ReaderInitData import org.readium.r2.testapp.reader.VisualReaderInitData import org.readium.r2.testapp.reader.preferences.PreferencesManager import org.readium.r2.testapp.reader.preferences.UserPreferencesViewModel import org.readium.r2.testapp.utils.extensions.mapStateIn +import timber.log.Timber /** * View model controlling a [TtsNavigator] to read a publication aloud. @@ -43,7 +46,7 @@ class TtsViewModel private constructor( private val bookId: Long, private val publication: Publication, private val ttsNavigatorFactory: AndroidTtsNavigatorFactory, - private val ttsServiceFacade: TtsServiceFacade, + private val mediaServiceFacade: MediaServiceFacade, private val preferencesManager: PreferencesManager, ) : TtsNavigator.Listener { @@ -64,8 +67,8 @@ class TtsViewModel private constructor( viewModelScope = viewModelScope, bookId = readerInitData.bookId, publication = readerInitData.publication, - ttsNavigatorFactory = readerInitData.ttsInitData.ttsNavigatorFactory, - ttsServiceFacade = readerInitData.ttsInitData.ttsServiceFacade, + ttsNavigatorFactory = readerInitData.ttsInitData.navigatorFactory, + mediaServiceFacade = readerInitData.ttsInitData.mediaServiceFacade, preferencesManager = readerInitData.ttsInitData.preferencesManager ) } @@ -83,8 +86,12 @@ class TtsViewModel private constructor( class OnMissingVoiceData(val language: Language) : Event() } + @Suppress("Unchecked_cast") + private val MediaService.Session.ttsNavigator + get() = navigator as? AndroidTtsNavigator + private val navigatorNow: AndroidTtsNavigator? get() = - ttsServiceFacade.session.value?.navigator + mediaServiceFacade.session.value?.ttsNavigator private val _events: Channel = Channel(Channel.BUFFERED) @@ -99,36 +106,34 @@ class TtsViewModel private constructor( preferencesManager = preferencesManager ) { preferences -> val baseEditor = ttsNavigatorFactory.createTtsPreferencesEditor(preferences) + val voices = navigatorNow?.voices.orEmpty() TtsPreferencesEditor(baseEditor, voices) } val showControls: StateFlow = - ttsServiceFacade.session.mapStateIn(viewModelScope) { + mediaServiceFacade.session.mapStateIn(viewModelScope) { it != null } val isPlaying: StateFlow = - ttsServiceFacade.session.flatMapLatest { session -> + mediaServiceFacade.session.flatMapLatest { session -> session?.navigator?.playback?.map { playback -> playback.playWhenReady } ?: MutableStateFlow(false) }.stateIn(viewModelScope, SharingStarted.Eagerly, false) val position: StateFlow = - ttsServiceFacade.session.flatMapLatest { session -> + mediaServiceFacade.session.flatMapLatest { session -> session?.navigator?.currentLocator ?: MutableStateFlow(null) }.stateIn(viewModelScope, SharingStarted.Eagerly, null) val highlight: StateFlow = - ttsServiceFacade.session.flatMapLatest { session -> - session?.navigator?.utterance?.map { it.utteranceLocator } + mediaServiceFacade.session.flatMapLatest { session -> + session?.ttsNavigator?.location?.map { it.utteranceLocator } ?: MutableStateFlow(null) }.stateIn(viewModelScope, SharingStarted.Eagerly, null) - val voices: Set get() = - ttsServiceFacade.session.value?.navigator?.voices.orEmpty() - init { - ttsServiceFacade.session + mediaServiceFacade.session .flatMapLatest { it?.navigator?.playback ?: MutableStateFlow(null) } .onEach { playback -> when (playback?.state) { @@ -146,7 +151,7 @@ class TtsViewModel private constructor( }.launchIn(viewModelScope) preferencesManager.preferences - .onEach { ttsServiceFacade.session.value?.navigator?.submitPreferences(it) } + .onEach { navigatorNow?.submitPreferences(it) } .launchIn(viewModelScope) } @@ -155,7 +160,7 @@ class TtsViewModel private constructor( */ fun start(navigator: Navigator) { viewModelScope.launch { - if (ttsServiceFacade.session.value != null) + if (mediaServiceFacade.session.value != null) return@launch openSession(navigator) @@ -178,12 +183,12 @@ class TtsViewModel private constructor( // playWhenReady must be true for the MediaSessionService to call Service.startForeground // and prevent crashing ttsNavigator.play() - ttsServiceFacade.openSession(bookId, ttsNavigator) + mediaServiceFacade.openSession(bookId, ttsNavigator) } fun stop() { viewModelScope.launch { - ttsServiceFacade.closeSession() + mediaServiceFacade.closeSession() } } @@ -210,15 +215,17 @@ class TtsViewModel private constructor( private fun onPlaybackError(error: TtsNavigator.State.Error) { val exception = when (error) { is TtsNavigator.State.Error.ContentError -> { + Timber.e(error.exception) UserException(R.string.tts_error_other, cause = error.exception) } is TtsNavigator.State.Error.EngineError<*> -> { - when ((error.error as AndroidTtsEngine.Error).kind) { + val kind = (error.error as AndroidTtsEngine.Error).kind + when (kind) { AndroidTtsEngine.Error.Kind.Network -> UserException(R.string.tts_error_network) else -> UserException(R.string.tts_error_other) - } + }.also { Timber.e(it, "Error type: ${kind.name}") } } } diff --git a/test-app/src/main/res/values/strings.xml b/test-app/src/main/res/values/strings.xml index 6a4bbec932..ba9c0e7aa3 100644 --- a/test-app/src/main/res/values/strings.xml +++ b/test-app/src/main/res/values/strings.xml @@ -197,7 +197,6 @@ Select a font Close Language - Default Failed to initialize the TTS engine The language %s is not supported From 522e88466cb986a19d67690ce37a97053bc2f197 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:11:53 +0200 Subject: [PATCH 02/65] Fix the hyphens setting (#347) --- .../org/readium/r2/navigator/epub/EpubPreferencesEditor.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt index f045ea843e..c3458afba4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt @@ -144,7 +144,10 @@ class EpubPreferencesEditor internal constructor( val hyphens: Preference = PreferenceDelegate( getValue = { preferences.hyphens }, - getEffectiveValue = { state.settings.hyphens ?: false }, + getEffectiveValue = { + state.settings.hyphens + ?: (state.settings.textAlign == TextAlign.JUSTIFY) + }, getIsEffective = ::isHyphensEffective, updateValue = { value -> updateValues { it.copy(hyphens = value) } }, ) @@ -471,7 +474,7 @@ class EpubPreferencesEditor internal constructor( private fun isHyphensEffective() = layout == EpubLayout.REFLOWABLE && state.layout.stylesheets == Layout.Stylesheets.Default && !state.settings.publisherStyles && - preferences.hyphens != null + (preferences.hyphens != null || state.settings.textAlign == TextAlign.JUSTIFY) private fun isLetterSpacingEffective() = layout == EpubLayout.REFLOWABLE && state.layout.stylesheets == Layout.Stylesheets.Default && From c1c8df3fc401f824783ce8d2d33b8aa932b62715 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:36:55 +0200 Subject: [PATCH 03/65] Add support for full remote publications (#337) --- docs/migration-guide.md | 9 + .../readium/r2/lcp/LcpContentProtection.kt | 70 +- .../java/org/readium/r2/lcp/LcpDecryptor.kt | 57 +- .../java/org/readium/r2/lcp/LcpService.kt | 60 +- .../r2/lcp/auth/LcpDumbAuthentication.kt | 19 + .../r2/lcp/license/LicenseValidation.kt | 51 +- .../container/ArchiveLicenseContainer.kt | 39 + .../license/container/EPUBLicenseContainer.kt | 16 - .../container/FetcherLicenseContainer.kt | 42 + .../license/container/LCPLLicenseContainer.kt | 1 + .../lcp/license/container/LicenseContainer.kt | 27 +- .../container/WebPubLicenseContainer.kt | 16 - .../license/container/ZIPLicenseContainer.kt | 6 +- .../r2/lcp/service/LcpLicensedAsset.kt | 21 + .../readium/r2/lcp/service/LicensesService.kt | 120 +- .../java/org/readium/r2/shared/URLHelper.kt | 10 - .../r2/shared/extensions/InputStream.kt | 15 + .../r2/shared/fetcher/ArchiveFetcher.kt | 6 + .../readium/r2/shared/fetcher/HttpFetcher.kt | 23 +- .../shared/publication/ContentProtection.kt | 23 +- .../asset/DefaultPublicationAssetFactory.kt | 51 + .../r2/shared/publication/asset/FileAsset.kt | 108 +- .../publication/asset/PublicationAsset.kt | 15 +- .../asset/PublicationAssetFactory.kt | 26 + .../shared/publication/asset/RemoteAsset.kt | 62 + .../org/readium/r2/shared/util/CursorList.kt | 6 + .../java/org/readium/r2/shared/util/Url.kt | 54 + .../readium/r2/shared/util/archive/Archive.kt | 31 + .../channel/BufferedReadableChannel.kt | 95 + .../archive/channel/CachingReadableChannel.kt | 105 + .../shared/util/archive/channel/ChannelZip.kt | 152 ++ .../archive/channel/FileChannelAdapter.java | 69 + .../util/archive/channel/HttpChannel.kt | 166 ++ .../compress/archivers/ArchiveEntry.java | 62 + .../archivers/ArchiveInputStream.java | 156 ++ .../archivers/ArchiveOutputStream.java | 169 ++ .../archivers/EntryStreamOffsets.java | 46 + .../zip/AbstractUnicodeExtraField.java | 193 ++ .../archivers/zip/CharsetAccessor.java | 50 + .../zip/ExtraFieldParsingBehavior.java | 69 + .../archivers/zip/ExtraFieldUtils.java | 414 ++++ .../archivers/zip/GeneralPurposeBit.java | 252 +++ .../InflaterInputStreamWithStatistics.java | 89 + .../archivers/zip/NioZipEncoding.java | 223 ++ .../zip/ResourceAlignmentExtraField.java | 147 ++ .../archivers/zip/ScatterStatistics.java | 62 + .../archivers/zip/ScatterZipOutputStream.java | 184 ++ .../archivers/zip/StreamCompressor.java | 346 +++ .../zip/UnicodeCommentExtraField.java | 76 + .../archivers/zip/UnicodePathExtraField.java | 74 + .../compress/archivers/zip/UnixStat.java | 74 + .../zip/UnparseableExtraFieldBehavior.java | 56 + .../zip/UnparseableExtraFieldData.java | 127 ++ .../archivers/zip/UnrecognizedExtraField.java | 160 ++ .../zip/UnsupportedZipFeatureException.java | 141 ++ .../Zip64ExtendedInformationExtraField.java | 346 +++ .../compress/archivers/zip/Zip64Mode.java | 63 + .../archivers/zip/Zip64RequiredException.java | 67 + .../archivers/zip/ZipArchiveEntry.java | 1230 +++++++++++ .../zip/ZipArchiveEntryPredicate.java | 40 + .../archivers/zip/ZipArchiveEntryRequest.java | 87 + .../archivers/zip/ZipArchiveOutputStream.java | 1938 +++++++++++++++++ .../compress/archivers/zip/ZipConstants.java | 73 + .../archivers/zip/ZipEightByteInteger.java | 238 ++ .../compress/archivers/zip/ZipEncoding.java | 90 + .../archivers/zip/ZipEncodingHelper.java | 100 + .../compress/archivers/zip/ZipExtraField.java | 102 + .../compress/archivers/zip/ZipFile.java | 1418 ++++++++++++ .../compress/archivers/zip/ZipLong.java | 220 ++ .../compress/archivers/zip/ZipMethod.java | 230 ++ .../compress/archivers/zip/ZipShort.java | 167 ++ .../archivers/zip/ZipSplitOutputStream.java | 252 +++ .../ZipSplitReadOnlySeekableByteChannel.java | 149 ++ .../compress/archivers/zip/ZipUtil.java | 366 ++++ .../parallel/InputStreamSupplier.java | 40 + .../parallel/ScatterGatherBackingStore.java | 61 + .../ScatterGatherBackingStoreSupplier.java | 36 + .../utils/BoundedArchiveInputStream.java | 98 + .../compress/utils/BoundedInputStream.java | 96 + ...BoundedSeekableByteChannelInputStream.java | 59 + .../channel/compress/utils/ByteUtils.java | 269 +++ .../compress/utils/CountingInputStream.java | 82 + .../channel/compress/utils/FileNameUtils.java | 78 + .../channel/compress/utils/IOUtils.java | 356 +++ .../compress/utils/InputStreamStatistics.java | 38 + .../MultiReadOnlySeekableByteChannel.java | 239 ++ .../jvm/AsynchronousCloseException.java | 14 + .../util/archive/channel/jvm/ByteChannel.java | 13 + .../util/archive/channel/jvm/Channel.java | 39 + .../jvm/ClosedByInterruptException.java | 18 + .../channel/jvm/ClosedChannelException.java | 15 + .../jvm/NonReadableChannelException.java | 14 + .../jvm/NonWritableChannelException.java | 14 + .../channel/jvm/ReadableByteChannel.java | 48 + .../channel/jvm/SeekableByteChannel.java | 139 ++ .../channel/jvm/WritableByteChannel.java | 46 + .../r2/shared/util/io/CountingInputStream.kt | 7 +- .../shared/util/mediatype/SnifferContent.kt | 10 +- .../shared/util/mediatype/SnifferContext.kt | 2 +- .../r2/shared/util/archive/ArchiveTest.kt | 5 +- .../readium/r2/streamer/PublicationParser.kt | 34 - .../java/org/readium/r2/streamer/Streamer.kt | 75 +- .../container/PublicationContainer.kt | 52 - .../parser/FallbackContentProtection.kt | 4 +- .../r2/streamer/parser/PublicationParser.kt | 28 +- .../streamer/parser/audio/AudioBookParser.kt | 68 - .../r2/streamer/parser/audio/AudioParser.kt | 25 +- .../r2/streamer/parser/cbz/CBZParser.kt | 81 - .../r2/streamer/parser/divina/DiViNaParser.kt | 67 - .../r2/streamer/parser/epub/EpubParser.kt | 84 +- .../r2/streamer/parser/image/ImageParser.kt | 29 +- .../r2/streamer/parser/pdf/PdfParser.kt | 56 +- .../parser/readium/ReadiumWebPubParser.kt | 128 +- .../java/org/readium/r2/streamer/TestUtils.kt | 6 +- .../streamer/parser/image/ImageParserTest.kt | 44 +- test-app/build.gradle.kts | 1 - .../java/org/readium/r2/testapp/Readium.kt | 11 +- .../r2/testapp/bookshelf/BookRepository.kt | 133 +- .../r2/testapp/bookshelf/BookshelfAdapter.kt | 4 +- .../r2/testapp/bookshelf/BookshelfFragment.kt | 18 +- .../testapp/bookshelf/BookshelfViewModel.kt | 57 +- .../r2/testapp/catalogs/CatalogViewModel.kt | 2 +- .../readium/r2/testapp/domain/model/Book.kt | 36 +- .../r2/testapp/reader/ReaderRepository.kt | 12 +- test-app/src/main/res/values/arrays.xml | 4 +- test-app/src/main/res/values/strings.xml | 1 + 126 files changed, 13887 insertions(+), 926 deletions(-) create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDumbAuthentication.kt create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt delete mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/EPUBLicenseContainer.kt create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt delete mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/WebPubLicenseContainer.kt create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/URLHelper.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/BufferedReadableChannel.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/CachingReadableChannel.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZip.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/FileChannelAdapter.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveEntry.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveInputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveOutputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/EntryStreamOffsets.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/AbstractUnicodeExtraField.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/CharsetAccessor.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldParsingBehavior.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldUtils.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/GeneralPurposeBit.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/InflaterInputStreamWithStatistics.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/NioZipEncoding.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ResourceAlignmentExtraField.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterStatistics.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterZipOutputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/StreamCompressor.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodeCommentExtraField.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodePathExtraField.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnixStat.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldBehavior.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldData.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnrecognizedExtraField.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnsupportedZipFeatureException.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64ExtendedInformationExtraField.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64Mode.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64RequiredException.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntry.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryPredicate.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryRequest.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveOutputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipConstants.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEightByteInteger.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncoding.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncodingHelper.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipExtraField.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipFile.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipLong.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipMethod.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipShort.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitOutputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitReadOnlySeekableByteChannel.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipUtil.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/InputStreamSupplier.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStore.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStoreSupplier.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedArchiveInputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedInputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedSeekableByteChannelInputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/ByteUtils.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/CountingInputStream.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/FileNameUtils.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/IOUtils.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/InputStreamStatistics.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/MultiReadOnlySeekableByteChannel.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/AsynchronousCloseException.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ByteChannel.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/Channel.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedByInterruptException.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedChannelException.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonReadableChannelException.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonWritableChannelException.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ReadableByteChannel.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/SeekableByteChannel.java create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/WritableByteChannel.java delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/PublicationParser.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/container/PublicationContainer.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioBookParser.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/parser/cbz/CBZParser.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/parser/divina/DiViNaParser.kt diff --git a/docs/migration-guide.md b/docs/migration-guide.md index c8992f56be..843716eb76 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -29,6 +29,15 @@ dependencies { } ``` +### Publication assets + +In most cases, you no longer need to manually create a `PublicationAsset` to open a publication with +the streamer. You can use the overloaded open method taking a `Url` as argument instead. + +```kotlin +streamer.open(file.toUrl(), ...) +``` + ## 2.3.0 ### `Decoration.extras` diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt index 5bf5ff7595..3a416cec4b 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt @@ -7,12 +7,13 @@ package org.readium.r2.lcp import org.readium.r2.lcp.auth.LcpPassphraseAuthentication -import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.lcp.service.LcpLicensedAsset import org.readium.r2.shared.fetcher.TransformingFetcher import org.readium.r2.shared.publication.ContentProtection import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.asset.FileAsset import org.readium.r2.shared.publication.asset.PublicationAsset +import org.readium.r2.shared.publication.asset.RemoteAsset import org.readium.r2.shared.publication.services.contentProtectionServiceFactory import org.readium.r2.shared.util.Try @@ -23,31 +24,72 @@ internal class LcpContentProtection( override suspend fun open( asset: PublicationAsset, - fetcher: Fetcher, credentials: String?, allowUserInteraction: Boolean, sender: Any? ): Try? { - if (asset !is FileAsset) { - return null - } + val license = retrieveLicense(asset, credentials, allowUserInteraction, sender) + ?: return null + return createProtectedAsset(asset, license) + } - if (!lcpService.isLcpProtected(asset.file)) { - return null - } + /* Returns null if the publication is not protected by LCP. */ + private suspend fun retrieveLicense( + asset: PublicationAsset, + credentials: String?, + allowUserInteraction: Boolean, + sender: Any? + ): Try? { - val authentication = credentials?.let { LcpPassphraseAuthentication(it, fallback = this.authentication) } + val authentication = credentials + ?.let { LcpPassphraseAuthentication(it, fallback = this.authentication) } ?: this.authentication - val license = lcpService - .retrieveLicense(asset.file, authentication, allowUserInteraction, sender) + val license = when (asset) { + is FileAsset -> + lcpService.retrieveLicense(asset.file, authentication, allowUserInteraction, sender) + is RemoteAsset -> + lcpService.retrieveLicense(asset.fetcher, asset.mediaType, authentication, allowUserInteraction, sender) + is LcpLicensedAsset -> + asset.license + ?.let { Try.success(it) } + ?: lcpService.retrieveLicense(asset.licenseFile, authentication, allowUserInteraction, sender) + else -> + null + } + + return license?.takeUnless { result -> + result is Try.Failure<*, *> && result.exception is LcpException.Container + } + } + private fun createProtectedAsset( + originalAsset: PublicationAsset, + license: Try, + ): Try { val serviceFactory = LcpContentProtectionService - .createFactory(license?.getOrNull(), license?.exceptionOrNull()) + .createFactory(license.getOrNull(), license.exceptionOrNull()) + + val newFetcher = TransformingFetcher( + originalAsset.fetcher, + LcpDecryptor(license.getOrNull())::transform + ) + + val newAsset = when (originalAsset) { + is FileAsset -> { + originalAsset.copy(fetcher = newFetcher) + } + is RemoteAsset -> { + originalAsset.copy(fetcher = newFetcher) + } + is LcpLicensedAsset -> { + originalAsset.copy(fetcher = newFetcher) + } + else -> throw IllegalStateException() + } val protectedFile = ContentProtection.ProtectedAsset( - asset = asset, - fetcher = TransformingFetcher(fetcher, LcpDecryptor(license?.getOrNull())::transform), + asset = newAsset, onCreatePublication = { servicesBuilder.contentProtectionServiceFactory = serviceFactory } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt index 6aff0c21cd..bb7a5e7b77 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt @@ -69,7 +69,23 @@ internal class LcpDecryptor(val license: LcpLicense?) { private val license: LcpLicense ) : Resource { - lateinit var _length: ResourceTry + private class Cache( + var startIndex: Int? = null, + val data: ByteArray = ByteArray(3 * AES_BLOCK_SIZE) + ) + + private lateinit var _length: ResourceTry + + /* + * Decryption needs to look around the data strictly matching the content to decipher. + * That means that in case of contiguous read requests, data fetched from the underlying + * resource are not contiguous. Every request to the underlying resource starts slightly + * before the end of the previous one. This is an issue with remote publications because + * you have to make a new HTTP request every time instead of reusing the previous one. + * To alleviate this, we cache the three last bytes read in each call and reuse them + * in the next call if possible. + */ + private val _cache: Cache = Cache() override suspend fun link(): Link = resource.link() @@ -78,7 +94,15 @@ internal class LcpDecryptor(val license: LcpLicense?) { if (::_length.isInitialized) return _length - _length = resource.length().flatMapCatching { length -> + _length = resource.link().properties.encryption?.originalLength + ?.let { Try.success(it) } + ?: lengthFromPadding() + + return _length + } + + private suspend fun lengthFromPadding(): ResourceTry = + resource.length().flatMapCatching { length -> if (length < 2 * AES_BLOCK_SIZE) { throw Exception("Invalid CBC-encrypted stream") } @@ -96,9 +120,6 @@ internal class LcpDecryptor(val license: LcpLicense?) { } } - return _length - } - override suspend fun read(range: LongRange?): ResourceTry { if (range == null) return license.decryptFully(resource.read(), isDeflated = false) @@ -112,13 +133,19 @@ internal class LcpDecryptor(val license: LcpLicense?) { return Try.success(ByteArray(0)) return resource.length().flatMapCatching { encryptedLength -> - // encrypted data is shifted by AES_BLOCK_SIZE because of IV and // the previous block must be provided to perform XOR on intermediate blocks val encryptedStart = range.first.floorMultipleOf(AES_BLOCK_SIZE.toLong()) val encryptedEndExclusive = (range.last + 1).ceilMultipleOf(AES_BLOCK_SIZE.toLong()) + AES_BLOCK_SIZE - resource.read(encryptedStart until encryptedEndExclusive).mapCatching { encryptedData -> + getEncryptedData(encryptedStart until encryptedEndExclusive).mapCatching { encryptedData -> + if (encryptedData.size >= _cache.data.size) { + // cache the three last encrypted blocks that have been read for future use + val cacheStart = encryptedData.size - _cache.data.size + _cache.startIndex = (encryptedEndExclusive - _cache.data.size).toInt() + encryptedData.copyInto(_cache.data, 0, cacheStart) + } + val bytes = license.decrypt(encryptedData) .getOrElse { throw IOException("Can't decrypt the content at: ${link().href}", it) } @@ -144,6 +171,22 @@ internal class LcpDecryptor(val license: LcpLicense?) { } } + private suspend fun getEncryptedData(range: LongRange): ResourceTry { + val cacheStartIndex = _cache.startIndex + ?.takeIf { cacheStart -> + val cacheEnd = cacheStart + _cache.data.size + cacheStart <= range.first && cacheEnd <= range.last + 1 + } ?: return resource.read(range) + + return resource.read(range.first + _cache.data.size..range.last).map { + val bytes = ByteArray(range.last.toInt() - range.first.toInt() + 1) + val offsetInCache = (range.first - cacheStartIndex).toInt() + _cache.data.copyInto(bytes, 0, offsetInCache) + it.copyInto(bytes, _cache.data.size) + bytes + } + } + override suspend fun close() = resource.close() companion object { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt index 1c099f16b7..8b27d1c559 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt @@ -23,8 +23,15 @@ import org.readium.r2.lcp.service.LicensesService import org.readium.r2.lcp.service.NetworkService import org.readium.r2.lcp.service.PassphrasesRepository import org.readium.r2.lcp.service.PassphrasesService +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.ContentProtection +import org.readium.r2.shared.publication.asset.PublicationAsset import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.archive.ArchiveFactory +import org.readium.r2.shared.util.archive.DefaultArchiveFactory +import org.readium.r2.shared.util.http.DefaultHttpClient +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.mediatype.MediaType /** * Service used to acquire and open publications protected with LCP. @@ -76,7 +83,28 @@ interface LcpService { authentication: LcpAuthenticating = LcpDialogAuthentication(), allowUserInteraction: Boolean, sender: Any? = null - ): Try? + ): Try + + /** + * Opens the LCP license of a protected publication, to access its DRM metadata and decipher + * its content. As the updated license cannot be stored through a [Fetcher], + * you'll get an exception if the license points to a LSD server that cannot be reached, + * for instance because no Internet gateway is available. + * + * @param authentication Used to retrieve the user passphrase if it is not already known. + * The request will be cancelled if no passphrase is found in the LCP passphrase storage + * and the provided [authentication]. + * @param allowUserInteraction Indicates whether the user can be prompted for their passphrase. + * @param sender Free object that can be used by reading apps to give some UX context when + * presenting dialogs with [LcpAuthenticating]. + */ + suspend fun retrieveLicense( + fetcher: Fetcher, + mediaType: MediaType, + authentication: LcpAuthenticating = LcpDialogAuthentication(), + allowUserInteraction: Boolean, + sender: Any? = null + ): Try /** * Creates a [ContentProtection] instance which can be used with a Streamer to unlock @@ -89,6 +117,11 @@ interface LcpService { fun contentProtection(authentication: LcpAuthenticating = LcpDialogAuthentication()): ContentProtection = LcpContentProtection(this, authentication) + /** + * Builds a [PublicationAsset] to open a LCP-protected publication from its license file. + */ + suspend fun remoteAssetForLicense(license: File): Try + /** * Information about an acquired publication protected with LCP. * @@ -110,7 +143,11 @@ interface LcpService { /** * LCP service factory. */ - operator fun invoke(context: Context): LcpService? { + operator fun invoke( + context: Context, + archiveFactory: ArchiveFactory = DefaultArchiveFactory(), + httpClient: HttpClient = DefaultHttpClient() + ): LcpService? { if (!LcpClient.isAvailable()) return null @@ -122,7 +159,16 @@ interface LcpService { val device = DeviceService(repository = deviceRepository, network = network, context = context) val crl = CRLService(network = network, context = context) val passphrases = PassphrasesService(repository = passphraseRepository) - return LicensesService(licenses = licenseRepository, crl = crl, device = device, network = network, passphrases = passphrases, context = context) + return LicensesService( + licenses = licenseRepository, + crl = crl, + device = device, + network = network, + passphrases = passphrases, + context = context, + archiveFactory = archiveFactory, + httpClient = httpClient + ) } @Deprecated("Use `LcpService()` instead", ReplaceWith("LcpService(context)"), level = DeprecationLevel.ERROR) @@ -151,7 +197,13 @@ interface LcpService { completion: (LcpLicense?, LcpException?) -> Unit ) { GlobalScope.launch { - val result = retrieveLicense(File(publication), authentication ?: LcpDialogAuthentication(), allowUserInteraction = true) + val result = + try { + retrieveLicense(File(publication), authentication ?: LcpDialogAuthentication(), allowUserInteraction = true) + } catch (e: CancellationException) { + null + } + if (result == null) { completion(null, null) } else { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDumbAuthentication.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDumbAuthentication.kt new file mode 100644 index 0000000000..81d8ccd5b2 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDumbAuthentication.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.auth + +import org.readium.r2.lcp.LcpAuthenticating + +internal class LcpDumbAuthentication : LcpAuthenticating { + + override suspend fun retrievePassphrase( + license: LcpAuthenticating.AuthenticatedLicense, + reason: LcpAuthenticating.AuthenticationReason, + allowUserInteraction: Boolean, + sender: Any? + ): String? = null +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt index a918497a76..1c539beef2 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt @@ -11,7 +11,6 @@ package org.readium.r2.lcp.license import java.util.* import kotlin.time.Duration.Companion.seconds -import kotlin.time.ExperimentalTime import kotlinx.coroutines.runBlocking import org.readium.r2.lcp.BuildConfig.DEBUG import org.readium.r2.lcp.LcpAuthenticating @@ -61,7 +60,11 @@ internal sealed class State { data class fetchStatus(val license: LicenseDocument) : State() data class validateStatus(val license: LicenseDocument, val data: ByteArray) : State() data class fetchLicense(val license: LicenseDocument, val status: StatusDocument) : State() - data class checkLicenseStatus(val license: LicenseDocument, val status: StatusDocument?) : State() + data class checkLicenseStatus( + val license: LicenseDocument, + val status: StatusDocument?, + val statusDocumentTakesPrecedence: Boolean + ) : State() data class retrievePassphrase(val license: LicenseDocument, val status: StatusDocument?) : State() data class validateIntegrity( val license: LicenseDocument, @@ -87,10 +90,14 @@ internal sealed class Event { object cancelled : Event() } -@OptIn(ExperimentalTime::class) +/** + * If [ignoreInternetErrors] is true, then the validation won't fail on [LcpException.Network] errors. + * This should be the case with writable licenses (such as local ones) but not with read-only licences. + */ internal class LicenseValidation( var authentication: LcpAuthenticating?, val allowUserInteraction: Boolean, + val ignoreInternetErrors: Boolean, val sender: Any?, val crl: CRLService, val device: DeviceService, @@ -142,7 +149,7 @@ internal class LicenseValidation( on { status?.let { status -> if (DEBUG) Timber.d("State.checkLicenseStatus(it.license, status)") - transitionTo(State.checkLicenseStatus(it.license, status)) + transitionTo(State.checkLicenseStatus(it.license, status, false)) } ?: run { if (DEBUG) Timber.d("State.fetchStatus(it.license)") transitionTo(State.fetchStatus(it.license)) @@ -159,8 +166,13 @@ internal class LicenseValidation( transitionTo(State.validateStatus(license, it.data)) } on { - if (DEBUG) Timber.d("State.checkLicenseStatus(license, null)") - transitionTo(State.checkLicenseStatus(license, null)) + if (!ignoreInternetErrors && it.error is LcpException.Network) { + if (DEBUG) Timber.d("State.failure(it.error)") + transitionTo(State.failure(it.error)) + } else { + if (DEBUG) Timber.d("State.checkLicenseStatus(license, null)") + transitionTo(State.checkLicenseStatus(license, null, false)) + } } } state { @@ -170,12 +182,12 @@ internal class LicenseValidation( transitionTo(State.fetchLicense(license, it.status)) } else { if (DEBUG) Timber.d("State.checkLicenseStatus(license, it.status)") - transitionTo(State.checkLicenseStatus(license, it.status)) + transitionTo(State.checkLicenseStatus(license, it.status, false)) } } on { if (DEBUG) Timber.d("State.checkLicenseStatus(license, null)") - transitionTo(State.checkLicenseStatus(license, null)) + transitionTo(State.checkLicenseStatus(license, null, false)) } } state { @@ -185,7 +197,7 @@ internal class LicenseValidation( } on { if (DEBUG) Timber.d("State.checkLicenseStatus(license, status)") - transitionTo(State.checkLicenseStatus(license, status)) + transitionTo(State.checkLicenseStatus(license, status, true)) } } state { @@ -280,7 +292,7 @@ internal class LicenseValidation( is State.fetchStatus -> fetchStatus(state.license) is State.validateStatus -> validateStatus(state.data) is State.fetchLicense -> fetchLicense(state.status) - is State.checkLicenseStatus -> checkLicenseStatus(state.license, state.status) + is State.checkLicenseStatus -> checkLicenseStatus(state.license, state.status, state.statusDocumentTakesPrecedence) is State.retrievePassphrase -> requestPassphrase(state.license) is State.validateIntegrity -> validateIntegrity(state.license, state.passphrase) is State.registerDevice -> registerDevice(state.documents.license, state.link) @@ -321,8 +333,9 @@ internal class LicenseValidation( private suspend fun fetchStatus(license: LicenseDocument) { val url = license.url(LicenseDocument.Rel.status, preferredType = MediaType.LCP_STATUS_DOCUMENT).toString() - // Short timeout to avoid blocking the License, since the LSD is optional. - val data = network.fetch(url, timeout = 5.seconds, headers = mapOf("Accept" to MediaType.LCP_STATUS_DOCUMENT.toString())) + // Short timeout to avoid blocking the License, when the LSD is optional. + val timeout = 5.seconds.takeIf { ignoreInternetErrors } + val data = network.fetch(url, timeout = timeout, headers = mapOf("Accept" to MediaType.LCP_STATUS_DOCUMENT.toString())) .getOrElse { throw LcpException.Network(it) } raise(Event.retrievedStatusData(data)) @@ -342,12 +355,22 @@ internal class LicenseValidation( raise(Event.retrievedLicenseData(data)) } - private fun checkLicenseStatus(license: LicenseDocument, status: StatusDocument?) { + private fun checkLicenseStatus( + license: LicenseDocument, + status: StatusDocument?, + statusDocumentTakesPrecedence: Boolean + ) { var error: LcpException.LicenseStatus? = null val now = Date() val start = license.rights.start ?: now val end = license.rights.end ?: now - if (start > now || now > end) { + val isLicenseExpired = (start > now || now > end) + val isStatusValid = status?.status in listOf(null, StatusDocument.Status.active, StatusDocument.Status.ready) + + // We only check the Status Document's status if the License itself is expired, to get a proper status error message. + // But in the case where the Status Document takes precedence (eg. after a failed License update), + // then we also check the status validity. + if (isLicenseExpired || statusDocumentTakesPrecedence && !isStatusValid) { error = if (status != null) { val date = status.statusUpdated when (status.status) { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt new file mode 100644 index 0000000000..b26ffce22a --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.license.container + +import kotlinx.coroutines.runBlocking +import org.readium.r2.lcp.LcpException +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.util.archive.Archive + +/** + * Access to a License Document stored in a read-only ZIP archive. + */ +internal class ArchiveLicenseContainer( + private val archive: Archive, + private val entryPath: String, +) : LicenseContainer { + + override fun read(): ByteArray { + val entry = try { + runBlocking { archive.entry(entryPath) } + } catch (e: Exception) { + throw LcpException.Container.FileNotFound(entryPath) + } + + return try { + runBlocking { entry.read() } + } catch (e: Exception) { + throw LcpException.Container.ReadFailed(entryPath) + } + } + + override fun write(license: LicenseDocument) { + throw LcpException.Container.WriteFailed(entryPath) + } +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/EPUBLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/EPUBLicenseContainer.kt deleted file mode 100644 index c44bc7a0f2..0000000000 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/EPUBLicenseContainer.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Module: r2-lcp-kotlin - * Developers: Aferdita Muriqi, Mickaël Menu - * - * Copyright (c) 2019. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.lcp.license.container - -/** - * Access a License Document stored in an EPUB archive, under META-INF/license.lcpl. - */ -internal class EPUBLicenseContainer(epub: String) : - ZIPLicenseContainer(zip = epub, pathInZIP = "META-INF/license.lcpl") diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt new file mode 100644 index 0000000000..ed15736b71 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.license.container + +import kotlinx.coroutines.runBlocking +import org.readium.r2.lcp.LcpException +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.util.use + +/** + * Access to a License Document stored in a [Fetcher]. + */ +internal class FetcherLicenseContainer( + private val fetcher: Fetcher, + private val entryPath: String, +) : LicenseContainer { + + override fun read(): ByteArray = + runBlocking { + fetcher.get(entryPath).use { resource -> + resource.read() + .mapFailure { it.toLcpException() } + .getOrThrow() + } + } + + private fun Resource.Exception.toLcpException() = + when (this) { + is Resource.Exception.NotFound -> LcpException.Container.FileNotFound(entryPath) + else -> LcpException.Container.ReadFailed(entryPath) + } + + override fun write(license: LicenseDocument) { + throw LcpException.Container.WriteFailed(entryPath) + } +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt index b5dd5590aa..0c36e9cb0e 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt @@ -6,6 +6,7 @@ * Use of this source code is governed by a BSD-style license which is detailed in the * LICENSE file present in the project repository where this source code is maintained. */ + package org.readium.r2.lcp.license.container import java.io.File diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt index c65cc3c04d..b07b00df1c 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt @@ -11,8 +11,14 @@ package org.readium.r2.lcp.license.container import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.extensions.addPrefix +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.util.mediatype.MediaType +private const val LICENSE_IN_EPUB = "META-INF/license.lcpl" + +private const val LICENSE_IN_RPF = "license.lcpl" + /** * Encapsulates the read/write access to the packaged License Document (eg. in an EPUB container, * or a standalone LCPL file). @@ -31,10 +37,25 @@ internal suspend fun createLicenseContainer( return createLicenseContainer(filepath, mediaType) } -internal fun createLicenseContainer(filepath: String, mediaType: MediaType): LicenseContainer = +internal fun createLicenseContainer( + filepath: String, + mediaType: MediaType +): LicenseContainer = when (mediaType) { - MediaType.EPUB -> EPUBLicenseContainer(filepath) + MediaType.EPUB -> ZIPLicenseContainer(filepath, LICENSE_IN_EPUB) MediaType.LCP_LICENSE_DOCUMENT -> LCPLLicenseContainer(filepath) // Assuming it's a Readium WebPub package (e.g. audiobook, LCPDF, etc.) as a fallback - else -> WebPubLicenseContainer(filepath) + else -> ZIPLicenseContainer(filepath, LICENSE_IN_RPF) + } + +internal fun createLicenseContainer( + fetcher: Fetcher, + mediaType: MediaType, +): LicenseContainer { + val licensePath = when (mediaType) { + MediaType.EPUB -> LICENSE_IN_EPUB.addPrefix("/") + // Assuming it's a Readium WebPub package (e.g. audiobook, LCPDF, etc.) as a fallback + else -> LICENSE_IN_RPF.addPrefix("/") } + return FetcherLicenseContainer(fetcher, licensePath) +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/WebPubLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/WebPubLicenseContainer.kt deleted file mode 100644 index c7033c224c..0000000000 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/WebPubLicenseContainer.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Module: r2-lcp-kotlin - * Developers: Mickaël Menu - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.lcp.license.container - -/** - * Access a License Document stored in a Readium WebPub package (e.g. WebPub, Audiobook, LCPDF or DiViNa). - */ -internal class WebPubLicenseContainer(path: String) : - ZIPLicenseContainer(zip = path, pathInZIP = "license.lcpl") diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt index a3115aa5f8..5405bb3cc8 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt @@ -17,9 +17,11 @@ import org.zeroturnaround.zip.ZipUtil /** * Access to a License Document stored in a ZIP archive. - * Meant to be subclassed to customize the pathInZIP property, eg. [EPUBLicenseContainer]. */ -internal open class ZIPLicenseContainer(private val zip: String, private val pathInZIP: String) : LicenseContainer { +internal class ZIPLicenseContainer( + private val zip: String, + private val pathInZIP: String, +) : LicenseContainer { override fun read(): ByteArray { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt new file mode 100644 index 0000000000..0123186cf6 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.service + +import java.io.File +import org.readium.r2.lcp.LcpLicense +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.publication.asset.PublicationAsset +import org.readium.r2.shared.util.mediatype.MediaType + +data class LcpLicensedAsset( + override val name: String, + override val mediaType: MediaType, + override val fetcher: Fetcher, + val licenseFile: File, + val license: LcpLicense? +) : PublicationAsset diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index 5bf9cd5dce..b42fcf95a3 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -17,13 +17,20 @@ import org.readium.r2.lcp.LcpAuthenticating import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.LcpLicense import org.readium.r2.lcp.LcpService +import org.readium.r2.lcp.auth.LcpDumbAuthentication import org.readium.r2.lcp.license.License import org.readium.r2.lcp.license.LicenseValidation import org.readium.r2.lcp.license.container.LicenseContainer import org.readium.r2.lcp.license.container.createLicenseContainer import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.extensions.tryOr +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.publication.asset.PublicationAsset +import org.readium.r2.shared.publication.asset.RemoteAsset import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.archive.ArchiveFactory +import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber @@ -33,7 +40,9 @@ internal class LicensesService( private val device: DeviceService, private val network: NetworkService, private val passphrases: PassphrasesService, - private val context: Context + private val context: Context, + private val archiveFactory: ArchiveFactory, + private val httpClient: HttpClient ) : LcpService, CoroutineScope by MainScope() { override suspend fun isLcpProtected(file: File): Boolean = @@ -42,6 +51,41 @@ internal class LicensesService( true } + override suspend fun remoteAssetForLicense(license: File): Try { + return try { + Try.success(remoteAssetForLicenseThrowing(license)) + } catch (e: Exception) { + Try.failure(LcpException.wrap(e)) + } + } + + private suspend fun remoteAssetForLicenseThrowing(licenseFile: File): PublicationAsset { + // Update the license file to get a fresh publication URL. + val license = retrieveLicense(licenseFile, LcpDumbAuthentication(), false) + .getOrNull() + + val licenseDoc = license?.license + ?: LicenseDocument(licenseFile.readBytes()) + + val link = checkNotNull(licenseDoc.link(LicenseDocument.Rel.publication)) + val url = try { + Url(link.url.toString()) ?: throw IllegalStateException() + } catch (e: Exception) { + throw LcpException.Parsing.Url(rel = LicenseDocument.Rel.publication.rawValue) + } + val baseAsset = RemoteAsset.Factory(archiveFactory, httpClient) + .createAsset(url, link.mediaType) + .getOrThrow() + + return LcpLicensedAsset( + baseAsset.name, + baseAsset.mediaType, + baseAsset.fetcher, + licenseFile, + license + ) + } + override suspend fun acquirePublication(lcpl: ByteArray, onProgress: (Double) -> Unit): Try = try { val licenseDocument = LicenseDocument(lcpl) @@ -56,29 +100,70 @@ internal class LicensesService( authentication: LcpAuthenticating, allowUserInteraction: Boolean, sender: Any? - ): Try? = + ): Try = try { val container = createLicenseContainer(file.path) - // WARNING: Using the Default dispatcher in the state machine code is critical. If we were using the Main Dispatcher, - // calling runBlocking in LicenseValidation.handle would block the main thread and cause a severe issue - // with LcpAuthenticating.retrievePassphrase. Specifically, the interaction of runBlocking and suspendCoroutine - // blocks the current thread before the passphrase popup has been showed until some button not yet showed is clicked. - val license = withContext(Dispatchers.Default) { retrieveLicense(container, authentication, allowUserInteraction, sender) } - Timber.d("license retrieved ${license?.license}") - - license?.let { Try.success(it) } + val license = retrieveLicense(container, authentication, allowUserInteraction, true, sender) + Try.success(license) + } catch (e: Exception) { + Try.failure(LcpException.wrap(e)) + } + + override suspend fun retrieveLicense( + fetcher: Fetcher, + mediaType: MediaType, + authentication: LcpAuthenticating, + allowUserInteraction: Boolean, + sender: Any? + ): Try = + try { + val container = createLicenseContainer(fetcher, mediaType) + val license = retrieveLicense(container, authentication, allowUserInteraction, false, sender) + Try.success(license) } catch (e: Exception) { Try.failure(LcpException.wrap(e)) } private suspend fun retrieveLicense( + container: LicenseContainer, + authentication: LcpAuthenticating, + allowUserInteraction: Boolean, + ignoreInternetErrors: Boolean, + sender: Any? + ): LcpLicense { + // WARNING: Using the Default dispatcher in the state machine code is critical. If we were using the Main Dispatcher, + // calling runBlocking in LicenseValidation.handle would block the main thread and cause a severe issue + // with LcpAuthenticating.retrievePassphrase. Specifically, the interaction of runBlocking and suspendCoroutine + // blocks the current thread before the passphrase popup has been showed until some button not yet showed is clicked. + val license = withContext(Dispatchers.Default) { + retrieveLicenseUnsafe( + container, + authentication, + allowUserInteraction, + ignoreInternetErrors, + sender + ) + } + Timber.d("license retrieved ${license.license}") + + return license + } + + private suspend fun retrieveLicenseUnsafe( container: LicenseContainer, authentication: LcpAuthenticating?, allowUserInteraction: Boolean, + ignoreInternetErrors: Boolean, sender: Any? - ): License? = + ): License = suspendCancellableCoroutine { cont -> - retrieveLicense(container, authentication, allowUserInteraction, sender) { license -> + retrieveLicense( + container, + authentication, + allowUserInteraction, + ignoreInternetErrors, + sender + ) { license -> if (cont.isActive) { cont.resume(license) } @@ -89,8 +174,9 @@ internal class LicensesService( container: LicenseContainer, authentication: LcpAuthenticating?, allowUserInteraction: Boolean, + ignoreInternetErrors: Boolean, sender: Any?, - completion: (License?) -> Unit + completion: (License) -> Unit ) { var initialData = container.read() @@ -99,7 +185,8 @@ internal class LicensesService( val validation = LicenseValidation( authentication = authentication, crl = this.crl, device = this.device, network = this.network, passphrases = this.passphrases, context = this.context, - allowUserInteraction = allowUserInteraction, sender = sender + allowUserInteraction = allowUserInteraction, ignoreInternetErrors = ignoreInternetErrors, + sender = sender ) { licenseDocument -> try { launch { @@ -134,8 +221,9 @@ internal class LicensesService( } error?.let { throw error } - if (documents == null && error == null) { - completion(null) + // Both error and documents can be null if the user cancelled the passphrase prompt. + if (documents == null) { + throw CancellationException("License validation was interrupted.") } } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/URLHelper.kt b/readium/shared/src/main/java/org/readium/r2/shared/URLHelper.kt deleted file mode 100644 index f3b429512f..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/URLHelper.kt +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Aferdita Muriqi, Clément Baumann - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt index e25f5a091e..30d1c9dd13 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt @@ -16,6 +16,7 @@ package org.readium.r2.shared.extensions import java.io.ByteArrayOutputStream import java.io.InputStream import java.io.OutputStream +import java.util.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -79,3 +80,17 @@ internal suspend fun InputStream.readFully(): ByteArray = withContext(Dispatchers.IO) { readBytes() } + +internal fun InputStream.readSafe(b: ByteArray): Int = + readSafe(b, 0, b.size) + +internal fun InputStream.readSafe(b: ByteArray, off: Int, len: Int): Int { + Objects.checkFromIndexSize(off, len, b.size) + var n = 0 + while (n < len) { + val count = read(b, off + n, len - n) + if (count < 0) break + n += count + } + return n +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt index 86aa9e1d11..cbf4991165 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt @@ -18,6 +18,7 @@ import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Properties import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.archive.Archive import org.readium.r2.shared.util.archive.ArchiveFactory import org.readium.r2.shared.util.archive.DefaultArchiveFactory @@ -48,6 +49,11 @@ class ArchiveFetcher private constructor(private val archive: Archive) : Fetcher withContext(Dispatchers.IO) { tryOrNull { ArchiveFetcher(archiveFactory.open(File(path), password = null)) } } + + suspend fun fromUrl(url: Url, archiveFactory: ArchiveFactory = DefaultArchiveFactory()): ArchiveFetcher? = + withContext(Dispatchers.IO) { + tryOrNull { ArchiveFetcher(archiveFactory.open(url, password = null)) } + } } private class EntryResource(val originalLink: Link, val archive: Archive) : Resource { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt index 69afb00589..8dce558b5b 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt @@ -32,13 +32,15 @@ import timber.log.Timber * * @param client HTTP client used to perform HTTP requests. * @param baseUrl Base URL from which relative HREF are served. + * @param links A set of links that are known to be available through this fetcher. */ class HttpFetcher( private val client: HttpClient, private val baseUrl: String? = null, + private val links: List = emptyList(), ) : Fetcher { - override suspend fun links(): List = emptyList() + override suspend fun links(): List = links override fun get(link: Link): Resource { val url = link.toUrl(baseUrl) @@ -48,7 +50,7 @@ class HttpFetcher( Timber.e(cause) FailureResource(link, error = Resource.Exception.BadRequest(cause = cause)) } else { - HttpResource(client, link, url) + HttpResource(client, link, url, MAX_SKIP_BYTES) } } @@ -59,6 +61,7 @@ class HttpFetcher( private val client: HttpClient, private val link: Link, private val url: String, + private val maxSkipBytes: Long ) : Resource { override suspend fun link(): Link = @@ -111,19 +114,18 @@ class HttpFetcher( /** * Returns an HTTP stream for the resource, starting at the [from] byte offset. * - * The stream is cached and reused for next calls, if the next [from] offset is in a forward - * direction. + * The stream is cached and reused for next calls, if the next [from] offset is not too far + * and in a forward direction. */ private suspend fun stream(from: Long? = null): ResourceTry { val stream = inputStream if (from != null && stream != null) { - // TODO Figure out a better way to handle this Kotlin warning - tryOrLog { + tryOrLog { val bytesToSkip = from - (inputStreamStart + stream.count) - if (bytesToSkip >= 0) { + if (bytesToSkip in 0 until maxSkipBytes) { stream.skip(bytesToSkip) + return Try.success(stream) } - return Try.success(stream) } } tryOrLog { inputStream?.close() } @@ -160,4 +162,9 @@ class HttpFetcher( Resource.Exception.Other(e) } } + + companion object { + + private const val MAX_SKIP_BYTES: Long = 8192 + } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentProtection.kt index 7218d32842..10347eadb8 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentProtection.kt @@ -29,21 +29,12 @@ interface ContentProtection { /** * Attempts to unlock a potentially protected publication asset. * - * The Streamer will create a leaf [fetcher] for the low-level [asset] access (e.g. - * ArchiveFetcher for a ZIP archive), to avoid having each Content Protection open the asset to - * check if it's protected or not. - * - * A publication might be protected in such a way that the package format can't be recognized, - * in which case the Content Protection will have the responsibility of creating a new leaf - * [Fetcher]. - * * @return A [ProtectedAsset] in case of success, null if the asset is not protected by this * technology or a [Publication.OpeningException] if the asset can't be successfully opened, * even in restricted mode. */ suspend fun open( asset: PublicationAsset, - fetcher: Fetcher, credentials: String?, allowUserInteraction: Boolean, sender: Any? @@ -53,29 +44,19 @@ interface ContentProtection { * Holds the result of opening a [PublicationAsset] with a [ContentProtection]. * * @property asset Protected asset which will be provided to the parsers. - * In most cases, this will be the asset provided to ContentProtection::open(), - * but a Content Protection might modify it in some cases: + * It is likely to be different from the asset provided to ContentProtection::open(): + * - If the original fetcher is wrapped into a new fetcher able to decipher content. * - If the original asset has a media type that can't be recognized by parsers, * the Content Protection must return an asset with the matching unprotected media type. * - If the Content Protection technology needs to redirect the Streamer to a different file. * For example, this could be used to decrypt a publication to a temporary secure location. * - * @property fetcher Primary leaf fetcher to be used by parsers. - * The Content Protection can unlock resources by modifying the Fetcher provided to - * ContentProtection::open(), for example by: - * - Wrapping the given fetcher in a TransformingFetcher with a decryption Resource.Transformer - * function. - * - Discarding the provided fetcher altogether and creating a new one to handle access - * restrictions. For example, by creating an HTTPFetcher which will inject a Bearer Token in - * requests. - * * @property onCreatePublication Called on every parsed Publication.Builder. * It can be used to modify the `Manifest`, the root [Fetcher] or the list of service factories * of a [Publication]. */ data class ProtectedAsset( val asset: PublicationAsset, - val fetcher: Fetcher, val onCreatePublication: Publication.Builder.() -> Unit = {} ) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt new file mode 100644 index 0000000000..42b4c8255f --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.asset + +import java.io.File +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.archive.ArchiveFactory +import org.readium.r2.shared.util.archive.DefaultArchiveFactory +import org.readium.r2.shared.util.http.DefaultHttpClient +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * A factory for various [PublicationAsset]s. + * + * Supported protocols are file, http and https. + */ +class DefaultPublicationAssetFactory( + val archiveFactory: ArchiveFactory = DefaultArchiveFactory(), + val httpClient: HttpClient = DefaultHttpClient() +) : PublicationAssetFactory { + + private val fileAssetFactory: FileAsset.Factory = + FileAsset.Factory(archiveFactory, httpClient) + + private val remoteAssetFactory: RemoteAsset.Factory = + RemoteAsset.Factory(archiveFactory, httpClient) + + /** + * Creates an asset for a publication available at [url]. + * + * @param url the url at which the publication is available + * @param mediaType the publication media type + */ + override suspend fun createAsset( + url: Url, + mediaType: MediaType, + ): Try { + return when (url.protocol) { + "file" -> fileAssetFactory.createAsset(File(url.path), mediaType) + "http", "https" -> remoteAssetFactory.createAsset(url, mediaType) + else -> throw IllegalArgumentException("Protocol not supported.") + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt index df0a04c784..4688b91220 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt @@ -8,73 +8,83 @@ package org.readium.r2.shared.publication.asset import java.io.File import java.io.FileNotFoundException -import org.readium.r2.shared.fetcher.ArchiveFetcher -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.FileFetcher +import java.nio.charset.Charset +import org.json.JSONObject +import org.readium.r2.shared.fetcher.* +import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.archive.ArchiveFactory +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.mediatype.MediaType /** - * Represents a publication stored as a file on the local file system. - * - * @param file File on the file system. + * A [PublicationAsset] built from a [File]. */ -class FileAsset private constructor( +data class FileAsset( val file: File, - private val knownMediaType: MediaType?, - private val mediaTypeHint: String? + override val mediaType: MediaType, + override val fetcher: Fetcher ) : PublicationAsset { - /** - * Creates a [FileAsset] from a [File] and an optional media type, when known. - */ - constructor(file: File, mediaType: MediaType? = null) : - this(file, knownMediaType = mediaType, mediaTypeHint = null) + override val name: String = + file.name - /** - * Creates a [FileAsset] from a [File] and an optional media type hint. - * - * Providing a media type hint will improve performances when sniffing the media type. - */ - constructor(file: File, mediaTypeHint: String?) : - this(file, knownMediaType = null, mediaTypeHint = mediaTypeHint) + internal class Factory( + private val archiveFactory: ArchiveFactory, + private val httpClient: HttpClient + ) { - override val name: String - get() = file.name + suspend fun createAsset( + file: File, + mediaType: MediaType + ): Try = + createFetcher(file, mediaType) + .map { fetcher -> FileAsset(file, mediaType, fetcher) } - override suspend fun mediaType(): MediaType { - if (!::_mediaType.isInitialized) { - _mediaType = knownMediaType - ?: MediaType.ofFile(file, mediaType = mediaTypeHint) - ?: MediaType.BINARY + private suspend fun createFetcher(file: File, mediaType: MediaType): Try { + return try { + when { + file.isDirectory -> Try.success(FileFetcher(href = "/", file = file)) + file.exists() -> createFetcherForFile(file, mediaType) + else -> throw FileNotFoundException(file.path) + } + } catch (e: SecurityException) { + Try.failure(Publication.OpeningException.Forbidden(e)) + } catch (e: FileNotFoundException) { + Try.failure(Publication.OpeningException.NotFound(e)) + } } - return _mediaType - } + private suspend fun createFetcherForFile(file: File, mediaType: MediaType): Try { + ArchiveFetcher.fromPath(file.path, archiveFactory) + ?.let { return Try.success(it) } - private lateinit var _mediaType: MediaType + if (mediaType.isRwpm) { + val manifest = file.readAsRwpm(packaged = false) + .mapFailure { Publication.OpeningException.ParsingFailed(it) } + .getOrElse { return Try.failure(it) } - override suspend fun createFetcher( - dependencies: PublicationAsset.Dependencies, - credentials: String? - ): Try { - return try { - val fetcher = when { - file.isDirectory -> FileFetcher(href = "/", file = file) + val fileFetcher = FileFetcher(href = "/manifest.json", file = file) + val baseUrl = manifest.linkWithRel("self")?.let { File(it.href).parent } + val httpFetcher = HttpFetcher(httpClient, baseUrl) + return Try.success(RoutingFetcher(fileFetcher, httpFetcher)) + } - file.exists() -> ArchiveFetcher.fromPath(file.path, dependencies.archiveFactory) - ?: FileFetcher(href = "/${file.name}", file = file) + return Try.success(FileFetcher(href = "/${file.name}", file = file)) + } - else -> throw FileNotFoundException(file.path) + private fun File.readAsRwpm(packaged: Boolean): Try = + try { + val bytes = readBytes() + val string = String(bytes, Charset.defaultCharset()) + val json = JSONObject(string) + val manifest = Manifest.fromJSON(json, packaged = packaged) + ?: throw Exception("Failed to parse the RWPM Manifest") + Try.success(manifest) + } catch (e: Exception) { + Try.failure(e) } - Try.success(fetcher) - } catch (e: SecurityException) { - Try.failure(Publication.OpeningException.Forbidden(e)) - } catch (e: FileNotFoundException) { - Try.failure(Publication.OpeningException.NotFound(e)) - } } - - override fun toString(): String = "FileAsset(${file.path})" } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt index b99a851793..83ac049455 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt @@ -7,15 +7,14 @@ package org.readium.r2.shared.publication.asset import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.archive.ArchiveFactory import org.readium.r2.shared.util.mediatype.MediaType /** Represents a digital medium (e.g. a file) offering access to a publication. */ interface PublicationAsset { - /** Name of the asset, e.g. a filename. */ + /** + * Name of the asset, e.g. a filename. + */ val name: String /** @@ -23,12 +22,10 @@ interface PublicationAsset { * * If unknown, fallback on `MediaType.BINARY`. */ - suspend fun mediaType(): MediaType + val mediaType: MediaType /** - * Creates a fetcher used to access the asset's content. + * [Fetcher] to provide access to the asset content. */ - suspend fun createFetcher(dependencies: Dependencies, credentials: String?): Try - - data class Dependencies(val archiveFactory: ArchiveFactory) + val fetcher: Fetcher } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt new file mode 100644 index 0000000000..83f62d9db9 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.asset + +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * Builds [PublicationAsset]s for publications that can be accessed through various means. + */ +interface PublicationAssetFactory { + + /** + * Creates a [PublicationAsset] for a publication with media type [mediaType] available at [url]. + */ + suspend fun createAsset( + url: Url, + mediaType: MediaType + ): Try +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt new file mode 100644 index 0000000000..3e4d32b612 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.asset + +import org.readium.r2.shared.InternalReadiumApi +import org.readium.r2.shared.fetcher.ArchiveFetcher +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.fetcher.HttpFetcher +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.archive.ArchiveFactory +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * A [PublicationAsset] built for a remote publication. + */ +data class RemoteAsset( + val url: Url, + override val mediaType: MediaType, + override val fetcher: Fetcher +) : PublicationAsset { + + override val name: String = + url.file + + @InternalReadiumApi + class Factory( + private val archiveFactory: ArchiveFactory, + private val httpClient: HttpClient + ) { + suspend fun createAsset( + url: Url, + mediaType: MediaType, + ): Try = + createFetcher(url, mediaType) + .map { fetcher -> RemoteAsset(url, mediaType, fetcher) } + + private suspend fun createFetcher(url: Url, mediaType: MediaType): Try { + ArchiveFetcher.fromUrl(url, archiveFactory) + ?.let { return Try.success(it) } + + // This enables support for both exploded containers (thanks to baseUrl) and + // single-file publications (thanks to links). + val httpFetcher = HttpFetcher( + client = httpClient, + baseUrl = url.toString(), + links = listOf( + Link(href = url.toString(), type = mediaType.toString()) + ) + ) + + return Try.success(httpFetcher) + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt index 41ebeaa398..4a3b9ce77f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt @@ -1,3 +1,9 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + package org.readium.r2.shared.util import org.readium.r2.shared.InternalReadiumApi diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt new file mode 100644 index 0000000000..761bd3186a --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util + +import java.io.File +import java.net.URL +import org.readium.r2.shared.extensions.extension +import org.readium.r2.shared.extensions.tryOrNull + +/** + * A Uniform Resource Locator. + */ +@JvmInline +value class Url internal constructor(internal val url: URL) { + + val protocol: String + get() = url.protocol + + val authority: String + get() = url.authority + + val path: String + get() = url.path + + val file: String + get() = url.file + + val extension: String? + get() = url.extension + + override fun toString(): String = + url.toString() + + companion object { + + operator fun invoke(url: String): Url? = + tryOrNull { Url(URL(url)) } + } +} + +fun Url.toURL(): URL = + url + +fun Url.isFile(): Boolean = + protocol == "file" + +fun Url.readBytes() = url.openStream().use { it.readBytes() } + +fun File.toUrl(): Url = + Url(toURI().toURL()!!) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt index 83983ea0a2..3582989957 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt @@ -10,15 +10,26 @@ package org.readium.r2.shared.util.archive import java.io.File +import java.io.IOException +import java.net.URL import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.extensions.tryOr import org.readium.r2.shared.util.SuspendingCloseable +import org.readium.r2.shared.util.Url interface ArchiveFactory { /** Opens an archive from a local [file]. */ suspend fun open(file: File, password: String?): Archive + + /** Opens an archive from a local or remote [URL]. */ + suspend fun open(url: Url, password: String?): Archive = + if (url.protocol == "file") { + open(File(url.path), password) + } else { + throw IOException("Cannot access ZIP archives through protocol ${url.protocol}.") + } } class DefaultArchiveFactory : ArchiveFactory { @@ -36,6 +47,26 @@ class DefaultArchiveFactory : ArchiveFactory { } } +class CompositeArchiveFactory( + private val primaryFactory: ArchiveFactory, + private val fallbackFactory: ArchiveFactory +) : ArchiveFactory { + + override suspend fun open(file: File, password: String?): Archive = + try { + primaryFactory.open(file, password) + } catch (e: Exception) { + fallbackFactory.open(file, password) + } + + override suspend fun open(url: Url, password: String?): Archive = + try { + primaryFactory.open(url, password) + } catch (e: Exception) { + fallbackFactory.open(url, password) + } +} + /** * Represents an immutable archive. */ diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/BufferedReadableChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/BufferedReadableChannel.kt new file mode 100644 index 0000000000..d4c1d70e7a --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/BufferedReadableChannel.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.archive.channel + +import java.nio.ByteBuffer +import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel + +internal class BufferedReadableChannel( + private val innerChannel: SeekableByteChannel, + bufferSize: Int +) : SeekableByteChannel { + + private val dataBuffer: ByteBuffer = + ByteBuffer.allocate(bufferSize) + .apply { limit(0) } + + private val lock: Any = + Any() + + override fun close() { + synchronized(lock) { + innerChannel.close() + } + } + + override fun isOpen(): Boolean { + synchronized(lock) { + return innerChannel.isOpen + } + } + + override fun read(buffer: ByteBuffer): Int { + synchronized(lock) { + val sizeToRead = buffer.remaining() + val sizeToReadFromBuffer = sizeToRead.coerceAtMost(dataBuffer.remaining()) + + val temp = ByteArray(sizeToReadFromBuffer) + dataBuffer.get(temp, 0, sizeToReadFromBuffer) + buffer.put(temp) + + if (sizeToReadFromBuffer == sizeToRead) { + return sizeToReadFromBuffer + } + + dataBuffer.clear() + innerChannel.read(dataBuffer) + dataBuffer.flip() + + if (!dataBuffer.hasRemaining()) { + return sizeToReadFromBuffer + } + + return sizeToReadFromBuffer + read(buffer) + } + } + + override fun write(buffer: ByteBuffer): Int { + throw NonWritableChannelException() + } + + override fun position(): Long { + synchronized(lock) { + return innerChannel.position() - dataBuffer.remaining() + } + } + + override fun position(newPosition: Long): BufferedReadableChannel { + synchronized(lock) { + val innerPosition = innerChannel.position() + if (newPosition in innerPosition - dataBuffer.limit() until innerPosition) { + val newBufferPosition = (dataBuffer.limit() - (innerPosition - newPosition)).toInt() + dataBuffer.position(newBufferPosition) + } else { + dataBuffer.limit(0) + innerChannel.position(newPosition) + } + return this + } + } + + override fun size(): Long { + synchronized(lock) { + return innerChannel.size() + } + } + + override fun truncate(size: Long): BufferedReadableChannel { + throw NonWritableChannelException() + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/CachingReadableChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/CachingReadableChannel.kt new file mode 100644 index 0000000000..6fc2e49964 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/CachingReadableChannel.kt @@ -0,0 +1,105 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.archive.channel + +import java.nio.ByteBuffer +import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel + +internal class CachingReadableChannel( + private val innerChannel: SeekableByteChannel, + private val cacheFrom: Long = 0 +) : SeekableByteChannel { + + init { + require(cacheFrom < innerChannel.size()) + } + + private val tail: ByteBuffer = + ByteBuffer.allocate((innerChannel.size() - cacheFrom).toInt()) + .apply { limit(0) } + + private val lock: Any = + Any() + + override fun close() { + synchronized(lock) { + innerChannel.close() + } + } + + override fun isOpen(): Boolean { + synchronized(lock) { + return innerChannel.isOpen + } + } + + fun cache() { + synchronized(lock) { + cacheTail() + } + } + + override fun read(buffer: ByteBuffer): Int { + synchronized(lock) { + val channelPosition = innerChannel.position() + if (channelPosition in cacheFrom until innerChannel.size()) { + if (tail.limit() == 0) { + cacheTail() + } + + return readFromTail(buffer, channelPosition - cacheFrom) + } + + return innerChannel.read(buffer) + } + } + + private fun readFromTail(buffer: ByteBuffer, start: Long): Int { + tail.position(start.toInt()) + val sizeToRead = buffer.remaining().coerceAtMost(tail.remaining()) + val temp = ByteArray(sizeToRead) + tail.get(temp) + buffer.put(temp) + innerChannel.position(innerChannel.position() + sizeToRead) + return sizeToRead + } + + private fun cacheTail() { + tail.clear() + innerChannel.position(cacheFrom) + innerChannel.read(tail) + tail.flip() + } + + override fun write(buffer: ByteBuffer): Int { + throw NonWritableChannelException() + } + + override fun position(): Long { + synchronized(lock) { + return innerChannel.position() + } + } + + override fun position(newPosition: Long): CachingReadableChannel { + synchronized(lock) { + innerChannel.position(newPosition) + return this + } + } + + override fun size(): Long { + synchronized(lock) { + return innerChannel.size() + } + } + + override fun truncate(size: Long): CachingReadableChannel { + throw NonWritableChannelException() + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZip.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZip.kt new file mode 100644 index 0000000000..69a5825b39 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZip.kt @@ -0,0 +1,152 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.archive.channel + +import java.io.File +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.extensions.readFully +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.archive.Archive +import org.readium.r2.shared.util.archive.ArchiveFactory +import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipArchiveEntry +import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipFile +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel +import org.readium.r2.shared.util.http.DefaultHttpClient +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.io.CountingInputStream + +internal class ChannelZip( + private val archive: ZipFile +) : Archive { + + private inner class Entry(private val entry: ZipArchiveEntry) : Archive.Entry { + override val path: String get() = entry.name + + override val length: Long? get() = entry.size.takeUnless { it == -1L } + + override val compressedLength: Long? + get() = + if (entry.method == ZipArchiveEntry.STORED || entry.method == -1) + null + else + entry.compressedSize.takeUnless { it == -1L } + + override suspend fun read(range: LongRange?): ByteArray = + withContext(Dispatchers.IO) { + if (range == null) + readFully() + else + readRange(range) + } + + private suspend fun readFully(): ByteArray = + archive.getInputStream(entry).use { + it.readFully() + } + + private fun readRange(range: LongRange): ByteArray = + stream(range.first).readRange(range) + + /** + * Reading an entry in chunks (e.g. from the HTTP server) can be really slow if the entry + * is deflated in the archive, because we can't jump to an arbitrary offset in a deflated + * stream. This means that we need to read from the start of the entry for each chunk. + * + * To alleviate this issue, we cache a stream which will be reused as long as the chunks are + * requested in order. + * + * See this issue for more info: https://github.com/readium/r2-shared-kotlin/issues/129 + * + * In case of a stored entry, we create a new stream starting at the desired index in order + * to prevent downloading of data until [fromIndex]. + * + */ + private fun stream(fromIndex: Long): CountingInputStream { + if (entry.method == ZipArchiveEntry.STORED && fromIndex < entry.size) { + return CountingInputStream(archive.getRawInputStream(entry, fromIndex), fromIndex) + } + + // Reuse the current stream if it didn't exceed the requested index. + stream + ?.takeIf { it.count <= fromIndex } + ?.let { return it } + + stream?.close() + + return CountingInputStream(archive.getInputStream(entry)) + .also { stream = it } + } + + private var stream: CountingInputStream? = null + + override suspend fun close() { + withContext(Dispatchers.IO) { + stream?.close() + } + } + } + + override suspend fun entries(): List = + archive.entries.toList().filterNot { it.isDirectory }.mapNotNull { Entry(it) } + + override suspend fun entry(path: String): Archive.Entry { + val entry = archive.getEntry(path) + ?: throw Exception("No file entry at path $path.") + + return Entry(entry) + } + + override suspend fun close() = withContext(Dispatchers.IO) { + archive.close() + } +} + +/** + * An [ArchiveFactory] able to open a ZIP archive served through an HTTP server. + * + * The given [httpClient] is used to perform the HTTP requests. + */ +class ChannelZipArchiveFactory( + private val httpClient: HttpClient = DefaultHttpClient() +) : ArchiveFactory { + + override suspend fun open(file: File, password: String?): Archive = withContext(Dispatchers.IO) { + throw Exception("RemoteZipArchiveFactory doesn't support files.") + } + + override suspend fun open(url: Url, password: String?): Archive = withContext(Dispatchers.IO) { + val httpChannel = HttpChannel(url.toString(), httpClient) + val channel = wrapBaseChannel(httpChannel) + ChannelZip(ZipFile(channel, true)) + } + + internal fun openFile(file: File): Archive { + val fileChannel = FileChannelAdapter(file, "r") + val channel = wrapBaseChannel(fileChannel) + return ChannelZip(ZipFile(channel)) + } + + private fun wrapBaseChannel(channel: SeekableByteChannel): SeekableByteChannel { + val size = channel.size() + return if (size < CACHE_ALL_MAX_SIZE) { + CachingReadableChannel(channel, 0) + } else { + val cacheStart = size - CACHED_TAIL_SIZE + val cachingChannel = CachingReadableChannel(channel, cacheStart) + cachingChannel.cache() + BufferedReadableChannel(cachingChannel, DEFAULT_BUFFER_SIZE) + } + } + + companion object { + + private const val CACHE_ALL_MAX_SIZE = 5242880 + + private const val CACHED_TAIL_SIZE = 65557 + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/FileChannelAdapter.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/FileChannelAdapter.java new file mode 100644 index 0000000000..0263bec965 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/FileChannelAdapter.java @@ -0,0 +1,69 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.archive.channel; + +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +public class FileChannelAdapter implements SeekableByteChannel { + + private final FileChannel channel; + + FileChannelAdapter(final File file, final String mode) throws FileNotFoundException { + channel = new RandomAccessFile(file, mode).getChannel(); + } + + private FileChannelAdapter(final FileChannel channel) { + this.channel = channel; + } + + @Override + public int read(ByteBuffer dst) throws IOException { + return channel.read(dst); + } + + @Override + public int write(ByteBuffer src) throws IOException { + return channel.write(src); + } + + @Override + public long position() throws IOException { + return channel.position(); + } + + @Override + public SeekableByteChannel position(long newPosition) throws IOException { + return new FileChannelAdapter(channel.position(newPosition)); + } + + @Override + public long size() throws IOException { + return channel.size(); + } + + @Override + public SeekableByteChannel truncate(long size) throws IOException { + return new FileChannelAdapter(channel.truncate(size)); + } + + @Override + public boolean isOpen() { + return channel.isOpen(); + } + + @Override + public void close() throws IOException { + channel.close(); + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt new file mode 100644 index 0000000000..b95e4fe87a --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt @@ -0,0 +1,166 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.archive.channel + +import java.io.IOException +import java.io.InputStream +import java.nio.ByteBuffer +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.readium.r2.shared.extensions.readSafe +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.http.HttpException +import org.readium.r2.shared.util.http.HttpRequest +import org.readium.r2.shared.util.http.HttpResponse +import org.readium.r2.shared.util.io.CountingInputStream +import timber.log.Timber + +internal class HttpChannel( + private val url: String, + private val client: HttpClient, + private val maxSkipBytes: Long = 8192 +) : SeekableByteChannel { + + private var position: Long = 0 + + private val lock = Any() + + private var inputStream: CountingInputStream? = null + + private var inputStreamStart = 0L + + /** Cached HEAD response to get the expected content length and other metadata. */ + private lateinit var _headResponse: Try + + private suspend fun headResponse(): Try { + if (::_headResponse.isInitialized) + return _headResponse + + _headResponse = client.fetch(HttpRequest(url, method = HttpRequest.Method.HEAD)) + .map { it.response } + + return _headResponse + } + + /** + * Returns an HTTP stream for the resource, starting at the [from] byte offset. + * + * The stream is cached and reused for next calls, if the next [from] offset is in a forward + * direction. + */ + private suspend fun stream(from: Long? = null): Try { + Timber.d("getStream") + val stream = inputStream + if (from != null && stream != null) { + tryOrLog { + val bytesToSkip = from - (inputStreamStart + stream.count) + if (bytesToSkip in 0 until maxSkipBytes) { + stream.skip(bytesToSkip) + Timber.d("reusing stream") + return Try.success(stream) + } + } + } + + tryOrLog { inputStream?.close() } + + val request = HttpRequest(url) { + from?.takeUnless { it == 0L } + ?.let { setRange(from..-1) } + } + + Timber.d("request ${request.headers}") + + return client.stream(request) + .map { + Timber.d("responseCode ${it.response.statusCode}") + Timber.d("response ${it.response}") + Timber.d("responseHeaders ${it.response.headers}") + CountingInputStream(it.body) + } + .onSuccess { + inputStream = it + inputStreamStart = from ?: 0 + } + } + + override fun close() {} + + override fun isOpen(): Boolean { + return true + } + + override fun read(dst: ByteBuffer): Int { + synchronized(lock) { + return runBlocking { + withContext(Dispatchers.IO) { + val size = headResponse() + .map { it.contentLength } + .getOrThrow() + ?: throw IOException("Server didn't provide content length.") + + if (position >= size) { + return@withContext -1 + } + + Timber.d("position $position") + val available = size - position + val buffer = ByteArray(dst.remaining().coerceAtMost(available.toInt())) + Timber.d("bufferSize ${buffer.size}") + val read = stream(position) + .getOrThrow() + .readSafe(buffer) + Timber.d("read $read") + if (read != -1) { + dst.put(buffer, 0, read) + position += read + } + return@withContext read + } + } + } + } + + override fun write(src: ByteBuffer): Int { + throw NonWritableChannelException() + } + + override fun position(): Long { + synchronized(lock) { + return position + } + } + + override fun position(newPosition: Long): HttpChannel { + synchronized(lock) { + if (newPosition < 0) { + throw IllegalArgumentException("Requested position is negative.") + } + + position = newPosition + return this + } + } + + override fun size(): Long { + return synchronized(lock) { + runBlocking { headResponse() } + .getOrThrow() + .contentLength + ?: throw IOException("Unknown file length.") + } + } + + override fun truncate(size: Long): HttpChannel { + throw NonWritableChannelException() + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveEntry.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveEntry.java new file mode 100644 index 0000000000..9a4ad730d1 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveEntry.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers; + +import java.util.Date; + +/** + * Represents an entry of an archive. + */ +public interface ArchiveEntry { + + /** Special value indicating that the size is unknown */ + long SIZE_UNKNOWN = -1; + + /** + * Gets the last modified date of this entry. + * + * @return the last modified date of this entry. + * @since 1.1 + */ + Date getLastModifiedDate(); + + /** + * Gets the name of the entry in this archive. May refer to a file or directory or other item. + * + *

This method returns the raw name as it is stored inside of the archive.

+ * + * @return The name of this entry in the archive. + */ + String getName(); + + /** + * Gets the uncompressed size of this entry. May be -1 (SIZE_UNKNOWN) if the size is unknown + * + * @return the uncompressed size of this entry. + */ + long getSize(); + + /** + * Returns true if this entry refers to a directory. + * + * @return true if this entry refers to a directory. + */ + boolean isDirectory(); +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveInputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveInputStream.java new file mode 100644 index 0000000000..d4ee0e0205 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveInputStream.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Archive input streams MUST override the + * {@link #read(byte[], int, int)} - or {@link #read()} - + * method so that reading from the stream generates EOF for the end of + * data in each entry as well as at the end of the file proper. + *

+ * The {@link #getNextEntry()} method is used to reset the input stream + * ready for reading the data from the next entry. + *

+ * The input stream classes must also implement a method with the signature: + *

+ * public static boolean matches(byte[] signature, int length)
+ * 
+ * which is used by the ArchiveStreamFactory to autodetect + * the archive type from the first few bytes of a stream. + */ +public abstract class ArchiveInputStream extends InputStream { + + private static final int BYTE_MASK = 0xFF; + private final byte[] single = new byte[1]; + + /** holds the number of bytes read in this stream */ + private long bytesRead; + + /** + * Whether this stream is able to read the given entry. + * + *

+ * Some archive formats support variants or details that are not supported (yet). + *

+ * + * @param archiveEntry + * the entry to test + * @return This implementation always returns true. + * + * @since 1.1 + */ + public boolean canReadEntryData(final ArchiveEntry archiveEntry) { + return true; + } + + /* + * Note that subclasses also implement specific get() methods which + * return the appropriate class without need for a cast. + * See SVN revision r743259 + * @return + * @throws IOException + */ + // public abstract XXXArchiveEntry getNextXXXEntry() throws IOException; + + /** + * Increments the counter of already read bytes. + * Doesn't increment if the EOF has been hit (read == -1) + * + * @param read the number of bytes read + */ + protected void count(final int read) { + count((long) read); + } + + /** + * Increments the counter of already read bytes. + * Doesn't increment if the EOF has been hit (read == -1) + * + * @param read the number of bytes read + * @since 1.1 + */ + protected void count(final long read) { + if (read != -1) { + bytesRead = bytesRead + read; + } + } + + /** + * Returns the current number of bytes read from this stream. + * @return the number of read bytes + * @since 1.1 + */ + public long getBytesRead() { + return bytesRead; + } + + /** + * Returns the current number of bytes read from this stream. + * @return the number of read bytes + * @deprecated this method may yield wrong results for large + * archives, use #getBytesRead instead + */ + @Deprecated + public int getCount() { + return (int) bytesRead; + } + + /** + * Returns the next Archive Entry in this Stream. + * + * @return the next entry, + * or {@code null} if there are no more entries + * @throws IOException if the next entry could not be read + */ + public abstract ArchiveEntry getNextEntry() throws IOException; + + /** + * Decrements the counter of already read bytes. + * + * @param pushedBack the number of bytes pushed back. + * @since 1.1 + */ + protected void pushedBackBytes(final long pushedBack) { + bytesRead -= pushedBack; + } + + /** + * Reads a byte of data. This method will block until enough input is + * available. + * + * Simply calls the {@link #read(byte[], int, int)} method. + * + * MUST be overridden if the {@link #read(byte[], int, int)} method + * is not overridden; may be overridden otherwise. + * + * @return the byte read, or -1 if end of input is reached + * @throws IOException + * if an I/O error has occurred + */ + @Override + public int read() throws IOException { + final int num = read(single, 0, 1); + return num == -1 ? -1 : single[0] & BYTE_MASK; + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveOutputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveOutputStream.java new file mode 100644 index 0000000000..3ce0b05965 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/ArchiveOutputStream.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Archive output stream implementations are expected to override the + * {@link #write(byte[], int, int)} method to improve performance. + * They should also override {@link #close()} to ensure that any necessary + * trailers are added. + * + *

The normal sequence of calls when working with ArchiveOutputStreams is:

+ *
    + *
  • Create ArchiveOutputStream object,
  • + *
  • optionally write SFX header (Zip only),
  • + *
  • repeat as needed: + *
      + *
    • {@link #putArchiveEntry(ArchiveEntry)} (writes entry header), + *
    • {@link #write(byte[])} (writes entry data, as often as needed), + *
    • {@link #closeArchiveEntry()} (closes entry), + *
    + *
  • + *
  • {@link #finish()} (ends the addition of entries),
  • + *
  • optionally write additional data, provided format supports it,
  • + *
  • {@link #close()}.
  • + *
+ */ +public abstract class ArchiveOutputStream extends OutputStream { + + static final int BYTE_MASK = 0xFF; + /** Temporary buffer used for the {@link #write(int)} method */ + private final byte[] oneByte = new byte[1]; + + /** holds the number of bytes written to this stream */ + private long bytesWritten; + // Methods specific to ArchiveOutputStream + + /** + * Whether this stream is able to write the given entry. + * + *

Some archive formats support variants or details that are + * not supported (yet).

+ * + * @param archiveEntry + * the entry to test + * @return This implementation always returns true. + * @since 1.1 + */ + public boolean canWriteEntryData(final ArchiveEntry archiveEntry) { + return true; + } + + /** + * Closes the archive entry, writing any trailer information that may + * be required. + * @throws IOException if an I/O error occurs + */ + public abstract void closeArchiveEntry() throws IOException; + + /** + * Increments the counter of already written bytes. + * Doesn't increment if EOF has been hit ({@code written == -1}). + * + * @param written the number of bytes written + */ + protected void count(final int written) { + count((long) written); + } + + /** + * Increments the counter of already written bytes. + * Doesn't increment if EOF has been hit ({@code written == -1}). + * + * @param written the number of bytes written + * @since 1.1 + */ + protected void count(final long written) { + if (written != -1) { + bytesWritten = bytesWritten + written; + } + } + + /** + * Create an archive entry using the inputFile and entryName provided. + * + * @param inputFile the file to create the entry from + * @param entryName name to use for the entry + * @return the ArchiveEntry set up with details from the file + * + * @throws IOException if an I/O error occurs + */ + public abstract ArchiveEntry createArchiveEntry(File inputFile, String entryName) throws IOException; + + // Generic implementations of OutputStream methods that may be useful to sub-classes + + /** + * Finishes the addition of entries to this stream, without closing it. + * Additional data can be written, if the format supports it. + * + * @throws IOException if the user forgets to close the entry. + */ + public abstract void finish() throws IOException; + + /** + * Returns the current number of bytes written to this stream. + * @return the number of written bytes + * @since 1.1 + */ + public long getBytesWritten() { + return bytesWritten; + } + + /** + * Returns the current number of bytes written to this stream. + * @return the number of written bytes + * @deprecated this method may yield wrong results for large + * archives, use #getBytesWritten instead + */ + @Deprecated + public int getCount() { + return (int) bytesWritten; + } + + /** + * Writes the headers for an archive entry to the output stream. + * The caller must then write the content to the stream and call + * {@link #closeArchiveEntry()} to complete the process. + * + * @param entry describes the entry + * @throws IOException if an I/O error occurs + */ + public abstract void putArchiveEntry(ArchiveEntry entry) throws IOException; + + /** + * Writes a byte to the current archive entry. + * + *

This method simply calls {@code write( byte[], 0, 1 )}. + * + *

MUST be overridden if the {@link #write(byte[], int, int)} method + * is not overridden; may be overridden otherwise. + * + * @param b The byte to be written. + * @throws IOException on error + */ + @Override + public void write(final int b) throws IOException { + oneByte[0] = (byte) (b & BYTE_MASK); + write(oneByte, 0, 1); + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/EntryStreamOffsets.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/EntryStreamOffsets.java new file mode 100644 index 0000000000..b4a3875e01 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/EntryStreamOffsets.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers; + +/** + * Provides information about ArchiveEntry stream offsets. + */ +public interface EntryStreamOffsets { + + /** Special value indicating that the offset is unknown. */ + long OFFSET_UNKNOWN = -1; + + /** + * Gets the offset of data stream within the archive file, + * + * @return + * the offset of entry data stream, {@code OFFSET_UNKNOWN} if not known. + */ + long getDataOffset(); + + /** + * Indicates whether the stream is contiguous, i.e. not split among + * several archive parts, interspersed with control blocks, etc. + * + * @return + * true if stream is contiguous, false otherwise. + */ + boolean isStreamContiguous(); +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/AbstractUnicodeExtraField.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/AbstractUnicodeExtraField.java new file mode 100644 index 0000000000..f6abd92938 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/AbstractUnicodeExtraField.java @@ -0,0 +1,193 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.util.zip.CRC32; +import java.util.zip.ZipException; + +/** + * A common base class for Unicode extra information extra fields. + * @NotThreadSafe + */ +public abstract class AbstractUnicodeExtraField implements ZipExtraField { + private long nameCRC32; + private byte[] unicodeName; + private byte[] data; + + protected AbstractUnicodeExtraField() { + } + + /** + * Assemble as unicode extension from the name/comment and + * encoding of the original zip entry. + * + * @param text The file name or comment. + * @param bytes The encoded of the file name or comment in the zip + * file. + */ + protected AbstractUnicodeExtraField(final String text, final byte[] bytes) { + this(text, bytes, 0, bytes.length); + } + + /** + * Assemble as unicode extension from the name/comment and + * encoding of the original zip entry. + * + * @param text The file name or comment. + * @param bytes The encoded of the file name or comment in the zip + * file. + * @param off The offset of the encoded file name or comment in + * {@code bytes}. + * @param len The length of the encoded file name or comment in + * {@code bytes}. + */ + protected AbstractUnicodeExtraField(final String text, final byte[] bytes, final int off, final int len) { + final CRC32 crc32 = new CRC32(); + crc32.update(bytes, off, len); + nameCRC32 = crc32.getValue(); + + unicodeName = text.getBytes(UTF_8); + } + + private void assembleData() { + if (unicodeName == null) { + return; + } + + data = new byte[5 + unicodeName.length]; + // version 1 + data[0] = 0x01; + System.arraycopy(ZipLong.getBytes(nameCRC32), 0, data, 1, 4); + System.arraycopy(unicodeName, 0, data, 5, unicodeName.length); + } + + @Override + public byte[] getCentralDirectoryData() { + if (data == null) { + this.assembleData(); + } + byte[] b = null; + if (data != null) { + b = new byte[data.length]; + System.arraycopy(data, 0, b, 0, b.length); + } + return b; + } + + @Override + public ZipShort getCentralDirectoryLength() { + if (data == null) { + assembleData(); + } + return new ZipShort(data != null ? data.length : 0); + } + + @Override + public byte[] getLocalFileDataData() { + return getCentralDirectoryData(); + } + + @Override + public ZipShort getLocalFileDataLength() { + return getCentralDirectoryLength(); + } + + /** + * @return The CRC32 checksum of the file name or comment as + * encoded in the central directory of the zip file. + */ + public long getNameCRC32() { + return nameCRC32; + } + + /** + * @return The UTF-8 encoded name. + */ + public byte[] getUnicodeName() { + byte[] b = null; + if (unicodeName != null) { + b = new byte[unicodeName.length]; + System.arraycopy(unicodeName, 0, b, 0, b.length); + } + return b; + } + + /** + * Doesn't do anything special since this class always uses the + * same data in central directory and local file data. + */ + @Override + public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, + final int length) + throws ZipException { + parseFromLocalFileData(buffer, offset, length); + } + + @Override + public void parseFromLocalFileData(final byte[] buffer, final int offset, final int length) + throws ZipException { + + if (length < 5) { + throw new ZipException("UniCode path extra data must have at least 5 bytes."); + } + + final int version = buffer[offset]; + + if (version != 0x01) { + throw new ZipException("Unsupported version [" + version + + "] for UniCode path extra data."); + } + + nameCRC32 = ZipLong.getValue(buffer, offset + 1); + unicodeName = new byte[length - 5]; + System.arraycopy(buffer, offset + 5, unicodeName, 0, length - 5); + data = null; + } + + /** + * @param nameCRC32 The CRC32 checksum of the file name as encoded + * in the central directory of the zip file to set. + */ + public void setNameCRC32(final long nameCRC32) { + this.nameCRC32 = nameCRC32; + data = null; + } + + /** + * @param unicodeName The UTF-8 encoded name to set. + */ + public void setUnicodeName(final byte[] unicodeName) { + if (unicodeName != null) { + this.unicodeName = new byte[unicodeName.length]; + System.arraycopy(unicodeName, 0, this.unicodeName, 0, + unicodeName.length); + } else { + this.unicodeName = null; + } + data = null; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/CharsetAccessor.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/CharsetAccessor.java new file mode 100644 index 0000000000..dadd2634cd --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/CharsetAccessor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.nio.charset.Charset; + +/** + * An interface added to allow access to the character set associated with an {@link NioZipEncoding}, + * without requiring a new method to be added to {@link ZipEncoding}. + *

+ * This avoids introducing a + * potentially breaking change, or making {@link NioZipEncoding} a public class. + *

+ * @since 1.15 + */ +public interface CharsetAccessor { + + /** + * Provides access to the character set associated with an object. + *

+ * This allows nio oriented code to use more natural character encoding/decoding methods, + * whilst allowing existing code to continue to rely on special-case error handling for UTF-8. + *

+ * @return the character set associated with this object + */ + Charset getCharset(); +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldParsingBehavior.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldParsingBehavior.java new file mode 100644 index 0000000000..8185d5b6ac --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldParsingBehavior.java @@ -0,0 +1,69 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.zip.ZipException; + +/** + * Controls details of parsing zip extra fields. + * + * @since 1.19 + */ +public interface ExtraFieldParsingBehavior extends UnparseableExtraFieldBehavior { + /** + * Creates an instance of ZipExtraField for the given id. + * + *

A good default implementation would be {@link + * ExtraFieldUtils#createExtraField}.

+ * + * @param headerId the id for the extra field + * @return an instance of ZipExtraField, must not be {@code null} + * @throws ZipException if an error occurs + * @throws InstantiationException if unable to instantiate the class + * @throws IllegalAccessException if not allowed to instantiate the class + */ + ZipExtraField createExtraField(final ZipShort headerId) + throws ZipException, InstantiationException, IllegalAccessException; + + /** + * Fills in the extra field data for a single extra field. + * + *

A good default implementation would be {@link + * ExtraFieldUtils#fillExtraField}.

+ * + * @param field the extra field instance to fill + * @param data the array of extra field data + * @param off offset into data where this field's data starts + * @param len the length of this field's data + * @param local whether the extra field data stems from the local + * file header. If this is false then the data is part if the + * central directory header extra data. + * @return the filled field. Usually this is the same as {@code + * field} but it could be a replacement extra field as well. Must + * not be {@code null}. + * @throws ZipException if an error occurs + */ + ZipExtraField fill(ZipExtraField field, byte[] data, int off, int len, boolean local) + throws ZipException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldUtils.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldUtils.java new file mode 100644 index 0000000000..8ca535d05f --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ExtraFieldUtils.java @@ -0,0 +1,414 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.zip.ZipException; + +/** + * ZipExtraField related methods + * @NotThreadSafe because the HashMap is not synch. + */ +// CheckStyle:HideUtilityClassConstructorCheck OFF (bc) +public class ExtraFieldUtils { + + /** + * "enum" for the possible actions to take if the extra field + * cannot be parsed. + * + *

This class has been created long before Java 5 and would + * have been a real enum ever since.

+ * + * @since 1.1 + */ + public static final class UnparseableExtraField implements UnparseableExtraFieldBehavior { + /** + * Key for "throw an exception" action. + */ + public static final int THROW_KEY = 0; + /** + * Key for "skip" action. + */ + public static final int SKIP_KEY = 1; + /** + * Key for "read" action. + */ + public static final int READ_KEY = 2; + + /** + * Throw an exception if field cannot be parsed. + */ + public static final UnparseableExtraField THROW + = new UnparseableExtraField(THROW_KEY); + + /** + * Skip the extra field entirely and don't make its data + * available - effectively removing the extra field data. + */ + public static final UnparseableExtraField SKIP + = new UnparseableExtraField(SKIP_KEY); + + /** + * Read the extra field data into an instance of {@link + * UnparseableExtraFieldData UnparseableExtraFieldData}. + */ + public static final UnparseableExtraField READ + = new UnparseableExtraField(READ_KEY); + + private final int key; + + private UnparseableExtraField(final int k) { + key = k; + } + + /** + * Key of the action to take. + * @return the key + */ + public int getKey() { return key; } + + @Override + public ZipExtraField onUnparseableExtraField(final byte[] data, final int off, final int len, final boolean local, + final int claimedLength) throws ZipException { + switch(key) { + case THROW_KEY: + throw new ZipException("Bad extra field starting at " + + off + ". Block length of " + + claimedLength + " bytes exceeds remaining" + + " data of " + + (len - WORD) + + " bytes."); + case READ_KEY: + final UnparseableExtraFieldData field = new UnparseableExtraFieldData(); + if (local) { + field.parseFromLocalFileData(data, off, len); + } else { + field.parseFromCentralDirectoryData(data, off, len); + } + return field; + case SKIP_KEY: + return null; + default: + throw new ZipException("Unknown UnparseableExtraField key: " + key); + } + } + + } + + private static final int WORD = 4; + + /** + * Static registry of known extra fields. + */ + private static final Map> IMPLEMENTATIONS; + + static { + IMPLEMENTATIONS = new ConcurrentHashMap<>(); + } + + static final ZipExtraField[] EMPTY_ZIP_EXTRA_FIELD_ARRAY = {}; + + /** + * Create an instance of the appropriate ExtraField, falls back to + * {@link UnrecognizedExtraField UnrecognizedExtraField}. + * @param headerId the header identifier + * @return an instance of the appropriate ExtraField + * @throws InstantiationException if unable to instantiate the class + * @throws IllegalAccessException if not allowed to instantiate the class + */ + public static ZipExtraField createExtraField(final ZipShort headerId) + throws InstantiationException, IllegalAccessException { + final ZipExtraField field = createExtraFieldNoDefault(headerId); + if (field != null) { + return field; + } + final UnrecognizedExtraField u = new UnrecognizedExtraField(); + u.setHeaderId(headerId); + return u; + } + + /** + * Create an instance of the appropriate ExtraField. + * @param headerId the header identifier + * @return an instance of the appropriate ExtraField or null if + * the id is not supported + * @throws InstantiationException if unable to instantiate the class + * @throws IllegalAccessException if not allowed to instantiate the class + * @since 1.19 + */ + public static ZipExtraField createExtraFieldNoDefault(final ZipShort headerId) + throws InstantiationException, IllegalAccessException { + final Class c = IMPLEMENTATIONS.get(headerId); + if (c != null) { + return (ZipExtraField) c.newInstance(); + } + return null; + } + + /** + * Fills in the extra field data into the given instance. + * + *

Calls {@link ZipExtraField#parseFromCentralDirectoryData} or {@link ZipExtraField#parseFromLocalFileData} internally and wraps any {@link ArrayIndexOutOfBoundsException} thrown into a {@link ZipException}.

+ * + * @param ze the extra field instance to fill + * @param data the array of extra field data + * @param off offset into data where this field's data starts + * @param len the length of this field's data + * @param local whether the extra field data stems from the local + * file header. If this is false then the data is part if the + * central directory header extra data. + * @return the filled field, will never be {@code null} + * @throws ZipException if an error occurs + * + * @since 1.19 + */ + public static ZipExtraField fillExtraField(final ZipExtraField ze, final byte[] data, final int off, + final int len, final boolean local) throws ZipException { + try { + if (local) { + ze.parseFromLocalFileData(data, off, len); + } else { + ze.parseFromCentralDirectoryData(data, off, len); + } + return ze; + } catch (final ArrayIndexOutOfBoundsException aiobe) { + throw (ZipException) new ZipException("Failed to parse corrupt ZIP extra field of type " + + Integer.toHexString(ze.getHeaderId().getValue())).initCause(aiobe); + } + } + + /** + * Merges the central directory fields of the given ZipExtraFields. + * @param data an array of ExtraFields + * @return an array of bytes + */ + public static byte[] mergeCentralDirectoryData(final ZipExtraField[] data) { + final int dataLength = data.length; + final boolean lastIsUnparseableHolder = dataLength > 0 + && data[dataLength - 1] instanceof UnparseableExtraFieldData; + final int regularExtraFieldCount = + lastIsUnparseableHolder ? dataLength - 1 : dataLength; + + int sum = WORD * regularExtraFieldCount; + for (final ZipExtraField element : data) { + sum += element.getCentralDirectoryLength().getValue(); + } + final byte[] result = new byte[sum]; + int start = 0; + for (int i = 0; i < regularExtraFieldCount; i++) { + System.arraycopy(data[i].getHeaderId().getBytes(), + 0, result, start, 2); + System.arraycopy(data[i].getCentralDirectoryLength().getBytes(), + 0, result, start + 2, 2); + start += WORD; + final byte[] central = data[i].getCentralDirectoryData(); + if (central != null) { + System.arraycopy(central, 0, result, start, central.length); + start += central.length; + } + } + if (lastIsUnparseableHolder) { + final byte[] central = data[dataLength - 1].getCentralDirectoryData(); + if (central != null) { + System.arraycopy(central, 0, result, start, central.length); + } + } + return result; + } + + /** + * Merges the local file data fields of the given ZipExtraFields. + * @param data an array of ExtraFiles + * @return an array of bytes + */ + public static byte[] mergeLocalFileDataData(final ZipExtraField[] data) { + final int dataLength = data.length; + final boolean lastIsUnparseableHolder = dataLength > 0 + && data[dataLength - 1] instanceof UnparseableExtraFieldData; + final int regularExtraFieldCount = + lastIsUnparseableHolder ? dataLength - 1 : dataLength; + + int sum = WORD * regularExtraFieldCount; + for (final ZipExtraField element : data) { + sum += element.getLocalFileDataLength().getValue(); + } + + final byte[] result = new byte[sum]; + int start = 0; + for (int i = 0; i < regularExtraFieldCount; i++) { + System.arraycopy(data[i].getHeaderId().getBytes(), + 0, result, start, 2); + System.arraycopy(data[i].getLocalFileDataLength().getBytes(), + 0, result, start + 2, 2); + start += WORD; + final byte[] local = data[i].getLocalFileDataData(); + if (local != null) { + System.arraycopy(local, 0, result, start, local.length); + start += local.length; + } + } + if (lastIsUnparseableHolder) { + final byte[] local = data[dataLength - 1].getLocalFileDataData(); + if (local != null) { + System.arraycopy(local, 0, result, start, local.length); + } + } + return result; + } + + /** + * Split the array into ExtraFields and populate them with the + * given data as local file data, throwing an exception if the + * data cannot be parsed. + * @param data an array of bytes as it appears in local file data + * @return an array of ExtraFields + * @throws ZipException on error + */ + public static ZipExtraField[] parse(final byte[] data) throws ZipException { + return parse(data, true, UnparseableExtraField.THROW); + } + + /** + * Split the array into ExtraFields and populate them with the + * given data, throwing an exception if the data cannot be parsed. + * @param data an array of bytes + * @param local whether data originates from the local file data + * or the central directory + * @return an array of ExtraFields + * @throws ZipException on error + */ + public static ZipExtraField[] parse(final byte[] data, final boolean local) + throws ZipException { + return parse(data, local, UnparseableExtraField.THROW); + } + + /** + * Split the array into ExtraFields and populate them with the + * given data. + * @param data an array of bytes + * @param parsingBehavior controls parsing of extra fields. + * @param local whether data originates from the local file data + * or the central directory + * @return an array of ExtraFields + * @throws ZipException on error + * + * @since 1.19 + */ + public static ZipExtraField[] parse(final byte[] data, final boolean local, + final ExtraFieldParsingBehavior parsingBehavior) + throws ZipException { + final List v = new ArrayList<>(); + int start = 0; + final int dataLength = data.length; + LOOP: + while (start <= dataLength - WORD) { + final ZipShort headerId = new ZipShort(data, start); + final int length = new ZipShort(data, start + 2).getValue(); + if (start + WORD + length > dataLength) { + final ZipExtraField field = parsingBehavior.onUnparseableExtraField(data, start, dataLength - start, + local, length); + if (field != null) { + v.add(field); + } + // since we cannot parse the data we must assume + // the extra field consumes the whole rest of the + // available data + break LOOP; + } + try { + final ZipExtraField ze = Objects.requireNonNull(parsingBehavior.createExtraField(headerId), + "createExtraField must not return null"); + v.add(Objects.requireNonNull(parsingBehavior.fill(ze, data, start + WORD, length, local), + "fill must not return null")); + start += length + WORD; + } catch (final InstantiationException | IllegalAccessException ie) { + throw (ZipException) new ZipException(ie.getMessage()).initCause(ie); + } + } + + return v.toArray(EMPTY_ZIP_EXTRA_FIELD_ARRAY); + } + + /** + * Split the array into ExtraFields and populate them with the + * given data. + * @param data an array of bytes + * @param local whether data originates from the local file data + * or the central directory + * @param onUnparseableData what to do if the extra field data + * cannot be parsed. + * @return an array of ExtraFields + * @throws ZipException on error + * + * @since 1.1 + */ + public static ZipExtraField[] parse(final byte[] data, final boolean local, + final UnparseableExtraField onUnparseableData) + throws ZipException { + return parse(data, local, new ExtraFieldParsingBehavior() { + @Override + public ZipExtraField createExtraField(final ZipShort headerId) + throws ZipException, InstantiationException, IllegalAccessException { + return ExtraFieldUtils.createExtraField(headerId); + } + + @Override + public ZipExtraField fill(final ZipExtraField field, final byte[] data, final int off, final int len, final boolean local) + throws ZipException { + return fillExtraField(field, data, off, len, local); + } + + @Override + public ZipExtraField onUnparseableExtraField(final byte[] data, final int off, final int len, final boolean local, + final int claimedLength) throws ZipException { + return onUnparseableData.onUnparseableExtraField(data, off, len, local, claimedLength); + } + }); + } + + /** + * Register a ZipExtraField implementation. + * + *

The given class must have a no-arg constructor and implement + * the {@link ZipExtraField ZipExtraField interface}.

+ * @param c the class to register + */ + public static void register(final Class c) { + try { + final ZipExtraField ze = (ZipExtraField) c.newInstance(); + IMPLEMENTATIONS.put(ze.getHeaderId(), c); + } catch (final ClassCastException cc) { // NOSONAR + throw new IllegalArgumentException(c + " doesn't implement ZipExtraField"); //NOSONAR + } catch (final InstantiationException ie) { // NOSONAR + throw new IllegalArgumentException(c + " is not a concrete class"); //NOSONAR + } catch (final IllegalAccessException ie) { // NOSONAR + throw new IllegalArgumentException(c + "'s no-arg constructor is not public"); //NOSONAR + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/GeneralPurposeBit.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/GeneralPurposeBit.java new file mode 100644 index 0000000000..865b22f4a1 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/GeneralPurposeBit.java @@ -0,0 +1,252 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * Parser/encoder for the "general purpose bit" field in ZIP's local + * file and central directory headers. + * + * @since 1.1 + * @NotThreadSafe + */ +public final class GeneralPurposeBit implements Cloneable { + + /** + * Indicates that the file is encrypted. + */ + private static final int ENCRYPTION_FLAG = 1 << 0; + + /** + * Indicates the size of the sliding dictionary used by the compression method 6 (imploding). + *
    + *
  • 0: 4096 bytes
  • + *
  • 1: 8192 bytes
  • + *
+ */ + private static final int SLIDING_DICTIONARY_SIZE_FLAG = 1 << 1; + + /** + * Indicates the number of Shannon-Fano trees used by the compression method 6 (imploding). + *
    + *
  • 0: 2 trees (lengths, distances)
  • + *
  • 1: 3 trees (literals, lengths, distances)
  • + *
+ */ + private static final int NUMBER_OF_SHANNON_FANO_TREES_FLAG = 1 << 2; + + /** + * Indicates that a data descriptor stored after the file contents + * will hold CRC and size information. + */ + private static final int DATA_DESCRIPTOR_FLAG = 1 << 3; + + /** + * Indicates strong encryption. + */ + private static final int STRONG_ENCRYPTION_FLAG = 1 << 6; + + /** + * Indicates that file names are written in UTF-8. + * + *

The only reason this is public is that {@link + * ZipArchiveOutputStream#EFS_FLAG} was public in Apache Commons + * Compress 1.0 and we needed a substitute for it.

+ */ + public static final int UFT8_NAMES_FLAG = 1 << 11; + + /** + * Parses the supported flags from the given archive data. + * + * @param data local file header or a central directory entry. + * @param offset offset at which the general purpose bit starts + * @return parsed flags + */ + public static GeneralPurposeBit parse(final byte[] data, final int offset) { + final int generalPurposeFlag = ZipShort.getValue(data, offset); + final GeneralPurposeBit b = new GeneralPurposeBit(); + b.useDataDescriptor((generalPurposeFlag & DATA_DESCRIPTOR_FLAG) != 0); + b.useUTF8ForNames((generalPurposeFlag & UFT8_NAMES_FLAG) != 0); + b.useStrongEncryption((generalPurposeFlag & STRONG_ENCRYPTION_FLAG) != 0); + b.useEncryption((generalPurposeFlag & ENCRYPTION_FLAG) != 0); + b.slidingDictionarySize = (generalPurposeFlag & SLIDING_DICTIONARY_SIZE_FLAG) != 0 ? 8192 : 4096; + b.numberOfShannonFanoTrees = (generalPurposeFlag & NUMBER_OF_SHANNON_FANO_TREES_FLAG) != 0 ? 3 : 2; + return b; + } + private boolean languageEncodingFlag; + private boolean dataDescriptorFlag; + private boolean encryptionFlag; + private boolean strongEncryptionFlag; + private int slidingDictionarySize; + + private int numberOfShannonFanoTrees; + + public GeneralPurposeBit() { + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException ex) { + // impossible + throw new IllegalStateException("GeneralPurposeBit is not Cloneable?", ex); //NOSONAR + } + } + + /** + * Encodes the set bits in a form suitable for ZIP archives. + * @return the encoded general purpose bits + */ + public byte[] encode() { + final byte[] result = new byte[2]; + encode(result, 0); + return result; + } + + /** + * Encodes the set bits in a form suitable for ZIP archives. + * + * @param buf the output buffer + * @param offset + * The offset within the output buffer of the first byte to be written. + * must be non-negative and no larger than {@code buf.length-2} + */ + public void encode(final byte[] buf, final int offset) { + ZipShort.putShort((dataDescriptorFlag ? DATA_DESCRIPTOR_FLAG : 0) + | + (languageEncodingFlag ? UFT8_NAMES_FLAG : 0) + | + (encryptionFlag ? ENCRYPTION_FLAG : 0) + | + (strongEncryptionFlag ? STRONG_ENCRYPTION_FLAG : 0) + , buf, offset); + } + + @Override + public boolean equals(final Object o) { + if (!(o instanceof GeneralPurposeBit)) { + return false; + } + final GeneralPurposeBit g = (GeneralPurposeBit) o; + return g.encryptionFlag == encryptionFlag + && g.strongEncryptionFlag == strongEncryptionFlag + && g.languageEncodingFlag == languageEncodingFlag + && g.dataDescriptorFlag == dataDescriptorFlag; + } + + /** + * Returns the number of trees used by the compression method 6 (imploding). + */ + int getNumberOfShannonFanoTrees() { + return numberOfShannonFanoTrees; + } + + /** + * Returns the sliding dictionary size used by the compression method 6 (imploding). + */ + int getSlidingDictionarySize() { + return slidingDictionarySize; + } + + @Override + public int hashCode() { + return 3 * (7 * (13 * (17 * (encryptionFlag ? 1 : 0) + + (strongEncryptionFlag ? 1 : 0)) + + (languageEncodingFlag ? 1 : 0)) + + (dataDescriptorFlag ? 1 : 0)); + } + + /** + * whether the current entry will use the data descriptor to store + * CRC and size information. + * @param b whether the current entry will use the data descriptor to store + * CRC and size information + */ + public void useDataDescriptor(final boolean b) { + dataDescriptorFlag = b; + } + + /** + * whether the current entry will be encrypted. + * @param b whether the current entry will be encrypted + */ + public void useEncryption(final boolean b) { + encryptionFlag = b; + } + + /** + * whether the current entry uses the data descriptor to store CRC + * and size information. + * @return whether the current entry uses the data descriptor to store CRC + * and size information + */ + public boolean usesDataDescriptor() { + return dataDescriptorFlag; + } + + + /** + * whether the current entry is encrypted. + * @return whether the current entry is encrypted + */ + public boolean usesEncryption() { + return encryptionFlag; + } + + /** + * whether the current entry is encrypted using strong encryption. + * @return whether the current entry is encrypted using strong encryption + */ + public boolean usesStrongEncryption() { + return encryptionFlag && strongEncryptionFlag; + } + + /** + * whether the current entry will be encrypted using strong encryption. + * @param b whether the current entry will be encrypted using strong encryption + */ + public void useStrongEncryption(final boolean b) { + strongEncryptionFlag = b; + if (b) { + useEncryption(true); + } + } + + /** + * whether the current entry uses UTF8 for file name and comment. + * @return whether the current entry uses UTF8 for file name and comment. + */ + public boolean usesUTF8ForNames() { + return languageEncodingFlag; + } + + /** + * whether the current entry will use UTF8 for file name and comment. + * @param b whether the current entry will use UTF8 for file name and comment. + */ + public void useUTF8ForNames(final boolean b) { + languageEncodingFlag = b; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/InflaterInputStreamWithStatistics.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/InflaterInputStreamWithStatistics.java new file mode 100644 index 0000000000..3f40f0d97d --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/InflaterInputStreamWithStatistics.java @@ -0,0 +1,89 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + +import org.readium.r2.shared.util.archive.channel.compress.utils.InputStreamStatistics; + +/** + * Helper class to provide statistics + * + * @since 1.17 + */ +/* package */ class InflaterInputStreamWithStatistics extends InflaterInputStream + implements InputStreamStatistics { + private long compressedCount; + private long uncompressedCount; + + public InflaterInputStreamWithStatistics(final InputStream in) { + super(in); + } + + public InflaterInputStreamWithStatistics(final InputStream in, final Inflater inf) { + super(in, inf); + } + + public InflaterInputStreamWithStatistics(final InputStream in, final Inflater inf, final int size) { + super(in, inf, size); + } + + @Override + protected void fill() throws IOException { + super.fill(); + compressedCount += inf.getRemaining(); + } + + @Override + public long getCompressedCount() { + return compressedCount; + } + + @Override + public long getUncompressedCount() { + return uncompressedCount; + } + + @Override + public int read() throws IOException { + final int b = super.read(); + if (b > -1) { + uncompressedCount++; + } + return b; + } + + @Override + public int read(final byte[] b, final int off, final int len) throws IOException { + final int bytes = super.read(b, off, len); + if (bytes > -1) { + uncompressedCount += bytes; + } + return bytes; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/NioZipEncoding.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/NioZipEncoding.java new file mode 100644 index 0000000000..211165fee8 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/NioZipEncoding.java @@ -0,0 +1,223 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +/** + * A ZipEncoding, which uses a java.nio {@link + * java.nio.charset.Charset Charset} to encode names. + *

The methods of this class are reentrant.

+ * @Immutable + */ +class NioZipEncoding implements ZipEncoding, CharsetAccessor { + + private static final char REPLACEMENT = '?'; + private static final byte[] REPLACEMENT_BYTES = { (byte) REPLACEMENT }; + private static final String REPLACEMENT_STRING = String.valueOf(REPLACEMENT); + private static final char[] HEX_CHARS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + private static ByteBuffer encodeFully(final CharsetEncoder enc, final CharBuffer cb, final ByteBuffer out) { + ByteBuffer o = out; + while (cb.hasRemaining()) { + final CoderResult result = enc.encode(cb, o, false); + if (result.isOverflow()) { + final int increment = estimateIncrementalEncodingSize(enc, cb.remaining()); + o = ZipEncodingHelper.growBufferBy(o, increment); + } + } + return o; + } + private static CharBuffer encodeSurrogate(final CharBuffer cb, final char c) { + cb.position(0).limit(6); + cb.put('%'); + cb.put('U'); + + cb.put(HEX_CHARS[(c >> 12) & 0x0f]); + cb.put(HEX_CHARS[(c >> 8) & 0x0f]); + cb.put(HEX_CHARS[(c >> 4) & 0x0f]); + cb.put(HEX_CHARS[c & 0x0f]); + cb.flip(); + return cb; + } + + + /** + * Estimate the size needed for remaining characters + * + * @param enc encoder to use for estimates + * @param charCount number of characters remaining + * @return estimated size in bytes. + */ + private static int estimateIncrementalEncodingSize(final CharsetEncoder enc, final int charCount) { + return (int) Math.ceil(charCount * enc.averageBytesPerChar()); + } + + /** + * Estimate the initial encoded size (in bytes) for a character buffer. + *

+ * The estimate assumes that one character consumes uses the maximum length encoding, + * whilst the rest use an average size encoding. This accounts for any BOM for UTF-16, at + * the expense of a couple of extra bytes for UTF-8 encoded ASCII. + *

+ * + * @param enc encoder to use for estimates + * @param charChount number of characters in string + * @return estimated size in bytes. + */ + private static int estimateInitialBufferSize(final CharsetEncoder enc, final int charChount) { + final float first = enc.maxBytesPerChar(); + final float rest = (charChount - 1) * enc.averageBytesPerChar(); + return (int) Math.ceil(first + rest); + } + + private final Charset charset; + + private final boolean useReplacement; + + /** + * Construct an NioZipEncoding using the given charset. + * @param charset The character set to use. + * @param useReplacement should invalid characters be replaced, or reported. + */ + NioZipEncoding(final Charset charset, final boolean useReplacement) { + this.charset = charset; + this.useReplacement = useReplacement; + } + + /** + * @see ZipEncoding#canEncode(String) + */ + @Override + public boolean canEncode(final String name) { + final CharsetEncoder enc = newEncoder(); + + return enc.canEncode(name); + } + + /** + * @see + * ZipEncoding#decode(byte[]) + */ + @Override + public String decode(final byte[] data) throws IOException { + return newDecoder() + .decode(ByteBuffer.wrap(data)).toString(); + } + + /** + * @see ZipEncoding#encode(String) + */ + @Override + public ByteBuffer encode(final String name) { + final CharsetEncoder enc = newEncoder(); + + final CharBuffer cb = CharBuffer.wrap(name); + CharBuffer tmp = null; + ByteBuffer out = ByteBuffer.allocate(estimateInitialBufferSize(enc, cb.remaining())); + + while (cb.hasRemaining()) { + final CoderResult res = enc.encode(cb, out, false); + + if (res.isUnmappable() || res.isMalformed()) { + + // write the unmappable characters in utf-16 + // pseudo-URL encoding style to ByteBuffer. + + final int spaceForSurrogate = estimateIncrementalEncodingSize(enc, 6 * res.length()); + if (spaceForSurrogate > out.remaining()) { + // if the destination buffer isn't over sized, assume that the presence of one + // unmappable character makes it likely that there will be more. Find all the + // un-encoded characters and allocate space based on those estimates. + int charCount = 0; + for (int i = cb.position() ; i < cb.limit(); i++) { + charCount += !enc.canEncode(cb.get(i)) ? 6 : 1; + } + final int totalExtraSpace = estimateIncrementalEncodingSize(enc, charCount); + out = ZipEncodingHelper.growBufferBy(out, totalExtraSpace - out.remaining()); + } + if (tmp == null) { + tmp = CharBuffer.allocate(6); + } + for (int i = 0; i < res.length(); ++i) { + out = encodeFully(enc, encodeSurrogate(tmp, cb.get()), out); + } + + } else if (res.isOverflow()) { + final int increment = estimateIncrementalEncodingSize(enc, cb.remaining()); + out = ZipEncodingHelper.growBufferBy(out, increment); + + } else if (res.isUnderflow() || res.isError()) { + break; + } + } + // tell the encoder we are done + enc.encode(cb, out, true); + // may have caused underflow, but that's been ignored traditionally + + out.limit(out.position()); + out.rewind(); + return out; + } + + @Override + public Charset getCharset() { + return charset; + } + + private CharsetDecoder newDecoder() { + if (!useReplacement) { + return this.charset.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + } + return charset.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .replaceWith(REPLACEMENT_STRING); + } + + private CharsetEncoder newEncoder() { + if (useReplacement) { + return charset.newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .replaceWith(REPLACEMENT_BYTES); + } + return charset.newEncoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ResourceAlignmentExtraField.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ResourceAlignmentExtraField.java new file mode 100644 index 0000000000..867e822831 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ResourceAlignmentExtraField.java @@ -0,0 +1,147 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + + +import java.util.zip.ZipException; + +/** + * An extra field who's sole purpose is to align and pad the local file header + * so that the entry's data starts at a certain position. + * + *

The padding content of the padding is ignored and not retained + * when reading a padding field.

+ * + *

This enables Commons Compress to create "aligned" archives + * similar to Android's zipalign command line tool.

+ * + * @since 1.14 + * @see "https://developer.android.com/studio/command-line/zipalign.html" + * @see ZipArchiveEntry#setAlignment + */ +public class ResourceAlignmentExtraField implements ZipExtraField { + + /** + * Extra field id used for storing alignment and padding. + */ + public static final ZipShort ID = new ZipShort(0xa11e); + + public static final int BASE_SIZE = 2; + + private static final int ALLOW_METHOD_MESSAGE_CHANGE_FLAG = 0x8000; + + private short alignment; + + private boolean allowMethodChange; + + private int padding; + + public ResourceAlignmentExtraField() { + } + + public ResourceAlignmentExtraField(final int alignment) { + this(alignment, false); + } + + public ResourceAlignmentExtraField(final int alignment, final boolean allowMethodChange) { + this(alignment, allowMethodChange, 0); + } + + public ResourceAlignmentExtraField(final int alignment, final boolean allowMethodChange, final int padding) { + if (alignment < 0 || alignment > 0x7fff) { + throw new IllegalArgumentException("Alignment must be between 0 and 0x7fff, was: " + alignment); + } + if (padding < 0) { + throw new IllegalArgumentException("Padding must not be negative, was: " + padding); + } + this.alignment = (short) alignment; + this.allowMethodChange = allowMethodChange; + this.padding = padding; + } + + /** + * Indicates whether method change is allowed when re-compressing the ZIP file. + * + * @return + * true if method change is allowed, false otherwise. + */ + public boolean allowMethodChange() { + return allowMethodChange; + } + + /** + * Gets requested alignment. + * + * @return + * requested alignment. + */ + public short getAlignment() { + return alignment; + } + + @Override + public byte[] getCentralDirectoryData() { + return ZipShort.getBytes(alignment | (allowMethodChange ? ALLOW_METHOD_MESSAGE_CHANGE_FLAG : 0)); + } + + @Override + public ZipShort getCentralDirectoryLength() { + return new ZipShort(BASE_SIZE); + } + + @Override + public ZipShort getHeaderId() { + return ID; + } + + @Override + public byte[] getLocalFileDataData() { + final byte[] content = new byte[BASE_SIZE + padding]; + ZipShort.putShort(alignment | (allowMethodChange ? ALLOW_METHOD_MESSAGE_CHANGE_FLAG : 0), + content, 0); + return content; + } + + @Override + public ZipShort getLocalFileDataLength() { + return new ZipShort(BASE_SIZE + padding); + } + + @Override + public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, final int length) throws ZipException { + if (length < BASE_SIZE) { + throw new ZipException("Too short content for ResourceAlignmentExtraField (0xa11e): " + length); + } + final int alignmentValue = ZipShort.getValue(buffer, offset); + this.alignment = (short) (alignmentValue & (ALLOW_METHOD_MESSAGE_CHANGE_FLAG - 1)); + this.allowMethodChange = (alignmentValue & ALLOW_METHOD_MESSAGE_CHANGE_FLAG) != 0; + } + + @Override + public void parseFromLocalFileData(final byte[] buffer, final int offset, final int length) throws ZipException { + parseFromCentralDirectoryData(buffer, offset, length); + this.padding = length - BASE_SIZE; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterStatistics.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterStatistics.java new file mode 100644 index 0000000000..d63a2229b0 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterStatistics.java @@ -0,0 +1,62 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * Provides information about a scatter compression run. + * + * @since 1.10 + */ +public class ScatterStatistics { + private final long compressionElapsed; + private final long mergingElapsed; + + ScatterStatistics(final long compressionElapsed, final long mergingElapsed) { + this.compressionElapsed = compressionElapsed; + this.mergingElapsed = mergingElapsed; + } + + /** + * The number of milliseconds elapsed in the parallel compression phase + * @return The number of milliseconds elapsed + */ + public long getCompressionElapsed() { + return compressionElapsed; + } + + /** + * The number of milliseconds elapsed in merging the results of the parallel compression, the IO phase + * @return The number of milliseconds elapsed + */ + public long getMergingElapsed() { + return mergingElapsed; + } + + @Override + public String toString() { + return "compressionElapsed=" + compressionElapsed + "ms, mergingElapsed=" + mergingElapsed + "ms"; + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterZipOutputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterZipOutputStream.java new file mode 100644 index 0000000000..3b173b64bb --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ScatterZipOutputStream.java @@ -0,0 +1,184 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import org.readium.r2.shared.util.archive.channel.compress.parallel.ScatterGatherBackingStore; +import org.readium.r2.shared.util.archive.channel.compress.utils.BoundedInputStream; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * A zip output stream that is optimized for multi-threaded scatter/gather construction of zip files. + *

+ * The internal data format of the entries used by this class are entirely private to this class + * and are not part of any public api whatsoever. + *

+ *

It is possible to extend this class to support different kinds of backing storage, the default + * implementation only supports file-based backing. + *

+ * Thread safety: This class supports multiple threads. But the "writeTo" method must be called + * by the thread that originally created the {@link ZipArchiveEntry}. + * + * @since 1.10 + */ +public class ScatterZipOutputStream implements Closeable { + private static class CompressedEntry { + final ZipArchiveEntryRequest zipArchiveEntryRequest; + final long crc; + final long compressedSize; + final long size; + + public CompressedEntry(final ZipArchiveEntryRequest zipArchiveEntryRequest, final long crc, final long compressedSize, final long size) { + this.zipArchiveEntryRequest = zipArchiveEntryRequest; + this.crc = crc; + this.compressedSize = compressedSize; + this.size = size; + } + + /** + * Update the original {@link ZipArchiveEntry} with sizes/crc + * Do not use this methods from threads that did not create the instance itself ! + * @return the zipArchiveEntry that is basis for this request + */ + + public ZipArchiveEntry transferToArchiveEntry(){ + final ZipArchiveEntry entry = zipArchiveEntryRequest.getZipArchiveEntry(); + entry.setCompressedSize(compressedSize); + entry.setSize(size); + entry.setCrc(crc); + entry.setMethod(zipArchiveEntryRequest.getMethod()); + return entry; + } + } + public static class ZipEntryWriter implements Closeable { + private final Iterator itemsIterator; + private final InputStream itemsIteratorData; + + public ZipEntryWriter(final ScatterZipOutputStream scatter) throws IOException { + scatter.backingStore.closeForWriting(); + itemsIterator = scatter.items.iterator(); + itemsIteratorData = scatter.backingStore.getInputStream(); + } + + @Override + public void close() throws IOException { + if (itemsIteratorData != null) { + itemsIteratorData.close(); + } + } + + public void writeNextZipEntry(final ZipArchiveOutputStream target) throws IOException { + final CompressedEntry compressedEntry = itemsIterator.next(); + try (final BoundedInputStream rawStream = new BoundedInputStream(itemsIteratorData, compressedEntry.compressedSize)) { + target.addRawArchiveEntry(compressedEntry.transferToArchiveEntry(), rawStream); + } + } + } + + private final Queue items = new ConcurrentLinkedQueue<>(); + + private final ScatterGatherBackingStore backingStore; + + private final StreamCompressor streamCompressor; + + private final AtomicBoolean isClosed = new AtomicBoolean(); + + private ZipEntryWriter zipEntryWriter; + + public ScatterZipOutputStream(final ScatterGatherBackingStore backingStore, + final StreamCompressor streamCompressor) { + this.backingStore = backingStore; + this.streamCompressor = streamCompressor; + } + + /** + * Add an archive entry to this scatter stream. + * + * @param zipArchiveEntryRequest The entry to write. + * @throws IOException If writing fails + */ + public void addArchiveEntry(final ZipArchiveEntryRequest zipArchiveEntryRequest) throws IOException { + try (final InputStream payloadStream = zipArchiveEntryRequest.getPayloadStream()) { + streamCompressor.deflate(payloadStream, zipArchiveEntryRequest.getMethod()); + } + items.add(new CompressedEntry(zipArchiveEntryRequest, streamCompressor.getCrc32(), + streamCompressor.getBytesWrittenForLastEntry(), streamCompressor.getBytesRead())); + } + + /** + * Closes this stream, freeing all resources involved in the creation of this stream. + * @throws IOException If closing fails + */ + @Override + public void close() throws IOException { + if (!isClosed.compareAndSet(false, true)) { + return; + } + try { + if (zipEntryWriter != null) { + zipEntryWriter.close(); + } + backingStore.close(); + } finally { + streamCompressor.close(); + } + } + + /** + * Write the contents of this scatter stream to a target archive. + * + * @param target The archive to receive the contents of this {@link ScatterZipOutputStream}. + * @throws IOException If writing fails + * @see #zipEntryWriter() + */ + public void writeTo(final ZipArchiveOutputStream target) throws IOException { + backingStore.closeForWriting(); + try (final InputStream data = backingStore.getInputStream()) { + for (final CompressedEntry compressedEntry : items) { + try (final BoundedInputStream rawStream = new BoundedInputStream(data, + compressedEntry.compressedSize)) { + target.addRawArchiveEntry(compressedEntry.transferToArchiveEntry(), rawStream); + } + } + } + } + + /** + * Get a zip entry writer for this scatter stream. + * @throws IOException If getting scatter stream input stream + * @return the ZipEntryWriter created on first call of the method + */ + public ZipEntryWriter zipEntryWriter() throws IOException { + if (zipEntryWriter == null) { + zipEntryWriter = new ZipEntryWriter(this); + } + return zipEntryWriter; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/StreamCompressor.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/StreamCompressor.java new file mode 100644 index 0000000000..585d1b7608 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/StreamCompressor.java @@ -0,0 +1,346 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel; +import org.readium.r2.shared.util.archive.channel.compress.parallel.ScatterGatherBackingStore; + +import java.io.Closeable; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.util.zip.CRC32; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; + +/** + * Encapsulates a {@link Deflater} and crc calculator, handling multiple types of output streams. + * Currently {@link java.util.zip.ZipEntry#DEFLATED} and {@link java.util.zip.ZipEntry#STORED} are the only + * supported compression methods. + * + * @since 1.10 + */ +public abstract class StreamCompressor implements Closeable { + + private static final class DataOutputCompressor extends StreamCompressor { + private final DataOutput raf; + + public DataOutputCompressor(final Deflater deflater, final DataOutput raf) { + super(deflater); + this.raf = raf; + } + + @Override + protected void writeOut(final byte[] data, final int offset, final int length) + throws IOException { + raf.write(data, offset, length); + } + } + + private static final class OutputStreamCompressor extends StreamCompressor { + private final OutputStream os; + + public OutputStreamCompressor(final Deflater deflater, final OutputStream os) { + super(deflater); + this.os = os; + } + + @Override + protected void writeOut(final byte[] data, final int offset, final int length) + throws IOException { + os.write(data, offset, length); + } + } + + private static final class ScatterGatherBackingStoreCompressor extends StreamCompressor { + private final ScatterGatherBackingStore bs; + + public ScatterGatherBackingStoreCompressor(final Deflater deflater, final ScatterGatherBackingStore bs) { + super(deflater); + this.bs = bs; + } + + @Override + protected void writeOut(final byte[] data, final int offset, final int length) + throws IOException { + bs.writeOut(data, offset, length); + } + } + + private static final class SeekableByteChannelCompressor extends StreamCompressor { + private final SeekableByteChannel channel; + + public SeekableByteChannelCompressor(final Deflater deflater, + final SeekableByteChannel channel) { + super(deflater); + this.channel = channel; + } + + @Override + protected void writeOut(final byte[] data, final int offset, final int length) + throws IOException { + channel.write(ByteBuffer.wrap(data, offset, length)); + } + } + /* + * Apparently Deflater.setInput gets slowed down a lot on Sun JVMs + * when it gets handed a really big buffer. See + * https://issues.apache.org/bugzilla/show_bug.cgi?id=45396 + * + * Using a buffer size of 8 kB proved to be a good compromise + */ + private static final int DEFLATER_BLOCK_SIZE = 8192; + private static final int BUFFER_SIZE = 4096; + + /** + * Create a stream compressor with the given compression level. + * + * @param os The DataOutput to receive output + * @param deflater The deflater to use for the compressor + * @return A stream compressor + */ + static StreamCompressor create(final DataOutput os, final Deflater deflater) { + return new DataOutputCompressor(deflater, os); + } + /** + * Create a stream compressor with the given compression level. + * + * @param compressionLevel The {@link Deflater} compression level + * @param bs The ScatterGatherBackingStore to receive output + * @return A stream compressor + */ + public static StreamCompressor create(final int compressionLevel, final ScatterGatherBackingStore bs) { + final Deflater deflater = new Deflater(compressionLevel, true); + return new ScatterGatherBackingStoreCompressor(deflater, bs); + } + /** + * Create a stream compressor with the default compression level. + * + * @param os The stream to receive output + * @return A stream compressor + */ + static StreamCompressor create(final OutputStream os) { + return create(os, new Deflater(Deflater.DEFAULT_COMPRESSION, true)); + } + + /** + * Create a stream compressor with the given compression level. + * + * @param os The stream to receive output + * @param deflater The deflater to use + * @return A stream compressor + */ + static StreamCompressor create(final OutputStream os, final Deflater deflater) { + return new OutputStreamCompressor(deflater, os); + } + + /** + * Create a stream compressor with the default compression level. + * + * @param bs The ScatterGatherBackingStore to receive output + * @return A stream compressor + */ + public static StreamCompressor create(final ScatterGatherBackingStore bs) { + return create(Deflater.DEFAULT_COMPRESSION, bs); + } + + /** + * Create a stream compressor with the given compression level. + * + * @param os The SeekableByteChannel to receive output + * @param deflater The deflater to use for the compressor + * @return A stream compressor + * @since 1.13 + */ + static StreamCompressor create(final SeekableByteChannel os, final Deflater deflater) { + return new SeekableByteChannelCompressor(deflater, os); + } + + private final Deflater def; + + private final CRC32 crc = new CRC32(); + + private long writtenToOutputStreamForLastEntry; + + private long sourcePayloadLength; + + private long totalWrittenToOutputStream; + + private final byte[] outputBuffer = new byte[BUFFER_SIZE]; + + private final byte[] readerBuf = new byte[BUFFER_SIZE]; + + StreamCompressor(final Deflater deflater) { + this.def = deflater; + } + + + @Override + public void close() throws IOException { + def.end(); + } + + void deflate() throws IOException { + final int len = def.deflate(outputBuffer, 0, outputBuffer.length); + if (len > 0) { + writeCounted(outputBuffer, 0, len); + } + } + + + /** + * Deflate the given source using the supplied compression method + * + * @param source The source to compress + * @param method The #ZipArchiveEntry compression method + * @throws IOException When failures happen + */ + + public void deflate(final InputStream source, final int method) throws IOException { + reset(); + int length; + + while ((length = source.read(readerBuf, 0, readerBuf.length)) >= 0) { + write(readerBuf, 0, length, method); + } + if (method == ZipEntry.DEFLATED) { + flushDeflater(); + } + } + + private void deflateUntilInputIsNeeded() throws IOException { + while (!def.needsInput()) { + deflate(); + } + } + + void flushDeflater() throws IOException { + def.finish(); + while (!def.finished()) { + deflate(); + } + } + + /** + * Return the number of bytes read from the source stream + * + * @return The number of bytes read, never negative + */ + public long getBytesRead() { + return sourcePayloadLength; + } + + /** + * The number of bytes written to the output for the last entry + * + * @return The number of bytes, never negative + */ + public long getBytesWrittenForLastEntry() { + return writtenToOutputStreamForLastEntry; + } + + /** + * The crc32 of the last deflated file + * + * @return the crc32 + */ + + public long getCrc32() { + return crc.getValue(); + } + + /** + * The total number of bytes written to the output for all files + * + * @return The number of bytes, never negative + */ + public long getTotalBytesWritten() { + return totalWrittenToOutputStream; + } + + void reset() { + crc.reset(); + def.reset(); + sourcePayloadLength = 0; + writtenToOutputStreamForLastEntry = 0; + } + + /** + * Writes bytes to ZIP entry. + * + * @param b the byte array to write + * @param offset the start position to write from + * @param length the number of bytes to write + * @param method the comrpession method to use + * @return the number of bytes written to the stream this time + * @throws IOException on error + */ + long write(final byte[] b, final int offset, final int length, final int method) throws IOException { + final long current = writtenToOutputStreamForLastEntry; + crc.update(b, offset, length); + if (method == ZipEntry.DEFLATED) { + writeDeflated(b, offset, length); + } else { + writeCounted(b, offset, length); + } + sourcePayloadLength += length; + return writtenToOutputStreamForLastEntry - current; + } + + public void writeCounted(final byte[] data) throws IOException { + writeCounted(data, 0, data.length); + } + + public void writeCounted(final byte[] data, final int offset, final int length) throws IOException { + writeOut(data, offset, length); + writtenToOutputStreamForLastEntry += length; + totalWrittenToOutputStream += length; + } + + private void writeDeflated(final byte[] b, final int offset, final int length) + throws IOException { + if (length > 0 && !def.finished()) { + if (length <= DEFLATER_BLOCK_SIZE) { + def.setInput(b, offset, length); + deflateUntilInputIsNeeded(); + } else { + final int fullblocks = length / DEFLATER_BLOCK_SIZE; + for (int i = 0; i < fullblocks; i++) { + def.setInput(b, offset + i * DEFLATER_BLOCK_SIZE, + DEFLATER_BLOCK_SIZE); + deflateUntilInputIsNeeded(); + } + final int done = fullblocks * DEFLATER_BLOCK_SIZE; + if (done < length) { + def.setInput(b, offset + done, length - done); + deflateUntilInputIsNeeded(); + } + } + } + } + + protected abstract void writeOut(byte[] data, int offset, int length) throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodeCommentExtraField.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodeCommentExtraField.java new file mode 100644 index 0000000000..dc736812ea --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodeCommentExtraField.java @@ -0,0 +1,76 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * Info-ZIP Unicode Comment Extra Field (0x6375): + * + *

Stores the UTF-8 version of the file comment as stored in the + * central directory header.

+ * + * @see PKWARE + * APPNOTE.TXT, section 4.6.8 + * + * @NotThreadSafe super-class is not thread-safe + */ +public class UnicodeCommentExtraField extends AbstractUnicodeExtraField { + + public static final ZipShort UCOM_ID = new ZipShort(0x6375); + + public UnicodeCommentExtraField () { + } + + /** + * Assemble as unicode comment extension from the comment given as + * text as well as the bytes actually written to the archive. + * + * @param comment The file comment + * @param bytes the bytes actually written to the archive + */ + public UnicodeCommentExtraField(final String comment, final byte[] bytes) { + super(comment, bytes); + } + + /** + * Assemble as unicode comment extension from the name given as + * text as well as the encoded bytes actually written to the archive. + * + * @param text The file name + * @param bytes the bytes actually written to the archive + * @param off The offset of the encoded comment in {@code bytes}. + * @param len The length of the encoded comment or comment in + * {@code bytes}. + */ + public UnicodeCommentExtraField(final String text, final byte[] bytes, final int off, + final int len) { + super(text, bytes, off, len); + } + + @Override + public ZipShort getHeaderId() { + return UCOM_ID; + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodePathExtraField.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodePathExtraField.java new file mode 100644 index 0000000000..20ce6e7298 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnicodePathExtraField.java @@ -0,0 +1,74 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * Info-ZIP Unicode Path Extra Field (0x7075): + * + *

Stores the UTF-8 version of the file name field as stored in the + * local header and central directory header.

+ * + * @see PKWARE + * APPNOTE.TXT, section 4.6.9 + * + * @NotThreadSafe super-class is not thread-safe + */ +public class UnicodePathExtraField extends AbstractUnicodeExtraField { + + public static final ZipShort UPATH_ID = new ZipShort(0x7075); + + public UnicodePathExtraField () { + } + + /** + * Assemble as unicode path extension from the name given as + * text as well as the encoded bytes actually written to the archive. + * + * @param name The file name + * @param bytes the bytes actually written to the archive + */ + public UnicodePathExtraField(final String name, final byte[] bytes) { + super(name, bytes); + } + + /** + * Assemble as unicode path extension from the name given as + * text as well as the encoded bytes actually written to the archive. + * + * @param text The file name + * @param bytes the bytes actually written to the archive + * @param off The offset of the encoded file name in {@code bytes}. + * @param len The length of the encoded file name or comment in + * {@code bytes}. + */ + public UnicodePathExtraField(final String text, final byte[] bytes, final int off, final int len) { + super(text, bytes, off, len); + } + + @Override + public ZipShort getHeaderId() { + return UPATH_ID; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnixStat.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnixStat.java new file mode 100644 index 0000000000..91950544ff --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnixStat.java @@ -0,0 +1,74 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * Constants from stat.h on Unix systems. + */ +// CheckStyle:InterfaceIsTypeCheck OFF - backward compatible +public interface UnixStat { + + /** + * Bits used for permissions (and sticky bit) + */ + int PERM_MASK = 07777; + /** + * Bits used to indicate the file system object type. + * @since 1.14 + */ + int FILE_TYPE_FLAG = 0170000; + /** + * Indicates symbolic links. + */ + int LINK_FLAG = 0120000; + /** + * Indicates plain files. + */ + int FILE_FLAG = 0100000; + /** + * Indicates directories. + */ + int DIR_FLAG = 040000; + + // ---------------------------------------------------------- + // somewhat arbitrary choices that are quite common for shared + // installations + // ----------------------------------------------------------- + + /** + * Default permissions for symbolic links. + */ + int DEFAULT_LINK_PERM = 0777; + + /** + * Default permissions for directories. + */ + int DEFAULT_DIR_PERM = 0755; + + /** + * Default permissions for plain files. + */ + int DEFAULT_FILE_PERM = 0644; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldBehavior.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldBehavior.java new file mode 100644 index 0000000000..73b5a7a4b0 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldBehavior.java @@ -0,0 +1,56 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.zip.ZipException; + +/** + * Handles extra field data that doesn't follow the recommended + * pattern for extra fields with a two-byte key and a two-byte length. + * + * @since 1.19 + */ +public interface UnparseableExtraFieldBehavior { + /** + * Decides what to do with extra field data that doesn't follow the recommended pattern. + * + * @param data the array of extra field data + * @param off offset into data where the unparseable data starts + * @param len the length of unparseable data + * @param local whether the extra field data stems from the local + * file header. If this is false then the data is part if the + * central directory header extra data. + * @param claimedLength length of the extra field claimed by the + * third and forth byte if it did follow the recommended pattern + * + * @return null if the data should be ignored or an extra field + * implementation that represents the data + * @throws ZipException if an error occurs or unparseable extra + * fields must not be accepted + */ + ZipExtraField onUnparseableExtraField(byte[] data, int off, int len, boolean local, + int claimedLength) throws ZipException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldData.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldData.java new file mode 100644 index 0000000000..1f9a75b749 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnparseableExtraFieldData.java @@ -0,0 +1,127 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.Arrays; + +/** + * Wrapper for extra field data that doesn't conform to the recommended format of header-tag + size + data. + * + *

The header-id is artificial (and not listed as a known ID in APPNOTE.TXT). Since it isn't used anywhere + * except to satisfy the ZipExtraField contract it shouldn't matter anyway.

+ * + * @since 1.1 + * @NotThreadSafe + */ +public final class UnparseableExtraFieldData implements ZipExtraField { + private static final ZipShort HEADER_ID = new ZipShort(0xACC1); + + private byte[] localFileData; + private byte[] centralDirectoryData; + + /** + * The actual data to put into central directory. + * + * @return The CentralDirectoryData value + */ + @Override + public byte[] getCentralDirectoryData() { + return centralDirectoryData == null + ? getLocalFileDataData() : ZipUtil.copy(centralDirectoryData); + } + + /** + * Length of the complete extra field in the central directory. + * + * @return The CentralDirectoryLength value + */ + @Override + public ZipShort getCentralDirectoryLength() { + return centralDirectoryData == null + ? getLocalFileDataLength() + : new ZipShort(centralDirectoryData.length); + } + + /** + * The Header-ID. + * + * @return a completely arbitrary value that should be ignored. + */ + @Override + public ZipShort getHeaderId() { + return HEADER_ID; + } + + /** + * The actual data to put into local file data. + * + * @return The LocalFileDataData value + */ + @Override + public byte[] getLocalFileDataData() { + return ZipUtil.copy(localFileData); + } + + /** + * Length of the complete extra field in the local file data. + * + * @return The LocalFileDataLength value + */ + @Override + public ZipShort getLocalFileDataLength() { + return new ZipShort(localFileData == null ? 0 : localFileData.length); + } + + /** + * Populate data from this array as if it was in central directory data. + * + * @param buffer the buffer to read data from + * @param offset offset into buffer to read data + * @param length the length of data + */ + @Override + public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, + final int length) { + centralDirectoryData = Arrays.copyOfRange(buffer, offset, offset + length); + if (localFileData == null) { + parseFromLocalFileData(buffer, offset, length); + } + } + + /** + * Populate data from this array as if it was in local file data. + * + * @param buffer the buffer to read data from + * @param offset offset into buffer to read data + * @param length the length of data + */ + @Override + public void parseFromLocalFileData(final byte[] buffer, final int offset, final int length) { + localFileData = Arrays.copyOfRange(buffer, offset, offset + length); + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnrecognizedExtraField.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnrecognizedExtraField.java new file mode 100644 index 0000000000..5b768a425f --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnrecognizedExtraField.java @@ -0,0 +1,160 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.Arrays; + +/** + * Simple placeholder for all those extra fields we don't want to deal + * with. + * + *

Assumes local file data and central directory entries are + * identical - unless told the opposite.

+ * @NotThreadSafe + */ +public class UnrecognizedExtraField implements ZipExtraField { + + /** + * The Header-ID. + */ + private ZipShort headerId; + + /** + * Extra field data in local file data - without + * Header-ID or length specifier. + */ + private byte[] localData; + + /** + * Extra field data in central directory - without + * Header-ID or length specifier. + */ + private byte[] centralData; + + /** + * Get the central data. + * @return the central data if present, else return the local file data + */ + @Override + public byte[] getCentralDirectoryData() { + if (centralData != null) { + return ZipUtil.copy(centralData); + } + return getLocalFileDataData(); + } + + /** + * Get the central data length. + * If there is no central data, get the local file data length. + * @return the central data length + */ + @Override + public ZipShort getCentralDirectoryLength() { + if (centralData != null) { + return new ZipShort(centralData.length); + } + return getLocalFileDataLength(); + } + + /** + * Get the header id. + * @return the header id + */ + @Override + public ZipShort getHeaderId() { + return headerId; + } + + /** + * Get the local data. + * @return the local data + */ + @Override + public byte[] getLocalFileDataData() { + return ZipUtil.copy(localData); + } + + /** + * Get the length of the local data. + * @return the length of the local data + */ + @Override + public ZipShort getLocalFileDataLength() { + return new ZipShort(localData != null ? localData.length : 0); + } + + /** + * @param data the array of bytes. + * @param offset the source location in the data array. + * @param length the number of bytes to use in the data array. + * @see ZipExtraField#parseFromCentralDirectoryData(byte[], int, int) + */ + @Override + public void parseFromCentralDirectoryData(final byte[] data, final int offset, + final int length) { + final byte[] tmp = Arrays.copyOfRange(data, offset, offset + length); + setCentralDirectoryData(tmp); + if (localData == null) { + setLocalFileDataData(tmp); + } + } + + /** + * @param data the array of bytes. + * @param offset the source location in the data array. + * @param length the number of bytes to use in the data array. + * @see ZipExtraField#parseFromLocalFileData(byte[], int, int) + */ + @Override + public void parseFromLocalFileData(final byte[] data, final int offset, final int length) { + setLocalFileDataData(Arrays.copyOfRange(data, offset, offset + length)); + } + + /** + * Set the extra field data in central directory. + * @param data the data to use + */ + public void setCentralDirectoryData(final byte[] data) { + centralData = ZipUtil.copy(data); + } + + /** + * Set the header id. + * @param headerId the header id to use + */ + public void setHeaderId(final ZipShort headerId) { + this.headerId = headerId; + } + + /** + * Set the extra field data in the local file data - + * without Header-ID or length specifier. + * @param data the field data to use + */ + public void setLocalFileDataData(final byte[] data) { + localData = ZipUtil.copy(data); + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnsupportedZipFeatureException.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnsupportedZipFeatureException.java new file mode 100644 index 0000000000..b581c80f17 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/UnsupportedZipFeatureException.java @@ -0,0 +1,141 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.Serializable; +import java.util.zip.ZipException; + +/** + * Exception thrown when attempting to read or write data for a zip + * entry that uses ZIP features not supported by this library. + * @since 1.1 + */ +public class UnsupportedZipFeatureException extends ZipException { + + /** + * ZIP Features that may or may not be supported. + * @since 1.1 + */ + public static class Feature implements Serializable { + + private static final long serialVersionUID = 4112582948775420359L; + /** + * The entry is encrypted. + */ + public static final Feature ENCRYPTION = new Feature("encryption"); + /** + * The entry used an unsupported compression method. + */ + public static final Feature METHOD = new Feature("compression method"); + /** + * The entry uses a data descriptor. + */ + public static final Feature DATA_DESCRIPTOR = new Feature("data descriptor"); + /** + * The archive uses splitting or spanning. + * @since 1.5 + */ + public static final Feature SPLITTING = new Feature("splitting"); + /** + * The archive contains entries with unknown compressed size + * for a compression method that doesn't support detection of + * the end of the compressed stream. + * @since 1.16 + */ + public static final Feature UNKNOWN_COMPRESSED_SIZE = new Feature("unknown compressed size"); + + private final String name; + + private Feature(final String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } + private static final long serialVersionUID = 20161219L; + private final Feature reason; + + private transient final ZipArchiveEntry entry; + + /** + * Creates an exception when the whole archive uses an unsupported + * feature. + * + * @param reason the feature that is not supported + * @since 1.5 + */ + public UnsupportedZipFeatureException(final Feature reason) { + super("Unsupported feature " + reason + " used in archive."); + this.reason = reason; + this.entry = null; + } + + /** + * Creates an exception. + * @param reason the feature that is not supported + * @param entry the entry using the feature + */ + public UnsupportedZipFeatureException(final Feature reason, + final ZipArchiveEntry entry) { + super("Unsupported feature " + reason + " used in entry " + + entry.getName()); + this.reason = reason; + this.entry = entry; + } + + /** + * Creates an exception for archives that use an unsupported + * compression algorithm. + * @param method the method that is not supported + * @param entry the entry using the feature + * @since 1.5 + */ + public UnsupportedZipFeatureException(final ZipMethod method, + final ZipArchiveEntry entry) { + super("Unsupported compression method " + entry.getMethod() + + " (" + method.name() + ") used in entry " + entry.getName()); + this.reason = Feature.METHOD; + this.entry = entry; + } + + /** + * The entry using the unsupported feature. + * @return The entry using the unsupported feature. + */ + public ZipArchiveEntry getEntry() { + return entry; + } + + /** + * The unsupported feature that has been used. + * @return The unsupported feature that has been used. + */ + public Feature getFeature() { + return reason; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64ExtendedInformationExtraField.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64ExtendedInformationExtraField.java new file mode 100644 index 0000000000..539dc73580 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64ExtendedInformationExtraField.java @@ -0,0 +1,346 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.DWORD; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.WORD; + +import org.readium.r2.shared.util.archive.channel.compress.utils.ByteUtils; + +import java.util.zip.ZipException; + +/** + * Holds size and other extended information for entries that use Zip64 + * features. + * + *

Currently Commons Compress doesn't support encrypting the + * central directory so the note in APPNOTE.TXT about masking doesn't + * apply.

+ * + *

The implementation relies on data being read from the local file + * header and assumes that both size values are always present.

+ * + * @see PKWARE + * APPNOTE.TXT, section 4.5.3 + * + * @since 1.2 + * @NotThreadSafe + */ +public class Zip64ExtendedInformationExtraField implements ZipExtraField { + + static final ZipShort HEADER_ID = new ZipShort(0x0001); + + private static final String LFH_MUST_HAVE_BOTH_SIZES_MSG = + "Zip64 extended information must contain" + + " both size values in the local file header."; + private ZipEightByteInteger size, compressedSize, relativeHeaderOffset; + private ZipLong diskStart; + + /** + * Stored in {@link #parseFromCentralDirectoryData + * parseFromCentralDirectoryData} so it can be reused when ZipFile + * calls {@link #reparseCentralDirectoryData + * reparseCentralDirectoryData}. + * + *

Not used for anything else

+ * + * @since 1.3 + */ + private byte[] rawCentralDirectoryData; + + /** + * This constructor should only be used by the code that reads + * archives inside of Commons Compress. + */ + public Zip64ExtendedInformationExtraField() { } + + /** + * Creates an extra field based on the original and compressed size. + * + * @param size the entry's original size + * @param compressedSize the entry's compressed size + * + * @throws IllegalArgumentException if size or compressedSize is null + */ + public Zip64ExtendedInformationExtraField(final ZipEightByteInteger size, + final ZipEightByteInteger compressedSize) { + this(size, compressedSize, null, null); + } + + /** + * Creates an extra field based on all four possible values. + * + * @param size the entry's original size + * @param compressedSize the entry's compressed size + * @param relativeHeaderOffset the entry's offset + * @param diskStart the disk start + * + * @throws IllegalArgumentException if size or compressedSize is null + */ + public Zip64ExtendedInformationExtraField(final ZipEightByteInteger size, + final ZipEightByteInteger compressedSize, + final ZipEightByteInteger relativeHeaderOffset, + final ZipLong diskStart) { + this.size = size; + this.compressedSize = compressedSize; + this.relativeHeaderOffset = relativeHeaderOffset; + this.diskStart = diskStart; + } + + private int addSizes(final byte[] data) { + int off = 0; + if (size != null) { + System.arraycopy(size.getBytes(), 0, data, 0, DWORD); + off += DWORD; + } + if (compressedSize != null) { + System.arraycopy(compressedSize.getBytes(), 0, data, off, DWORD); + off += DWORD; + } + return off; + } + + @Override + public byte[] getCentralDirectoryData() { + final byte[] data = new byte[getCentralDirectoryLength().getValue()]; + int off = addSizes(data); + if (relativeHeaderOffset != null) { + System.arraycopy(relativeHeaderOffset.getBytes(), 0, data, off, DWORD); + off += DWORD; + } + if (diskStart != null) { + System.arraycopy(diskStart.getBytes(), 0, data, off, WORD); + off += WORD; // NOSONAR - assignment as documentation + } + return data; + } + + @Override + public ZipShort getCentralDirectoryLength() { + return new ZipShort((size != null ? DWORD : 0) + + (compressedSize != null ? DWORD : 0) + + (relativeHeaderOffset != null ? DWORD : 0) + + (diskStart != null ? WORD : 0)); + } + + /** + * The compressed size stored in this extra field. + * @return The compressed size stored in this extra field. + */ + public ZipEightByteInteger getCompressedSize() { + return compressedSize; + } + + /** + * The disk start number stored in this extra field. + * @return The disk start number stored in this extra field. + */ + public ZipLong getDiskStartNumber() { + return diskStart; + } + + @Override + public ZipShort getHeaderId() { + return HEADER_ID; + } + + @Override + public byte[] getLocalFileDataData() { + if (size != null || compressedSize != null) { + if (size == null || compressedSize == null) { + throw new IllegalArgumentException(LFH_MUST_HAVE_BOTH_SIZES_MSG); + } + final byte[] data = new byte[2 * DWORD]; + addSizes(data); + return data; + } + return ByteUtils.EMPTY_BYTE_ARRAY; + } + + @Override + public ZipShort getLocalFileDataLength() { + return new ZipShort(size != null ? 2 * DWORD : 0); + } + + /** + * The relative header offset stored in this extra field. + * @return The relative header offset stored in this extra field. + */ + public ZipEightByteInteger getRelativeHeaderOffset() { + return relativeHeaderOffset; + } + + /** + * The uncompressed size stored in this extra field. + * @return The uncompressed size stored in this extra field. + */ + public ZipEightByteInteger getSize() { + return size; + } + + @Override + public void parseFromCentralDirectoryData(final byte[] buffer, int offset, + final int length) + throws ZipException { + // store for processing in reparseCentralDirectoryData + rawCentralDirectoryData = new byte[length]; + System.arraycopy(buffer, offset, rawCentralDirectoryData, 0, length); + + // if there is no size information in here, we are screwed and + // can only hope things will get resolved by LFH data later + // But there are some cases that can be detected + // * all data is there + // * length == 24 -> both sizes and offset + // * length % 8 == 4 -> at least we can identify the diskStart field + if (length >= 3 * DWORD + WORD) { + parseFromLocalFileData(buffer, offset, length); + } else if (length == 3 * DWORD) { + size = new ZipEightByteInteger(buffer, offset); + offset += DWORD; + compressedSize = new ZipEightByteInteger(buffer, offset); + offset += DWORD; + relativeHeaderOffset = new ZipEightByteInteger(buffer, offset); + } else if (length % DWORD == WORD) { + diskStart = new ZipLong(buffer, offset + length - WORD); + } + } + + @Override + public void parseFromLocalFileData(final byte[] buffer, int offset, final int length) + throws ZipException { + if (length == 0) { + // no local file data at all, may happen if an archive + // only holds a ZIP64 extended information extra field + // inside the central directory but not inside the local + // file header + return; + } + if (length < 2 * DWORD) { + throw new ZipException(LFH_MUST_HAVE_BOTH_SIZES_MSG); + } + size = new ZipEightByteInteger(buffer, offset); + offset += DWORD; + compressedSize = new ZipEightByteInteger(buffer, offset); + offset += DWORD; + int remaining = length - 2 * DWORD; + if (remaining >= DWORD) { + relativeHeaderOffset = new ZipEightByteInteger(buffer, offset); + offset += DWORD; + remaining -= DWORD; + } + if (remaining >= WORD) { + diskStart = new ZipLong(buffer, offset); + offset += WORD; // NOSONAR - assignment as documentation + remaining -= WORD; // NOSONAR - assignment as documentation + } + } + + /** + * Parses the raw bytes read from the central directory extra + * field with knowledge which fields are expected to be there. + * + *

All four fields inside the zip64 extended information extra + * field are optional and must only be present if their corresponding + * entry inside the central directory contains the correct magic + * value.

+ * + * @param hasUncompressedSize flag to read from central directory + * @param hasCompressedSize flag to read from central directory + * @param hasRelativeHeaderOffset flag to read from central directory + * @param hasDiskStart flag to read from central directory + * @throws ZipException on error + */ + public void reparseCentralDirectoryData(final boolean hasUncompressedSize, + final boolean hasCompressedSize, + final boolean hasRelativeHeaderOffset, + final boolean hasDiskStart) + throws ZipException { + if (rawCentralDirectoryData != null) { + final int expectedLength = (hasUncompressedSize ? DWORD : 0) + + (hasCompressedSize ? DWORD : 0) + + (hasRelativeHeaderOffset ? DWORD : 0) + + (hasDiskStart ? WORD : 0); + if (rawCentralDirectoryData.length < expectedLength) { + throw new ZipException("Central directory zip64 extended" + + " information extra field's length" + + " doesn't match central directory" + + " data. Expected length " + + expectedLength + " but is " + + rawCentralDirectoryData.length); + } + int offset = 0; + if (hasUncompressedSize) { + size = new ZipEightByteInteger(rawCentralDirectoryData, offset); + offset += DWORD; + } + if (hasCompressedSize) { + compressedSize = new ZipEightByteInteger(rawCentralDirectoryData, + offset); + offset += DWORD; + } + if (hasRelativeHeaderOffset) { + relativeHeaderOffset = + new ZipEightByteInteger(rawCentralDirectoryData, offset); + offset += DWORD; + } + if (hasDiskStart) { + diskStart = new ZipLong(rawCentralDirectoryData, offset); + offset += WORD; // NOSONAR - assignment as documentation + } + } + } + + /** + * The uncompressed size stored in this extra field. + * @param compressedSize The uncompressed size stored in this extra field. + */ + public void setCompressedSize(final ZipEightByteInteger compressedSize) { + this.compressedSize = compressedSize; + } + + /** + * The disk start number stored in this extra field. + * @param ds The disk start number stored in this extra field. + */ + public void setDiskStartNumber(final ZipLong ds) { + diskStart = ds; + } + + /** + * The relative header offset stored in this extra field. + * @param rho The relative header offset stored in this extra field. + */ + public void setRelativeHeaderOffset(final ZipEightByteInteger rho) { + relativeHeaderOffset = rho; + } + + /** + * The uncompressed size stored in this extra field. + * @param size The uncompressed size stored in this extra field. + */ + public void setSize(final ZipEightByteInteger size) { + this.size = size; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64Mode.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64Mode.java new file mode 100644 index 0000000000..60c1603973 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64Mode.java @@ -0,0 +1,63 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * The different modes {@link ZipArchiveOutputStream} can operate in. + * + * @see ZipArchiveOutputStream#setUseZip64 + * + * @since 1.3 + */ +public enum Zip64Mode { + /** + * Use Zip64 extensions for all entries, even if it is clear it is + * not required. + */ + Always, + /** + * Don't use Zip64 extensions for any entries. + * + *

This will cause a {@link Zip64RequiredException} to be + * thrown if {@link ZipArchiveOutputStream} detects it needs Zip64 + * support.

+ */ + Never, + /** + * Use Zip64 extensions for all entries where they are required, + * don't use them for entries that clearly don't require them. + */ + AsNeeded, + /** + * Always use Zip64 extensions for LFH and central directory as + * {@link Zip64Mode#Always} did, and at the meantime encode + * the relative offset of LFH and disk number start as needed in + * CFH as {@link Zip64Mode#AsNeeded} did. + *

+ * This is a compromise for some libraries including 7z and + * Expand-Archive Powershell utility(and likely Excel). + */ + AlwaysWithCompatibility +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64RequiredException.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64RequiredException.java new file mode 100644 index 0000000000..a8fa086f7f --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/Zip64RequiredException.java @@ -0,0 +1,67 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.zip.ZipException; + +/** + * Exception thrown when attempting to write data that requires Zip64 + * support to an archive and {@link ZipArchiveOutputStream#setUseZip64 + * UseZip64} has been set to {@link Zip64Mode#Never Never}. + * @since 1.3 + */ +public class Zip64RequiredException extends ZipException { + + private static final long serialVersionUID = 20110809L; + + static final String NUMBER_OF_THIS_DISK_TOO_BIG_MESSAGE = + "Number of the disk of End Of Central Directory exceeds the limit of 65535."; + + static final String NUMBER_OF_THE_DISK_OF_CENTRAL_DIRECTORY_TOO_BIG_MESSAGE = + "Number of the disk with the start of Central Directory exceeds the limit of 65535."; + + static final String TOO_MANY_ENTRIES_ON_THIS_DISK_MESSAGE = + "Number of entries on this disk exceeds the limit of 65535."; + + static final String SIZE_OF_CENTRAL_DIRECTORY_TOO_BIG_MESSAGE = + "The size of the entire central directory exceeds the limit of 4GByte."; + + static final String ARCHIVE_TOO_BIG_MESSAGE = + "Archive's size exceeds the limit of 4GByte."; + + static final String TOO_MANY_ENTRIES_MESSAGE = + "Archive contains more than 65535 entries."; + + /** + * Helper to format "entry too big" messages. + */ + static String getEntryTooBigMessage(final ZipArchiveEntry ze) { + return ze.getName() + "'s size exceeds the limit of 4GByte."; + } + + public Zip64RequiredException(final String reason) { + super(reason); + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntry.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntry.java new file mode 100644 index 0000000000..0bf633d423 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntry.java @@ -0,0 +1,1230 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import org.readium.r2.shared.util.archive.channel.compress.archivers.ArchiveEntry; +import org.readium.r2.shared.util.archive.channel.compress.archivers.EntryStreamOffsets; +import org.readium.r2.shared.util.archive.channel.compress.utils.ByteUtils; + +import java.io.File; +import java.nio.file.attribute.FileTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.zip.ZipException; + +/** + * Extension that adds better handling of extra fields and provides + * access to the internal and external file attributes. + * + *

The extra data is expected to follow the recommendation of + * APPNOTE.TXT:

+ *
    + *
  • the extra byte array consists of a sequence of extra fields
  • + *
  • each extra fields starts by a two byte header id followed by + * a two byte sequence holding the length of the remainder of + * data.
  • + *
+ * + *

Any extra data that cannot be parsed by the rules above will be + * consumed as "unparseable" extra data and treated differently by the + * methods of this class. Versions prior to Apache Commons Compress + * 1.1 would have thrown an exception if any attempt was made to read + * or write extra data not conforming to the recommendation.

+ * + * @NotThreadSafe + */ +public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEntry, EntryStreamOffsets { + + /** + * Indicates how the comment of this entry has been determined. + * @since 1.16 + */ + public enum CommentSource { + /** + * The comment has been read from the archive using the encoding + * of the archive specified when creating the {@link ZipFile} (defaults to the + * platform's default encoding). + */ + COMMENT, + /** + * The comment has been read from an {@link UnicodeCommentExtraField + * Unicode Extra Field}. + */ + UNICODE_EXTRA_FIELD + } + + /** + * How to try to parse the extra fields. + * + *

Configures the behavior for:

+ *
    + *
  • What shall happen if the extra field content doesn't + * follow the recommended pattern of two-byte id followed by a + * two-byte length?
  • + *
  • What shall happen if an extra field is generally supported + * by Commons Compress but its content cannot be parsed + * correctly? This may for example happen if the archive is + * corrupt, it triggers a bug in Commons Compress or the extra + * field uses a version not (yet) supported by Commons + * Compress.
  • + *
+ * + * @since 1.19 + */ + public enum ExtraFieldParsingMode implements ExtraFieldParsingBehavior { + /** + * Try to parse as many extra fields as possible and wrap + * unknown extra fields as well as supported extra fields that + * cannot be parsed in {@link UnrecognizedExtraField}. + * + *

Wrap extra data that doesn't follow the recommended + * pattern in an {@link UnparseableExtraFieldData} + * instance.

+ * + *

This is the default behavior starting with Commons Compress 1.19.

+ */ + BEST_EFFORT(ExtraFieldUtils.UnparseableExtraField.READ) { + @Override + public ZipExtraField fill(final ZipExtraField field, final byte[] data, final int off, final int len, final boolean local) { + return fillAndMakeUnrecognizedOnError(field, data, off, len, local); + } + }, + /** + * Try to parse as many extra fields as possible and wrap + * unknown extra fields in {@link UnrecognizedExtraField}. + * + *

Wrap extra data that doesn't follow the recommended + * pattern in an {@link UnparseableExtraFieldData} + * instance.

+ * + *

Throw an exception if an extra field that is generally + * supported cannot be parsed.

+ * + *

This used to be the default behavior prior to Commons + * Compress 1.19.

+ */ + STRICT_FOR_KNOW_EXTRA_FIELDS(ExtraFieldUtils.UnparseableExtraField.READ), + /** + * Try to parse as many extra fields as possible and wrap + * unknown extra fields as well as supported extra fields that + * cannot be parsed in {@link UnrecognizedExtraField}. + * + *

Ignore extra data that doesn't follow the recommended + * pattern.

+ */ + ONLY_PARSEABLE_LENIENT(ExtraFieldUtils.UnparseableExtraField.SKIP) { + @Override + public ZipExtraField fill(final ZipExtraField field, final byte[] data, final int off, final int len, final boolean local) { + return fillAndMakeUnrecognizedOnError(field, data, off, len, local); + } + }, + /** + * Try to parse as many extra fields as possible and wrap + * unknown extra fields in {@link UnrecognizedExtraField}. + * + *

Ignore extra data that doesn't follow the recommended + * pattern.

+ * + *

Throw an exception if an extra field that is generally + * supported cannot be parsed.

+ */ + ONLY_PARSEABLE_STRICT(ExtraFieldUtils.UnparseableExtraField.SKIP), + /** + * Throw an exception if any of the recognized extra fields + * cannot be parsed or any extra field violates the + * recommended pattern. + */ + DRACONIC(ExtraFieldUtils.UnparseableExtraField.THROW); + + private static ZipExtraField fillAndMakeUnrecognizedOnError(final ZipExtraField field, final byte[] data, final int off, + final int len, final boolean local) { + try { + return ExtraFieldUtils.fillExtraField(field, data, off, len, local); + } catch (final ZipException ex) { + final UnrecognizedExtraField u = new UnrecognizedExtraField(); + u.setHeaderId(field.getHeaderId()); + if (local) { + u.setLocalFileDataData(Arrays.copyOfRange(data, off, off + len)); + } else { + u.setCentralDirectoryData(Arrays.copyOfRange(data, off, off + len)); + } + return u; + } + } + + private final ExtraFieldUtils.UnparseableExtraField onUnparseableData; + + ExtraFieldParsingMode(final ExtraFieldUtils.UnparseableExtraField onUnparseableData) { + this.onUnparseableData = onUnparseableData; + } + + @Override + public ZipExtraField createExtraField(final ZipShort headerId) + throws ZipException, InstantiationException, IllegalAccessException { + return ExtraFieldUtils.createExtraField(headerId); + } + + @Override + public ZipExtraField fill(final ZipExtraField field, final byte[] data, final int off, final int len, final boolean local) + throws ZipException { + return ExtraFieldUtils.fillExtraField(field, data, off, len, local); + } + + @Override + public ZipExtraField onUnparseableExtraField(final byte[] data, final int off, final int len, final boolean local, + final int claimedLength) throws ZipException { + return onUnparseableData.onUnparseableExtraField(data, off, len, local, claimedLength); + } + } + /** + * Indicates how the name of this entry has been determined. + * @since 1.16 + */ + public enum NameSource { + /** + * The name has been read from the archive using the encoding + * of the archive specified when creating the {@link ZipFile} (defaults to the + * platform's default encoding). + */ + NAME, + /** + * The name has been read from the archive and the archive + * specified the EFS flag which indicates the name has been + * encoded as UTF-8. + */ + NAME_WITH_EFS_FLAG, + /** + * The name has been read from an {@link UnicodePathExtraField + * Unicode Extra Field}. + */ + UNICODE_EXTRA_FIELD + } + static final ZipArchiveEntry[] EMPTY_ARRAY = {}; + public static final int PLATFORM_UNIX = 3; + public static final int PLATFORM_FAT = 0; + public static final int CRC_UNKNOWN = -1; + + private static final int SHORT_MASK = 0xFFFF; + + private static final int SHORT_SHIFT = 16; + + /** + * The {@link java.util.zip.ZipEntry} base class only supports + * the compression methods STORED and DEFLATED. We override the + * field so that any compression methods can be used. + *

+ * The default value -1 means that the method has not been specified. + * + * @see COMPRESS-93 + */ + private int method = ZipMethod.UNKNOWN_CODE; + /** + * The {@link java.util.zip.ZipEntry#setSize} method in the base + * class throws an IllegalArgumentException if the size is bigger + * than 2GB for Java versions < 7 and even in Java 7+ if the + * implementation in java.util.zip doesn't support Zip64 itself + * (it is an optional feature). + * + *

We need to keep our own size information for Zip64 support.

+ */ + private long size = SIZE_UNKNOWN; + private int internalAttributes; + private int versionRequired; + private int versionMadeBy; + private int platform = PLATFORM_FAT; + private int rawFlag; + private long externalAttributes; + private int alignment; + private ZipExtraField[] extraFields; + private UnparseableExtraFieldData unparseableExtra; + private String name; + private byte[] rawName; + private GeneralPurposeBit gpb = new GeneralPurposeBit(); + private long localHeaderOffset = OFFSET_UNKNOWN; + private long dataOffset = OFFSET_UNKNOWN; + private boolean isStreamContiguous; + private NameSource nameSource = NameSource.NAME; + + private CommentSource commentSource = CommentSource.COMMENT; + + private long diskNumberStart; + + private long time = -1; + + /** + */ + protected ZipArchiveEntry() { + this(""); + } + + /** + * Creates a new ZIP entry taking some information from the given + * file and using the provided name. + * + *

The name will be adjusted to end with a forward slash "/" if + * the file is a directory. If the file is not a directory a + * potential trailing forward slash will be stripped from the + * entry name.

+ * @param inputFile file to create the entry from + * @param entryName name of the entry + */ + public ZipArchiveEntry(final File inputFile, final String entryName) { + this(inputFile.isDirectory() && !entryName.endsWith("/") ? + entryName + "/" : entryName); + if (inputFile.isFile()){ + setSize(inputFile.length()); + } + setTime(inputFile.lastModified()); + } + + /** + * Creates a new ZIP entry with fields taken from the specified ZIP entry. + * + *

Assumes the entry represents a directory if and only if the + * name ends with a forward slash "/".

+ * + * @param entry the entry to get fields from + * @throws ZipException on error + */ + public ZipArchiveEntry(final java.util.zip.ZipEntry entry) throws ZipException { + super(entry); + setName(entry.getName()); + final byte[] extra = entry.getExtra(); + if (extra != null) { + setExtraFields(ExtraFieldUtils.parse(extra, true, ExtraFieldParsingMode.BEST_EFFORT)); + } else { + // initializes extra data to an empty byte array + setExtra(); + } + setMethod(entry.getMethod()); + this.size = entry.getSize(); + } + + /** + * Creates a new ZIP entry with the specified name. + * + *

Assumes the entry represents a directory if and only if the + * name ends with a forward slash "/".

+ * + * @param name the name of the entry + */ + public ZipArchiveEntry(final String name) { + super(name); + setName(name); + } + + /** + * Creates a new ZIP entry with fields taken from the specified ZIP entry. + * + *

Assumes the entry represents a directory if and only if the + * name ends with a forward slash "/".

+ * + * @param entry the entry to get fields from + * @throws ZipException on error + */ + public ZipArchiveEntry(final ZipArchiveEntry entry) throws ZipException { + this((java.util.zip.ZipEntry) entry); + setInternalAttributes(entry.getInternalAttributes()); + setExternalAttributes(entry.getExternalAttributes()); + setExtraFields(entry.getAllExtraFieldsNoCopy()); + setPlatform(entry.getPlatform()); + final GeneralPurposeBit other = entry.getGeneralPurposeBit(); + setGeneralPurposeBit(other == null ? null : + (GeneralPurposeBit) other.clone()); + } + + /** + * Adds an extra field - replacing an already present extra field + * of the same type. + * + *

The new extra field will be the first one.

+ * @param ze an extra field + */ + public void addAsFirstExtraField(final ZipExtraField ze) { + if (ze instanceof UnparseableExtraFieldData) { + unparseableExtra = (UnparseableExtraFieldData) ze; + } else { + if (getExtraField(ze.getHeaderId()) != null) { + internalRemoveExtraField(ze.getHeaderId()); + } + final ZipExtraField[] copy = extraFields; + final int newLen = extraFields != null ? extraFields.length + 1 : 1; + extraFields = new ZipExtraField[newLen]; + extraFields[0] = ze; + if (copy != null){ + System.arraycopy(copy, 0, extraFields, 1, extraFields.length - 1); + } + } + setExtra(); + } + + /** + * Adds an extra field - replacing an already present extra field + * of the same type. + * + *

If no extra field of the same type exists, the field will be + * added as last field.

+ * @param ze an extra field + */ + public void addExtraField(final ZipExtraField ze) { + internalAddExtraField(ze); + setExtra(); + } + + /** + * Overwrite clone. + * @return a cloned copy of this ZipArchiveEntry + */ + @Override + public Object clone() { + final ZipArchiveEntry e = (ZipArchiveEntry) super.clone(); + + e.setInternalAttributes(getInternalAttributes()); + e.setExternalAttributes(getExternalAttributes()); + e.setExtraFields(getAllExtraFieldsNoCopy()); + return e; + } + + private ZipExtraField[] copyOf(final ZipExtraField[] src, final int length) { + return Arrays.copyOf(src, length); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final ZipArchiveEntry other = (ZipArchiveEntry) obj; + final String myName = getName(); + final String otherName = other.getName(); + if (!Objects.equals(myName, otherName)) { + return false; + } + String myComment = getComment(); + String otherComment = other.getComment(); + if (myComment == null) { + myComment = ""; + } + if (otherComment == null) { + otherComment = ""; + } + return myComment.equals(otherComment) + && getInternalAttributes() == other.getInternalAttributes() + && getPlatform() == other.getPlatform() + && getExternalAttributes() == other.getExternalAttributes() + && getMethod() == other.getMethod() + && getSize() == other.getSize() + && getCrc() == other.getCrc() + && getCompressedSize() == other.getCompressedSize() + && Arrays.equals(getCentralDirectoryExtra(), + other.getCentralDirectoryExtra()) + && Arrays.equals(getLocalFileDataExtra(), + other.getLocalFileDataExtra()) + && localHeaderOffset == other.localHeaderOffset + && dataOffset == other.dataOffset + && gpb.equals(other.gpb); + } + + private ZipExtraField findMatching(final ZipShort headerId, final List fs) { + for (ZipExtraField field: fs) { + if (headerId.equals(field.getHeaderId())) { + return field; + } + } + return null; + } + + private ZipExtraField findUnparseable(final List fs) { + for (ZipExtraField field: fs) { + if (field instanceof UnparseableExtraFieldData) { + return field; + } + } + return null; + } + + /** + * Gets currently configured alignment. + * + * @return + * alignment for this entry. + * @since 1.14 + */ + protected int getAlignment() { + return this.alignment; + } + + private ZipExtraField[] getAllExtraFields() { + final ZipExtraField[] allExtraFieldsNoCopy = getAllExtraFieldsNoCopy(); + return (allExtraFieldsNoCopy == extraFields) ? copyOf(allExtraFieldsNoCopy, allExtraFieldsNoCopy.length) + : allExtraFieldsNoCopy; + } + + /** + * Get all extra fields, including unparseable ones. + * @return An array of all extra fields. Not necessarily a copy of internal data structures, hence private method + */ + private ZipExtraField[] getAllExtraFieldsNoCopy() { + if (extraFields == null) { + return getUnparseableOnly(); + } + return unparseableExtra != null ? getMergedFields() : extraFields; + } + + /** + * Retrieves the extra data for the central directory. + * @return the central directory extra data + */ + public byte[] getCentralDirectoryExtra() { + return ExtraFieldUtils.mergeCentralDirectoryData(getAllExtraFieldsNoCopy()); + } + + /** + * The source of the comment field value. + * @return source of the comment field value + * @since 1.16 + */ + public CommentSource getCommentSource() { + return commentSource; + } + + @Override + public long getDataOffset() { + return dataOffset; + } + + /** + * The number of the split segment this entry starts at. + * + * @return the number of the split segment this entry starts at. + * @since 1.20 + */ + public long getDiskNumberStart() { + return diskNumberStart; + } + + /** + * Retrieves the external file attributes. + * + * @return the external file attributes + */ + public long getExternalAttributes() { + return externalAttributes; + } + + /** + * Looks up an extra field by its header id. + * + * @param type the header id + * @return null if no such field exists. + */ + public ZipExtraField getExtraField(final ZipShort type) { + if (extraFields != null) { + for (final ZipExtraField extraField : extraFields) { + if (type.equals(extraField.getHeaderId())) { + return extraField; + } + } + } + return null; + } + + /** + * Retrieves all extra fields that have been parsed successfully. + * + * @return an array of the extra fields + */ + public ZipExtraField[] getExtraFields() { + return getParseableExtraFields(); + } + + /** + * Retrieves extra fields. + * @param includeUnparseable whether to also return unparseable + * extra fields as {@link UnparseableExtraFieldData} if such data + * exists. + * @return an array of the extra fields + * + * @since 1.1 + */ + public ZipExtraField[] getExtraFields(final boolean includeUnparseable) { + return includeUnparseable ? + getAllExtraFields() : + getParseableExtraFields(); + } + + /** + * Retrieves extra fields. + * @param parsingBehavior controls parsing of extra fields. + * @return an array of the extra fields + * + * @throws ZipException if parsing fails, can not happen if {@code + * parsingBehavior} is {@link ExtraFieldParsingMode#BEST_EFFORT}. + * + * @since 1.19 + */ + public ZipExtraField[] getExtraFields(final ExtraFieldParsingBehavior parsingBehavior) + throws ZipException { + if (parsingBehavior == ExtraFieldParsingMode.BEST_EFFORT) { + return getExtraFields(true); + } + if (parsingBehavior == ExtraFieldParsingMode.ONLY_PARSEABLE_LENIENT) { + return getExtraFields(false); + } + final byte[] local = getExtra(); + final List localFields = new ArrayList<>(Arrays.asList(ExtraFieldUtils.parse(local, true, + parsingBehavior))); + final byte[] central = getCentralDirectoryExtra(); + final List centralFields = new ArrayList<>(Arrays.asList(ExtraFieldUtils.parse(central, false, + parsingBehavior))); + final List merged = new ArrayList<>(); + for (final ZipExtraField l : localFields) { + ZipExtraField c; + if (l instanceof UnparseableExtraFieldData) { + c = findUnparseable(centralFields); + } else { + c = findMatching(l.getHeaderId(), centralFields); + } + if (c != null) { + final byte[] cd = c.getCentralDirectoryData(); + if (cd != null && cd.length > 0) { + l.parseFromCentralDirectoryData(cd, 0, cd.length); + } + centralFields.remove(c); + } + merged.add(l); + } + merged.addAll(centralFields); + return merged.toArray(ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY); + } + + /** + * The "general purpose bit" field. + * @return the general purpose bit + * @since 1.1 + */ + public GeneralPurposeBit getGeneralPurposeBit() { + return gpb; + } + + /** + * Retrieves the internal file attributes. + * + * @return the internal file attributes + */ + public int getInternalAttributes() { + return internalAttributes; + } + + /** + * Wraps {@link java.util.zip.ZipEntry#getTime} with a {@link Date} as the + * entry's last modified date. + * + *

Changes to the implementation of {@link java.util.zip.ZipEntry#getTime} + * leak through and the returned value may depend on your local + * time zone as well as your version of Java.

+ */ + @Override + public Date getLastModifiedDate() { + return new Date(getTime()); + } + + /** + * Retrieves the extra data for the local file data. + * @return the extra data for local file + */ + public byte[] getLocalFileDataExtra() { + final byte[] extra = getExtra(); + return extra != null ? extra : ByteUtils.EMPTY_BYTE_ARRAY; + } + + protected long getLocalHeaderOffset() { + return this.localHeaderOffset; + } + + private ZipExtraField[] getMergedFields() { + final ZipExtraField[] zipExtraFields = copyOf(extraFields, extraFields.length + 1); + zipExtraFields[extraFields.length] = unparseableExtra; + return zipExtraFields; + } + + /** + * Returns the compression method of this entry, or -1 if the + * compression method has not been specified. + * + * @return compression method + * + * @since 1.1 + */ + @Override + public int getMethod() { + return method; + } + + /** + * Get the name of the entry. + * + *

This method returns the raw name as it is stored inside of the archive.

+ * + * @return the entry name + */ + @Override + public String getName() { + return name == null ? super.getName() : name; + } + + /** + * The source of the name field value. + * @return source of the name field value + * @since 1.16 + */ + public NameSource getNameSource() { + return nameSource; + } + + private ZipExtraField[] getParseableExtraFields() { + final ZipExtraField[] parseableExtraFields = getParseableExtraFieldsNoCopy(); + return (parseableExtraFields == extraFields) ? copyOf(parseableExtraFields, parseableExtraFields.length) + : parseableExtraFields; + } + + private ZipExtraField[] getParseableExtraFieldsNoCopy() { + if (extraFields == null) { + return ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY; + } + return extraFields; + } + + /** + * Platform specification to put into the "version made + * by" part of the central file header. + * + * @return PLATFORM_FAT unless {@link #setUnixMode setUnixMode} + * has been called, in which case PLATFORM_UNIX will be returned. + */ + public int getPlatform() { + return platform; + } + + /** + * The content of the flags field. + * @return content of the flags field + * @since 1.11 + */ + public int getRawFlag() { + return rawFlag; + } + + /** + * Returns the raw bytes that made up the name before it has been + * converted using the configured or guessed encoding. + * + *

This method will return null if this instance has not been + * read from an archive.

+ * + * @return the raw name bytes + * @since 1.2 + */ + public byte[] getRawName() { + if (rawName != null) { + return Arrays.copyOf(rawName, rawName.length); + } + return null; + } + + /** + * Gets the uncompressed size of the entry data. + * + * @return the entry size + */ + @Override + public long getSize() { + return size; + } + + /** + * {@inheritDoc} + * + *

Override to work around bug JDK-8130914

+ * + * @return The last modification time of the entry in milliseconds + * since the epoch, or -1 if not specified + * + * @see #setTime(long) + * @see #setLastModifiedTime(FileTime) + */ + @Override + public long getTime() { + return time != -1 ? time : super.getTime(); + } + + /** + * Unix permission. + * @return the unix permissions + */ + public int getUnixMode() { + return platform != PLATFORM_UNIX ? 0 : + (int) ((getExternalAttributes() >> SHORT_SHIFT) & SHORT_MASK); + } + + private ZipExtraField[] getUnparseableOnly() { + return unparseableExtra == null ? ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY : new ZipExtraField[] { unparseableExtra }; + } + + /** + * The "version made by" field. + * @return "version made by" field + * @since 1.11 + */ + public int getVersionMadeBy() { + return versionMadeBy; + } + + /** + * The "version required to expand" field. + * @return "version required to expand" field + * @since 1.11 + */ + public int getVersionRequired() { + return versionRequired; + } + + /** + * Get the hash code of the entry. + * This uses the name as the hash code. + * @return a hash code. + */ + @Override + public int hashCode() { + // this method has severe consequences on performance. We cannot rely + // on the super.hashCode() method since super.getName() always return + // the empty string in the current implementation (there's no setter) + // so it is basically draining the performance of a hashmap lookup + return getName().hashCode(); + } + + private void internalAddExtraField(final ZipExtraField ze) { + if (ze instanceof UnparseableExtraFieldData) { + unparseableExtra = (UnparseableExtraFieldData) ze; + } else if (extraFields == null) { + extraFields = new ZipExtraField[]{ze}; + } else { + if (getExtraField(ze.getHeaderId()) != null) { + internalRemoveExtraField(ze.getHeaderId()); + } + final ZipExtraField[] zipExtraFields = copyOf(extraFields, extraFields.length + 1); + zipExtraFields[zipExtraFields.length - 1] = ze; + extraFields = zipExtraFields; + } + } + + private void internalRemoveExtraField(final ZipShort type) { + if (extraFields == null) { + return; + } + final List newResult = new ArrayList<>(); + for (final ZipExtraField extraField : extraFields) { + if (!type.equals(extraField.getHeaderId())) { + newResult.add(extraField); + } + } + if (extraFields.length == newResult.size()) { + return; + } + extraFields = newResult.toArray(ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY); + } + + /** + * Is this entry a directory? + * @return true if the entry is a directory + */ + @Override + public boolean isDirectory() { + return getName().endsWith("/"); + } + + @Override + public boolean isStreamContiguous() { + return isStreamContiguous; + } + + /** + * Returns true if this entry represents a unix symlink, + * in which case the entry's content contains the target path + * for the symlink. + * + * @since 1.5 + * @return true if the entry represents a unix symlink, false otherwise. + */ + public boolean isUnixSymlink() { + return (getUnixMode() & UnixStat.FILE_TYPE_FLAG) == UnixStat.LINK_FLAG; + } + + /** + * If there are no extra fields, use the given fields as new extra + * data - otherwise merge the fields assuming the existing fields + * and the new fields stem from different locations inside the + * archive. + * @param f the extra fields to merge + * @param local whether the new fields originate from local data + */ + private void mergeExtraFields(final ZipExtraField[] f, final boolean local) { + if (extraFields == null) { + setExtraFields(f); + } else { + for (final ZipExtraField element : f) { + final ZipExtraField existing; + if (element instanceof UnparseableExtraFieldData) { + existing = unparseableExtra; + } else { + existing = getExtraField(element.getHeaderId()); + } + if (existing == null) { + internalAddExtraField(element); + } else { + final byte[] b = local ? element.getLocalFileDataData() + : element.getCentralDirectoryData(); + try { + if (local) { + existing.parseFromLocalFileData(b, 0, b.length); + } else { + existing.parseFromCentralDirectoryData(b, 0, b.length); + } + } catch (final ZipException ex) { + // emulate ExtraFieldParsingMode.fillAndMakeUnrecognizedOnError + final UnrecognizedExtraField u = new UnrecognizedExtraField(); + u.setHeaderId(existing.getHeaderId()); + if (local) { + u.setLocalFileDataData(b); + u.setCentralDirectoryData(existing.getCentralDirectoryData()); + } else { + u.setLocalFileDataData(existing.getLocalFileDataData()); + u.setCentralDirectoryData(b); + } + internalRemoveExtraField(existing.getHeaderId()); + internalAddExtraField(u); + } + } + } + setExtra(); + } + } + + /** + * Remove an extra field. + * @param type the type of extra field to remove + */ + public void removeExtraField(final ZipShort type) { + if (getExtraField(type) == null) { + throw new NoSuchElementException(); + } + internalRemoveExtraField(type); + setExtra(); + } + + /** + * Sets alignment for this entry. + * + * @param alignment + * requested alignment, 0 for default. + * @since 1.14 + */ + public void setAlignment(final int alignment) { + if ((alignment & (alignment - 1)) != 0 || alignment > 0xffff) { + throw new IllegalArgumentException("Invalid value for alignment, must be power of two and no bigger than " + + 0xffff + " but is " + alignment); + } + this.alignment = alignment; + } + + /** + * Sets the central directory part of extra fields. + * @param b an array of bytes to be parsed into extra fields + */ + public void setCentralDirectoryExtra(final byte[] b) { + try { + mergeExtraFields(ExtraFieldUtils.parse(b, false, ExtraFieldParsingMode.BEST_EFFORT), false); + } catch (final ZipException e) { + // actually this is not possible as of Commons Compress 1.19 + throw new IllegalArgumentException(e.getMessage(), e); // NOSONAR + } + } + + /** + * Sets the source of the comment field value. + * @param commentSource source of the comment field value + * @since 1.16 + */ + public void setCommentSource(final CommentSource commentSource) { + this.commentSource = commentSource; + } + + /* (non-Javadoc) + * @see Object#equals(Object) + */ + + /** + * Sets the data offset. + * + * @param dataOffset + * new value of data offset. + */ + protected void setDataOffset(final long dataOffset) { + this.dataOffset = dataOffset; + } + + /** + * The number of the split segment this entry starts at. + * + * @param diskNumberStart the number of the split segment this entry starts at. + * @since 1.20 + */ + public void setDiskNumberStart(final long diskNumberStart) { + this.diskNumberStart = diskNumberStart; + } + + /** + * Sets the external file attributes. + * @param value an {@code long} value + */ + public void setExternalAttributes(final long value) { + externalAttributes = value; + } + + /** + * Unfortunately {@link java.util.zip.ZipOutputStream} seems to + * access the extra data directly, so overriding getExtra doesn't + * help - we need to modify super's data directly and on every update. + */ + protected void setExtra() { + // ZipEntry will update the time fields here, so we need to reprocess them afterwards + super.setExtra(ExtraFieldUtils.mergeLocalFileDataData(getAllExtraFieldsNoCopy())); + } + + /** + * Parses the given bytes as extra field data and consumes any + * unparseable data as an {@link UnparseableExtraFieldData} + * instance. + * @param extra an array of bytes to be parsed into extra fields + * @throws RuntimeException if the bytes cannot be parsed + * @throws RuntimeException on error + */ + @Override + public void setExtra(final byte[] extra) throws RuntimeException { + try { + mergeExtraFields(ExtraFieldUtils.parse(extra, true, ExtraFieldParsingMode.BEST_EFFORT), true); + } catch (final ZipException e) { + // actually this is not possible as of Commons Compress 1.1 + throw new IllegalArgumentException("Error parsing extra fields for entry: " // NOSONAR + + getName() + " - " + e.getMessage(), e); + } + } + + /** + * Replaces all currently attached extra fields with the new array. + * @param fields an array of extra fields + */ + public void setExtraFields(final ZipExtraField[] fields) { + unparseableExtra = null; + final List newFields = new ArrayList<>(); + if (fields != null) { + for (final ZipExtraField field : fields) { + if (field instanceof UnparseableExtraFieldData) { + unparseableExtra = (UnparseableExtraFieldData) field; + } else { + newFields.add(field); + } + } + } + extraFields = newFields.toArray(ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY); + setExtra(); + } + + /** + * The "general purpose bit" field. + * @param b the general purpose bit + * @since 1.1 + */ + public void setGeneralPurposeBit(final GeneralPurposeBit b) { + gpb = b; + } + + /** + * Sets the internal file attributes. + * @param value an {@code int} value + */ + public void setInternalAttributes(final int value) { + internalAttributes = value; + } + + protected void setLocalHeaderOffset(final long localHeaderOffset) { + this.localHeaderOffset = localHeaderOffset; + } + + /** + * Sets the compression method of this entry. + * + * @param method compression method + * + * @since 1.t1 + */ + @Override + public void setMethod(final int method) { + if (method < 0) { + throw new IllegalArgumentException( + "ZIP compression method can not be negative: " + method); + } + this.method = method; + } + + /** + * Set the name of the entry. + * @param name the name to use + */ + protected void setName(String name) { + if (name != null && getPlatform() == PLATFORM_FAT + && !name.contains("/")) { + name = name.replace('\\', '/'); + } + this.name = name; + } + + /** + * Sets the name using the raw bytes and the string created from + * it by guessing or using the configured encoding. + * @param name the name to use created from the raw bytes using + * the guessed or configured encoding + * @param rawName the bytes originally read as name from the + * archive + * @since 1.2 + */ + protected void setName(final String name, final byte[] rawName) { + setName(name); + this.rawName = rawName; + } + + /** + * Sets the source of the name field value. + * @param nameSource source of the name field value + * @since 1.16 + */ + public void setNameSource(final NameSource nameSource) { + this.nameSource = nameSource; + } + + /** + * Set the platform (UNIX or FAT). + * @param platform an {@code int} value - 0 is FAT, 3 is UNIX + */ + protected void setPlatform(final int platform) { + this.platform = platform; + } + + /** + * Sets the content of the flags field. + * @param rawFlag content of the flags field + * @since 1.11 + */ + public void setRawFlag(final int rawFlag) { + this.rawFlag = rawFlag; + } + + /** + * Sets the uncompressed size of the entry data. + * @param size the uncompressed size in bytes + * @throws IllegalArgumentException if the specified size is less + * than 0 + */ + @Override + public void setSize(final long size) { + if (size < 0) { + throw new IllegalArgumentException("Invalid entry size"); + } + this.size = size; + } + + protected void setStreamContiguous(final boolean isStreamContiguous) { + this.isStreamContiguous = isStreamContiguous; + } + + /** + * + * {@inheritDoc} + * + *

Override to work around bug JDK-8130914

+ * + * @param time + * The last modification time of the entry in milliseconds + * since the epoch + * @see #getTime() + * @see #getLastModifiedTime() + */ + @Override + public void setTime(final long time) { + super.setTime(time); + this.time = time; + } + + /** + * Sets Unix permissions in a way that is understood by Info-Zip's + * unzip command. + * @param mode an {@code int} value + */ + public void setUnixMode(final int mode) { + // CheckStyle:MagicNumberCheck OFF - no point + setExternalAttributes((mode << SHORT_SHIFT) + // MS-DOS read-only attribute + | ((mode & 0200) == 0 ? 1 : 0) + // MS-DOS directory flag + | (isDirectory() ? 0x10 : 0)); + // CheckStyle:MagicNumberCheck ON + platform = PLATFORM_UNIX; + } + + /** + * Sets the "version made by" field. + * @param versionMadeBy "version made by" field + * @since 1.11 + */ + public void setVersionMadeBy(final int versionMadeBy) { + this.versionMadeBy = versionMadeBy; + } + + /** + * Sets the "version required to expand" field. + * @param versionRequired "version required to expand" field + * @since 1.11 + */ + public void setVersionRequired(final int versionRequired) { + this.versionRequired = versionRequired; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryPredicate.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryPredicate.java new file mode 100644 index 0000000000..8036f37b5c --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryPredicate.java @@ -0,0 +1,40 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * A predicate to test if a #ZipArchiveEntry matches a criteria. + * Some day this can extend java.util.function.Predicate + * + * @since 1.10 + */ +public interface ZipArchiveEntryPredicate { + /** + * Indicate if the given entry should be included in the operation + * @param zipArchiveEntry the entry to test + * @return true if the entry should be included + */ + boolean test(ZipArchiveEntry zipArchiveEntry); +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryRequest.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryRequest.java new file mode 100644 index 0000000000..e0b7d635b1 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveEntryRequest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import org.readium.r2.shared.util.archive.channel.compress.parallel.InputStreamSupplier; + +import java.io.InputStream; + +/** + * A Thread-safe representation of a ZipArchiveEntry that is used to add entries to parallel archives. + * + * @since 1.10 + */ +public class ZipArchiveEntryRequest { + /** + * Create a ZipArchiveEntryRequest + * @param zipArchiveEntry The entry to use + * @param payloadSupplier The payload that will be added to the zip entry. + * @return The newly created request + */ + public static ZipArchiveEntryRequest createZipArchiveEntryRequest(final ZipArchiveEntry zipArchiveEntry, final InputStreamSupplier payloadSupplier) { + return new ZipArchiveEntryRequest(zipArchiveEntry, payloadSupplier); + } + /* + The zipArchiveEntry is not thread safe, and cannot be safely accessed by the getters of this class. + It is safely accessible during the construction part of this class and also after the + thread pools have been shut down. + */ + private final ZipArchiveEntry zipArchiveEntry; + private final InputStreamSupplier payloadSupplier; + + + private final int method; + + private ZipArchiveEntryRequest(final ZipArchiveEntry zipArchiveEntry, final InputStreamSupplier payloadSupplier) { + // this constructor has "safe" access to all member variables on zipArchiveEntry + this.zipArchiveEntry = zipArchiveEntry; + this.payloadSupplier = payloadSupplier; + this.method = zipArchiveEntry.getMethod(); + } + + /** + * The compression method to use + * @return The compression method to use + */ + public int getMethod(){ + return method; + } + + /** + * The payload that will be added to this zip entry + * @return The input stream. + */ + public InputStream getPayloadStream() { + return payloadSupplier.get(); + } + + + /** + * Gets the underlying entry. Do not use this methods from threads that did not create the instance itself ! + * @return the zipArchiveEntry that is basis for this request + */ + ZipArchiveEntry getZipArchiveEntry() { + return zipArchiveEntry; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveOutputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveOutputStream.java new file mode 100644 index 0000000000..c73b04e124 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipArchiveOutputStream.java @@ -0,0 +1,1938 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.DATA_DESCRIPTOR_MIN_VERSION; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.DEFLATE_MIN_VERSION; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.DWORD; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.INITIAL_VERSION; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.SHORT; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.WORD; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.ZIP64_MAGIC; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.ZIP64_MAGIC_SHORT; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipConstants.ZIP64_MIN_VERSION; +import static org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipLong.putLong; + +import org.readium.r2.shared.util.archive.channel.compress.archivers.ArchiveEntry; +import org.readium.r2.shared.util.archive.channel.compress.archivers.ArchiveOutputStream; +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel; +import org.readium.r2.shared.util.archive.channel.compress.utils.ByteUtils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.util.Calendar; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.zip.Deflater; +import java.util.zip.ZipException; + +/** + * Reimplementation of {@link java.util.zip.ZipOutputStream + * java.util.zip.ZipOutputStream} that does handle the extended + * functionality of this package, especially internal/external file + * attributes and extra fields with different layouts for local file + * data and central directory entries. + * + *

This class will try to use {@link + * java.nio.channels.SeekableByteChannel} when it knows that the + * output is going to go to a file and no split archive shall be + * created.

+ * + *

If SeekableByteChannel cannot be used, this implementation will use + * a Data Descriptor to store size and CRC information for {@link + * #DEFLATED DEFLATED} entries, this means, you don't need to + * calculate them yourself. Unfortunately this is not possible for + * the {@link #STORED STORED} method, here setting the CRC and + * uncompressed size information is required before {@link + * #putArchiveEntry(ArchiveEntry)} can be called.

+ * + *

As of Apache Commons Compress 1.3 it transparently supports Zip64 + * extensions and thus individual entries and archives larger than 4 + * GB or with more than 65536 entries in most cases but explicit + * control is provided via {@link #setUseZip64}. If the stream can not + * use SeekableByteChannel and you try to write a ZipArchiveEntry of + * unknown size then Zip64 extensions will be disabled by default.

+ * + * @NotThreadSafe + */ +public class ZipArchiveOutputStream extends ArchiveOutputStream { + + /** + * Structure collecting information for the entry that is + * currently being written. + */ + private static final class CurrentEntry { + /** + * Current ZIP entry. + */ + private final ZipArchiveEntry entry; + /** + * Offset for CRC entry in the local file header data for the + * current entry starts here. + */ + private long localDataStart; + /** + * Data for local header data + */ + private long dataStart; + /** + * Number of bytes read for the current entry (can't rely on + * Deflater#getBytesRead) when using DEFLATED. + */ + private long bytesRead; + /** + * Whether current entry was the first one using ZIP64 features. + */ + private boolean causedUseOfZip64; + /** + * Whether write() has been called at all. + * + *

In order to create a valid archive {@link + * #closeArchiveEntry closeArchiveEntry} will write an empty + * array to get the CRC right if nothing has been written to + * the stream at all.

+ */ + private boolean hasWritten; + private CurrentEntry(final ZipArchiveEntry entry) { + this.entry = entry; + } + } + private static final class EntryMetaData { + private final long offset; + private final boolean usesDataDescriptor; + private EntryMetaData(final long offset, final boolean usesDataDescriptor) { + this.offset = offset; + this.usesDataDescriptor = usesDataDescriptor; + } + } + /** + * enum that represents the possible policies for creating Unicode + * extra fields. + */ + public static final class UnicodeExtraFieldPolicy { + /** + * Always create Unicode extra fields. + */ + public static final UnicodeExtraFieldPolicy ALWAYS = new UnicodeExtraFieldPolicy("always"); + /** + * Never create Unicode extra fields. + */ + public static final UnicodeExtraFieldPolicy NEVER = new UnicodeExtraFieldPolicy("never"); + /** + * Create Unicode extra fields for file names that cannot be + * encoded using the specified encoding. + */ + public static final UnicodeExtraFieldPolicy NOT_ENCODEABLE = + new UnicodeExtraFieldPolicy("not encodeable"); + + private final String name; + private UnicodeExtraFieldPolicy(final String n) { + name = n; + } + @Override + public String toString() { + return name; + } + } + static final int BUFFER_SIZE = 512; + private static final int LFH_SIG_OFFSET = 0; + private static final int LFH_VERSION_NEEDED_OFFSET = 4; + private static final int LFH_GPB_OFFSET = 6; + private static final int LFH_METHOD_OFFSET = 8; + private static final int LFH_TIME_OFFSET = 10; + private static final int LFH_CRC_OFFSET = 14; + private static final int LFH_COMPRESSED_SIZE_OFFSET = 18; + private static final int LFH_ORIGINAL_SIZE_OFFSET = 22; + private static final int LFH_FILENAME_LENGTH_OFFSET = 26; + private static final int LFH_EXTRA_LENGTH_OFFSET = 28; + private static final int LFH_FILENAME_OFFSET = 30; + private static final int CFH_SIG_OFFSET = 0; + private static final int CFH_VERSION_MADE_BY_OFFSET = 4; + private static final int CFH_VERSION_NEEDED_OFFSET = 6; + private static final int CFH_GPB_OFFSET = 8; + private static final int CFH_METHOD_OFFSET = 10; + private static final int CFH_TIME_OFFSET = 12; + private static final int CFH_CRC_OFFSET = 16; + private static final int CFH_COMPRESSED_SIZE_OFFSET = 20; + private static final int CFH_ORIGINAL_SIZE_OFFSET = 24; + private static final int CFH_FILENAME_LENGTH_OFFSET = 28; + private static final int CFH_EXTRA_LENGTH_OFFSET = 30; + private static final int CFH_COMMENT_LENGTH_OFFSET = 32; + private static final int CFH_DISK_NUMBER_OFFSET = 34; + private static final int CFH_INTERNAL_ATTRIBUTES_OFFSET = 36; + + private static final int CFH_EXTERNAL_ATTRIBUTES_OFFSET = 38; + + private static final int CFH_LFH_OFFSET = 42; + + private static final int CFH_FILENAME_OFFSET = 46; + + /** + * Compression method for deflated entries. + */ + public static final int DEFLATED = java.util.zip.ZipEntry.DEFLATED; + + /** + * Default compression level for deflated entries. + */ + public static final int DEFAULT_COMPRESSION = Deflater.DEFAULT_COMPRESSION; + + /** + * Compression method for stored entries. + */ + public static final int STORED = java.util.zip.ZipEntry.STORED; + + /** + * default encoding for file names and comment. + */ + static final String DEFAULT_ENCODING = ZipEncodingHelper.UTF8; + + /** + * General purpose flag, which indicates that file names are + * written in UTF-8. + * @deprecated use {@link GeneralPurposeBit#UFT8_NAMES_FLAG} instead + */ + @Deprecated + public static final int EFS_FLAG = GeneralPurposeBit.UFT8_NAMES_FLAG; + + /** + * Helper, a 0 as ZipShort. + */ + private static final byte[] ZERO = {0, 0}; + + /** + * Helper, a 0 as ZipLong. + */ + private static final byte[] LZERO = {0, 0, 0, 0}; + + private static final byte[] ONE = ZipLong.getBytes(1L); + + /* + * Various ZIP constants shared between this class, ZipArchiveInputStream and ZipFile + */ + /** + * local file header signature + */ + static final byte[] LFH_SIG = ZipLong.LFH_SIG.getBytes(); //NOSONAR + + /** + * data descriptor signature + */ + static final byte[] DD_SIG = ZipLong.DD_SIG.getBytes(); //NOSONAR + + /** + * central file header signature + */ + static final byte[] CFH_SIG = ZipLong.CFH_SIG.getBytes(); //NOSONAR + + /** + * end of central dir signature + */ + static final byte[] EOCD_SIG = ZipLong.getBytes(0X06054B50L); //NOSONAR + + /** + * ZIP64 end of central dir signature + */ + static final byte[] ZIP64_EOCD_SIG = ZipLong.getBytes(0X06064B50L); //NOSONAR + + /** + * ZIP64 end of central dir locator signature + */ + static final byte[] ZIP64_EOCD_LOC_SIG = ZipLong.getBytes(0X07064B50L); //NOSONAR + + /** indicates if this archive is finished. protected for use in Jar implementation */ + protected boolean finished; + + /** + * Current entry. + */ + private CurrentEntry entry; + + /** + * The file comment. + */ + private String comment = ""; + + /** + * Compression level for next entry. + */ + private int level = DEFAULT_COMPRESSION; + + /** + * Has the compression level changed when compared to the last + * entry? + */ + private boolean hasCompressionLevelChanged; + + /** + * Default compression method for next entry. + */ + private int method = java.util.zip.ZipEntry.DEFLATED; + + + /** + * List of ZipArchiveEntries written so far. + */ + private final List entries = + new LinkedList<>(); + private final StreamCompressor streamCompressor; + + /** + * Start of central directory. + */ + private long cdOffset; + + /** + * Length of central directory. + */ + private long cdLength; + + /** + * Disk number start of central directory. + */ + private long cdDiskNumberStart; + + /** + * Length of end of central directory + */ + private long eocdLength; + + /** + * Holds some book-keeping data for each entry. + */ + private final Map metaData = + new HashMap<>(); + + /** + * The encoding to use for file names and the file comment. + * + *

For a list of possible values see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html. + * Defaults to UTF-8.

+ */ + private String encoding = DEFAULT_ENCODING; + + /** + * The zip encoding to use for file names and the file comment. + * + * This field is of internal use and will be set in {@link + * #setEncoding(String)}. + */ + private ZipEncoding zipEncoding = + ZipEncodingHelper.getZipEncoding(DEFAULT_ENCODING); + /** + * This Deflater object is used for output. + * + */ + protected final Deflater def; + + /** + * Optional random access output. + */ + private final SeekableByteChannel channel; + + private final OutputStream outputStream; + + /** + * whether to use the general purpose bit flag when writing UTF-8 + * file names or not. + */ + private boolean useUTF8Flag = true; + + /** + * Whether to encode non-encodable file names as UTF-8. + */ + private boolean fallbackToUTF8; + + /** + * whether to create UnicodePathExtraField-s for each entry. + */ + private UnicodeExtraFieldPolicy createUnicodeExtraFields = UnicodeExtraFieldPolicy.NEVER; + + /** + * Whether anything inside this archive has used a ZIP64 feature. + * + * @since 1.3 + */ + private boolean hasUsedZip64; + + private Zip64Mode zip64Mode = Zip64Mode.AsNeeded; + + private final byte[] copyBuffer = new byte[32768]; + + private final Calendar calendarInstance = Calendar.getInstance(); + + /** + * Whether we are creating a split zip + */ + private final boolean isSplitZip; + + /** + * Holds the number of Central Directories on each disk, this is used + * when writing Zip64 End Of Central Directory and End Of Central Directory + */ + private final Map numberOfCDInDiskData = new HashMap<>(); + + /** + * Creates a new ZIP OutputStream filtering the underlying stream. + * @param out the outputstream to zip + */ + public ZipArchiveOutputStream(final OutputStream out) { + this.outputStream = out; + this.channel = null; + def = new Deflater(level, true); + streamCompressor = StreamCompressor.create(out, def); + isSplitZip = false; + } + + /** + * Creates a split ZIP Archive. + * + *

The files making up the archive will use Z01, Z02, + * ... extensions and the last part of it will be the given {@code + * file}.

+ * + *

Even though the stream writes to a file this stream will + * behave as if no random access was possible. This means the + * sizes of stored entries need to be known before the actual + * entry data is written.

+ * + * @param file the file that will become the last part of the split archive + * @param zipSplitSize maximum size of a single part of the split + * archive created by this stream. Must be between 64kB and about + * 4GB. + * + * @throws IOException on error + * @throws IllegalArgumentException if zipSplitSize is not in the required range + * @since 1.20 + */ + public ZipArchiveOutputStream(final File file, final long zipSplitSize) throws IOException { + def = new Deflater(level, true); + this.outputStream = new ZipSplitOutputStream(file, zipSplitSize); + streamCompressor = StreamCompressor.create(this.outputStream, def); + channel = null; + isSplitZip = true; + } + + /** + * Creates a new ZIP OutputStream writing to a SeekableByteChannel. + * + * @param channel the channel to zip to + * @since 1.13 + */ + public ZipArchiveOutputStream(final SeekableByteChannel channel) { + this.channel = channel; + def = new Deflater(level, true); + streamCompressor = StreamCompressor.create(channel, def); + outputStream = null; + isSplitZip = false; + } + + /** + * Adds an archive entry with a raw input stream. + * + * If crc, size and compressed size are supplied on the entry, these values will be used as-is. + * Zip64 status is re-established based on the settings in this stream, and the supplied value + * is ignored. + * + * The entry is put and closed immediately. + * + * @param entry The archive entry to add + * @param rawStream The raw input stream of a different entry. May be compressed/encrypted. + * @throws IOException If copying fails + */ + public void addRawArchiveEntry(final ZipArchiveEntry entry, final InputStream rawStream) + throws IOException { + final ZipArchiveEntry ae = new ZipArchiveEntry(entry); + if (hasZip64Extra(ae)) { + // Will be re-added as required. this may make the file generated with this method + // somewhat smaller than standard mode, + // since standard mode is unable to remove the zip 64 header. + ae.removeExtraField(Zip64ExtendedInformationExtraField.HEADER_ID); + } + final boolean is2PhaseSource = ae.getCrc() != ZipArchiveEntry.CRC_UNKNOWN + && ae.getSize() != ArchiveEntry.SIZE_UNKNOWN + && ae.getCompressedSize() != ArchiveEntry.SIZE_UNKNOWN; + putArchiveEntry(ae, is2PhaseSource); + copyFromZipInputStream(rawStream); + closeCopiedEntry(is2PhaseSource); + } + + /** + * Adds UnicodeExtra fields for name and file comment if mode is + * ALWAYS or the data cannot be encoded using the configured + * encoding. + */ + private void addUnicodeExtraFields(final ZipArchiveEntry ze, final boolean encodable, + final ByteBuffer name) + throws IOException { + if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS + || !encodable) { + ze.addExtraField(new UnicodePathExtraField(ze.getName(), + name.array(), + name.arrayOffset(), + name.limit() + - name.position())); + } + + final String comm = ze.getComment(); + if (comm != null && !comm.isEmpty()) { + + final boolean commentEncodable = zipEncoding.canEncode(comm); + + if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS + || !commentEncodable) { + final ByteBuffer commentB = getEntryEncoding(ze).encode(comm); + ze.addExtraField(new UnicodeCommentExtraField(comm, + commentB.array(), + commentB.arrayOffset(), + commentB.limit() + - commentB.position()) + ); + } + } + } + + /** + * Whether this stream is able to write the given entry. + * + *

May return false if it is set up to use encryption or a + * compression method that hasn't been implemented yet.

+ * @since 1.1 + */ + @Override + public boolean canWriteEntryData(final ArchiveEntry ae) { + if (ae instanceof ZipArchiveEntry) { + final ZipArchiveEntry zae = (ZipArchiveEntry) ae; + return zae.getMethod() != ZipMethod.IMPLODING.getCode() + && zae.getMethod() != ZipMethod.UNSHRINKING.getCode() + && ZipUtil.canHandleEntryData(zae); + } + return false; + } + + /** + * Verifies the sizes aren't too big in the Zip64Mode.Never case + * and returns whether the entry would require a Zip64 extra + * field. + */ + private boolean checkIfNeedsZip64(final Zip64Mode effectiveMode) + throws ZipException { + final boolean actuallyNeedsZip64 = isZip64Required(entry.entry, effectiveMode); + if (actuallyNeedsZip64 && effectiveMode == Zip64Mode.Never) { + throw new Zip64RequiredException(Zip64RequiredException.getEntryTooBigMessage(entry.entry)); + } + return actuallyNeedsZip64; + } + + /** + * Closes this output stream and releases any system resources + * associated with the stream. + * + * @throws IOException if an I/O error occurs. + * @throws Zip64RequiredException if the archive's size exceeds 4 + * GByte or there are more than 65535 entries inside the archive + * and {@link #setUseZip64} is {@link Zip64Mode#Never}. + */ + @Override + public void close() throws IOException { + try { + if (!finished) { + finish(); + } + } finally { + destroy(); + } + } + + /** + * Writes all necessary data for this entry. + * @throws IOException on error + * @throws Zip64RequiredException if the entry's uncompressed or + * compressed size exceeds 4 GByte and {@link #setUseZip64} + * is {@link Zip64Mode#Never}. + */ + @Override + public void closeArchiveEntry() throws IOException { + preClose(); + + flushDeflater(); + + final long bytesWritten = streamCompressor.getTotalBytesWritten() - entry.dataStart; + final long realCrc = streamCompressor.getCrc32(); + entry.bytesRead = streamCompressor.getBytesRead(); + final Zip64Mode effectiveMode = getEffectiveZip64Mode(entry.entry); + final boolean actuallyNeedsZip64 = handleSizesAndCrc(bytesWritten, realCrc, effectiveMode); + closeEntry(actuallyNeedsZip64, false); + streamCompressor.reset(); + } + + /** + * Writes all necessary data for this entry. + * + * @param phased This entry is second phase of a 2-phase zip creation, size, compressed size and crc + * are known in ZipArchiveEntry + * @throws IOException on error + * @throws Zip64RequiredException if the entry's uncompressed or + * compressed size exceeds 4 GByte and {@link #setUseZip64} + * is {@link Zip64Mode#Never}. + */ + private void closeCopiedEntry(final boolean phased) throws IOException { + preClose(); + entry.bytesRead = entry.entry.getSize(); + final Zip64Mode effectiveMode = getEffectiveZip64Mode(entry.entry); + final boolean actuallyNeedsZip64 = checkIfNeedsZip64(effectiveMode); + closeEntry(actuallyNeedsZip64, phased); + } + + private void closeEntry(final boolean actuallyNeedsZip64, final boolean phased) throws IOException { + if (!phased && channel != null) { + rewriteSizesAndCrc(actuallyNeedsZip64); + } + + if (!phased) { + writeDataDescriptor(entry.entry); + } + entry = null; + } + + private void copyFromZipInputStream(final InputStream src) throws IOException { + if (entry == null) { + throw new IllegalStateException("No current entry"); + } + ZipUtil.checkRequestedFeatures(entry.entry); + entry.hasWritten = true; + int length; + while ((length = src.read(copyBuffer)) >= 0 ) + { + streamCompressor.writeCounted(copyBuffer, 0, length); + count( length ); + } + } + + /** + * Creates a new zip entry taking some information from the given + * file and using the provided name. + * + *

The name will be adjusted to end with a forward slash "/" if + * the file is a directory. If the file is not a directory a + * potential trailing forward slash will be stripped from the + * entry name.

+ * + *

Must not be used if the stream has already been closed.

+ */ + @Override + public ArchiveEntry createArchiveEntry(final File inputFile, final String entryName) + throws IOException { + if (finished) { + throw new IOException("Stream has already been finished"); + } + return new ZipArchiveEntry(inputFile, entryName); + } + + private byte[] createCentralFileHeader(final ZipArchiveEntry ze) throws IOException { + + final EntryMetaData entryMetaData = metaData.get(ze); + final boolean needsZip64Extra = hasZip64Extra(ze) + || ze.getCompressedSize() >= ZIP64_MAGIC + || ze.getSize() >= ZIP64_MAGIC + || entryMetaData.offset >= ZIP64_MAGIC + || ze.getDiskNumberStart() >= ZIP64_MAGIC_SHORT + || zip64Mode == Zip64Mode.Always + || zip64Mode == Zip64Mode.AlwaysWithCompatibility; + + if (needsZip64Extra && zip64Mode == Zip64Mode.Never) { + // must be the offset that is too big, otherwise an + // exception would have been throw in putArchiveEntry or + // closeArchiveEntry + throw new Zip64RequiredException(Zip64RequiredException + .ARCHIVE_TOO_BIG_MESSAGE); + } + + + handleZip64Extra(ze, entryMetaData.offset, needsZip64Extra); + + return createCentralFileHeader(ze, getName(ze), entryMetaData, needsZip64Extra); + } + + /** + * Writes the central file header entry. + * @param ze the entry to write + * @param name The encoded name + * @param entryMetaData meta data for this file + * @throws IOException on error + */ + private byte[] createCentralFileHeader(final ZipArchiveEntry ze, final ByteBuffer name, + final EntryMetaData entryMetaData, + final boolean needsZip64Extra) throws IOException { + if(isSplitZip) { + // calculate the disk number for every central file header, + // this will be used in writing End Of Central Directory and Zip64 End Of Central Directory + final int currentSplitSegment = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex(); + if(numberOfCDInDiskData.get(currentSplitSegment) == null) { + numberOfCDInDiskData.put(currentSplitSegment, 1); + } else { + final int originalNumberOfCD = numberOfCDInDiskData.get(currentSplitSegment); + numberOfCDInDiskData.put(currentSplitSegment, originalNumberOfCD + 1); + } + } + + final byte[] extra = ze.getCentralDirectoryExtra(); + final int extraLength = extra.length; + + // file comment length + String comm = ze.getComment(); + if (comm == null) { + comm = ""; + } + + final ByteBuffer commentB = getEntryEncoding(ze).encode(comm); + final int nameLen = name.limit() - name.position(); + final int commentLen = commentB.limit() - commentB.position(); + final int len= CFH_FILENAME_OFFSET + nameLen + extraLength + commentLen; + final byte[] buf = new byte[len]; + + System.arraycopy(CFH_SIG, 0, buf, CFH_SIG_OFFSET, WORD); + + // version made by + // CheckStyle:MagicNumber OFF + ZipShort.putShort((ze.getPlatform() << 8) | (!hasUsedZip64 ? DATA_DESCRIPTOR_MIN_VERSION : ZIP64_MIN_VERSION), + buf, CFH_VERSION_MADE_BY_OFFSET); + + final int zipMethod = ze.getMethod(); + final boolean encodable = zipEncoding.canEncode(ze.getName()); + ZipShort.putShort(versionNeededToExtract(zipMethod, needsZip64Extra, entryMetaData.usesDataDescriptor), + buf, CFH_VERSION_NEEDED_OFFSET); + getGeneralPurposeBits(!encodable && fallbackToUTF8, entryMetaData.usesDataDescriptor).encode(buf, CFH_GPB_OFFSET); + + // compression method + ZipShort.putShort(zipMethod, buf, CFH_METHOD_OFFSET); + + + // last mod. time and date + ZipUtil.toDosTime(calendarInstance, ze.getTime(), buf, CFH_TIME_OFFSET); + + // CRC + // compressed length + // uncompressed length + putLong(ze.getCrc(), buf, CFH_CRC_OFFSET); + if (ze.getCompressedSize() >= ZIP64_MAGIC + || ze.getSize() >= ZIP64_MAGIC + || zip64Mode == Zip64Mode.Always + || zip64Mode == Zip64Mode.AlwaysWithCompatibility) { + ZipLong.ZIP64_MAGIC.putLong(buf, CFH_COMPRESSED_SIZE_OFFSET); + ZipLong.ZIP64_MAGIC.putLong(buf, CFH_ORIGINAL_SIZE_OFFSET); + } else { + putLong(ze.getCompressedSize(), buf, CFH_COMPRESSED_SIZE_OFFSET); + putLong(ze.getSize(), buf, CFH_ORIGINAL_SIZE_OFFSET); + } + + ZipShort.putShort(nameLen, buf, CFH_FILENAME_LENGTH_OFFSET); + + // extra field length + ZipShort.putShort(extraLength, buf, CFH_EXTRA_LENGTH_OFFSET); + + ZipShort.putShort(commentLen, buf, CFH_COMMENT_LENGTH_OFFSET); + + // disk number start + if(isSplitZip) { + if (ze.getDiskNumberStart() >= ZIP64_MAGIC_SHORT || zip64Mode == Zip64Mode.Always) { + ZipShort.putShort(ZIP64_MAGIC_SHORT, buf, CFH_DISK_NUMBER_OFFSET); + } else { + ZipShort.putShort((int) ze.getDiskNumberStart(), buf, CFH_DISK_NUMBER_OFFSET); + } + } else { + System.arraycopy(ZERO, 0, buf, CFH_DISK_NUMBER_OFFSET, SHORT); + } + + // internal file attributes + ZipShort.putShort(ze.getInternalAttributes(), buf, CFH_INTERNAL_ATTRIBUTES_OFFSET); + + // external file attributes + putLong(ze.getExternalAttributes(), buf, CFH_EXTERNAL_ATTRIBUTES_OFFSET); + + // relative offset of LFH + if (entryMetaData.offset >= ZIP64_MAGIC || zip64Mode == Zip64Mode.Always) { + putLong(ZIP64_MAGIC, buf, CFH_LFH_OFFSET); + } else { + putLong(Math.min(entryMetaData.offset, ZIP64_MAGIC), buf, CFH_LFH_OFFSET); + } + + // file name + System.arraycopy(name.array(), name.arrayOffset(), buf, CFH_FILENAME_OFFSET, nameLen); + + final int extraStart = CFH_FILENAME_OFFSET + nameLen; + System.arraycopy(extra, 0, buf, extraStart, extraLength); + + final int commentStart = extraStart + extraLength; + + // file comment + System.arraycopy(commentB.array(), commentB.arrayOffset(), buf, commentStart, commentLen); + return buf; + } + + private byte[] createLocalFileHeader(final ZipArchiveEntry ze, final ByteBuffer name, final boolean encodable, + final boolean phased, final long archiveOffset) { + final ZipExtraField oldEx = ze.getExtraField(ResourceAlignmentExtraField.ID); + if (oldEx != null) { + ze.removeExtraField(ResourceAlignmentExtraField.ID); + } + final ResourceAlignmentExtraField oldAlignmentEx = + oldEx instanceof ResourceAlignmentExtraField ? (ResourceAlignmentExtraField) oldEx : null; + + int alignment = ze.getAlignment(); + if (alignment <= 0 && oldAlignmentEx != null) { + alignment = oldAlignmentEx.getAlignment(); + } + + if (alignment > 1 || (oldAlignmentEx != null && !oldAlignmentEx.allowMethodChange())) { + final int oldLength = LFH_FILENAME_OFFSET + + name.limit() - name.position() + + ze.getLocalFileDataExtra().length; + + final int padding = (int) ((-archiveOffset - oldLength - ZipExtraField.EXTRAFIELD_HEADER_SIZE + - ResourceAlignmentExtraField.BASE_SIZE) & + (alignment - 1)); + ze.addExtraField(new ResourceAlignmentExtraField(alignment, + oldAlignmentEx != null && oldAlignmentEx.allowMethodChange(), padding)); + } + + final byte[] extra = ze.getLocalFileDataExtra(); + final int nameLen = name.limit() - name.position(); + final int len = LFH_FILENAME_OFFSET + nameLen + extra.length; + final byte[] buf = new byte[len]; + + System.arraycopy(LFH_SIG, 0, buf, LFH_SIG_OFFSET, WORD); + + //store method in local variable to prevent multiple method calls + final int zipMethod = ze.getMethod(); + final boolean dataDescriptor = usesDataDescriptor(zipMethod, phased); + + ZipShort.putShort(versionNeededToExtract(zipMethod, hasZip64Extra(ze), dataDescriptor), buf, LFH_VERSION_NEEDED_OFFSET); + + final GeneralPurposeBit generalPurposeBit = getGeneralPurposeBits(!encodable && fallbackToUTF8, dataDescriptor); + generalPurposeBit.encode(buf, LFH_GPB_OFFSET); + + // compression method + ZipShort.putShort(zipMethod, buf, LFH_METHOD_OFFSET); + + ZipUtil.toDosTime(calendarInstance, ze.getTime(), buf, LFH_TIME_OFFSET); + + // CRC + if (phased || !(zipMethod == DEFLATED || channel != null)){ + putLong(ze.getCrc(), buf, LFH_CRC_OFFSET); + } else { + System.arraycopy(LZERO, 0, buf, LFH_CRC_OFFSET, WORD); + } + + // compressed length + // uncompressed length + if (hasZip64Extra(entry.entry)){ + // point to ZIP64 extended information extra field for + // sizes, may get rewritten once sizes are known if + // stream is seekable + ZipLong.ZIP64_MAGIC.putLong(buf, LFH_COMPRESSED_SIZE_OFFSET); + ZipLong.ZIP64_MAGIC.putLong(buf, LFH_ORIGINAL_SIZE_OFFSET); + } else if (phased) { + putLong(ze.getCompressedSize(), buf, LFH_COMPRESSED_SIZE_OFFSET); + putLong(ze.getSize(), buf, LFH_ORIGINAL_SIZE_OFFSET); + } else if (zipMethod == DEFLATED || channel != null) { + System.arraycopy(LZERO, 0, buf, LFH_COMPRESSED_SIZE_OFFSET, WORD); + System.arraycopy(LZERO, 0, buf, LFH_ORIGINAL_SIZE_OFFSET, WORD); + } else { // Stored + putLong(ze.getSize(), buf, LFH_COMPRESSED_SIZE_OFFSET); + putLong(ze.getSize(), buf, LFH_ORIGINAL_SIZE_OFFSET); + } + // file name length + ZipShort.putShort(nameLen, buf, LFH_FILENAME_LENGTH_OFFSET); + + // extra field length + ZipShort.putShort(extra.length, buf, LFH_EXTRA_LENGTH_OFFSET); + + // file name + System.arraycopy( name.array(), name.arrayOffset(), buf, LFH_FILENAME_OFFSET, nameLen); + + // extra fields + System.arraycopy(extra, 0, buf, LFH_FILENAME_OFFSET + nameLen, extra.length); + + return buf; + } + + /** + * Writes next block of compressed data to the output stream. + * @throws IOException on error + */ + protected final void deflate() throws IOException { + streamCompressor.deflate(); + } + + /** + * Closes the underlying stream/file without finishing the + * archive, the result will likely be a corrupt archive. + * + *

This method only exists to support tests that generate + * corrupt archives so they can clean up any temporary files.

+ */ + void destroy() throws IOException { + try { + if (channel != null) { + channel.close(); + } + } finally { + if (outputStream != null) { + outputStream.close(); + } + } + } + + /** + * {@inheritDoc} + * @throws Zip64RequiredException if the archive's size exceeds 4 + * GByte or there are more than 65535 entries inside the archive + * and {@link #setUseZip64} is {@link Zip64Mode#Never}. + */ + @Override + public void finish() throws IOException { + if (finished) { + throw new IOException("This archive has already been finished"); + } + + if (entry != null) { + throw new IOException("This archive contains unclosed entries."); + } + + final long cdOverallOffset = streamCompressor.getTotalBytesWritten(); + cdOffset = cdOverallOffset; + if (isSplitZip) { + // when creating a split zip, the offset should be + // the offset to the corresponding segment disk + final ZipSplitOutputStream zipSplitOutputStream = (ZipSplitOutputStream)this.outputStream; + cdOffset = zipSplitOutputStream.getCurrentSplitSegmentBytesWritten(); + cdDiskNumberStart = zipSplitOutputStream.getCurrentSplitSegmentIndex(); + } + writeCentralDirectoryInChunks(); + + cdLength = streamCompressor.getTotalBytesWritten() - cdOverallOffset; + + // calculate the length of end of central directory, as it may be used in writeZip64CentralDirectory + final ByteBuffer commentData = this.zipEncoding.encode(comment); + final long commentLength = (long) commentData.limit() - commentData.position(); + eocdLength = WORD /* length of EOCD_SIG */ + + SHORT /* number of this disk */ + + SHORT /* disk number of start of central directory */ + + SHORT /* total number of entries on this disk */ + + SHORT /* total number of entries */ + + WORD /* size of central directory */ + + WORD /* offset of start of central directory */ + + SHORT /* zip comment length */ + + commentLength /* zip comment */; + + writeZip64CentralDirectory(); + writeCentralDirectoryEnd(); + metaData.clear(); + entries.clear(); + streamCompressor.close(); + if (isSplitZip) { + // trigger the ZipSplitOutputStream to write the final split segment + outputStream.close(); + } + finished = true; + } + + /** + * Flushes this output stream and forces any buffered output bytes + * to be written out to the stream. + * + * @throws IOException if an I/O error occurs. + */ + @Override + public void flush() throws IOException { + if (outputStream != null) { + outputStream.flush(); + } + } + + /** + * Ensures all bytes sent to the deflater are written to the stream. + */ + private void flushDeflater() throws IOException { + if (entry.entry.getMethod() == DEFLATED) { + streamCompressor.flushDeflater(); + } + } + + /** + * Returns the total number of bytes written to this stream. + * @return the number of written bytes + * @since 1.22 + */ + @Override + public long getBytesWritten() { + return streamCompressor.getTotalBytesWritten(); + } + + /** + * If the mode is AsNeeded and the entry is a compressed entry of + * unknown size that gets written to a non-seekable stream then + * change the default to Never. + * + * @since 1.3 + */ + private Zip64Mode getEffectiveZip64Mode(final ZipArchiveEntry ze) { + if (zip64Mode != Zip64Mode.AsNeeded + || channel != null + || ze.getMethod() != DEFLATED + || ze.getSize() != ArchiveEntry.SIZE_UNKNOWN) { + return zip64Mode; + } + return Zip64Mode.Never; + } + + /** + * The encoding to use for file names and the file comment. + * + * @return null if using the platform's default character encoding. + */ + public String getEncoding() { + return encoding; + } + + private ZipEncoding getEntryEncoding(final ZipArchiveEntry ze) { + final boolean encodable = zipEncoding.canEncode(ze.getName()); + return !encodable && fallbackToUTF8 + ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding; + } + + private GeneralPurposeBit getGeneralPurposeBits(final boolean utfFallback, final boolean usesDataDescriptor) { + final GeneralPurposeBit b = new GeneralPurposeBit(); + b.useUTF8ForNames(useUTF8Flag || utfFallback); + if (usesDataDescriptor) { + b.useDataDescriptor(true); + } + return b; + } + + private ByteBuffer getName(final ZipArchiveEntry ze) throws IOException { + return getEntryEncoding(ze).encode(ze.getName()); + } + + /** + * Get the existing ZIP64 extended information extra field or + * create a new one and add it to the entry. + * + * @since 1.3 + */ + private Zip64ExtendedInformationExtraField + getZip64Extra(final ZipArchiveEntry ze) { + if (entry != null) { + entry.causedUseOfZip64 = !hasUsedZip64; + } + hasUsedZip64 = true; + final ZipExtraField extra = ze.getExtraField(Zip64ExtendedInformationExtraField.HEADER_ID); + Zip64ExtendedInformationExtraField z64 = extra instanceof Zip64ExtendedInformationExtraField + ? (Zip64ExtendedInformationExtraField) extra : null; + if (z64 == null) { + /* + System.err.println("Adding z64 for " + ze.getName() + + ", method: " + ze.getMethod() + + " (" + (ze.getMethod() == STORED) + ")" + + ", channel: " + (channel != null)); + */ + z64 = new Zip64ExtendedInformationExtraField(); + } + + // even if the field is there already, make sure it is the first one + ze.addAsFirstExtraField(z64); + + return z64; + } + + /** + * Ensures the current entry's size and CRC information is set to + * the values just written, verifies it isn't too big in the + * Zip64Mode.Never case and returns whether the entry would + * require a Zip64 extra field. + */ + private boolean handleSizesAndCrc(final long bytesWritten, final long crc, + final Zip64Mode effectiveMode) + throws ZipException { + if (entry.entry.getMethod() == DEFLATED) { + /* It turns out def.getBytesRead() returns wrong values if + * the size exceeds 4 GB on Java < Java7 + entry.entry.setSize(def.getBytesRead()); + */ + entry.entry.setSize(entry.bytesRead); + entry.entry.setCompressedSize(bytesWritten); + entry.entry.setCrc(crc); + + } else if (channel == null) { + if (entry.entry.getCrc() != crc) { + throw new ZipException("Bad CRC checksum for entry " + + entry.entry.getName() + ": " + + Long.toHexString(entry.entry.getCrc()) + + " instead of " + + Long.toHexString(crc)); + } + + if (entry.entry.getSize() != bytesWritten) { + throw new ZipException("Bad size for entry " + + entry.entry.getName() + ": " + + entry.entry.getSize() + + " instead of " + + bytesWritten); + } + } else { /* method is STORED and we used SeekableByteChannel */ + entry.entry.setSize(bytesWritten); + entry.entry.setCompressedSize(bytesWritten); + entry.entry.setCrc(crc); + } + + return checkIfNeedsZip64(effectiveMode); + } + + /** + * If the entry needs Zip64 extra information inside the central + * directory then configure its data. + */ + private void handleZip64Extra(final ZipArchiveEntry ze, final long lfhOffset, + final boolean needsZip64Extra) { + if (needsZip64Extra) { + final Zip64ExtendedInformationExtraField z64 = getZip64Extra(ze); + if (ze.getCompressedSize() >= ZIP64_MAGIC + || ze.getSize() >= ZIP64_MAGIC + || zip64Mode == Zip64Mode.Always + || zip64Mode == Zip64Mode.AlwaysWithCompatibility) { + z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize())); + z64.setSize(new ZipEightByteInteger(ze.getSize())); + } else { + // reset value that may have been set for LFH + z64.setCompressedSize(null); + z64.setSize(null); + } + + final boolean needsToEncodeLfhOffset = + lfhOffset >= ZIP64_MAGIC || zip64Mode == Zip64Mode.Always; + final boolean needsToEncodeDiskNumberStart = + ze.getDiskNumberStart() >= ZIP64_MAGIC_SHORT || zip64Mode == Zip64Mode.Always; + + if (needsToEncodeLfhOffset || needsToEncodeDiskNumberStart) { + z64.setRelativeHeaderOffset(new ZipEightByteInteger(lfhOffset)); + } + if (needsToEncodeDiskNumberStart) { + z64.setDiskStartNumber(new ZipLong(ze.getDiskNumberStart())); + } + ze.setExtra(); + } + } + + /** + * Is there a ZIP64 extended information extra field for the + * entry? + * + * @since 1.3 + */ + private boolean hasZip64Extra(final ZipArchiveEntry ze) { + return ze.getExtraField(Zip64ExtendedInformationExtraField + .HEADER_ID) + instanceof Zip64ExtendedInformationExtraField; + } + /** + * This method indicates whether this archive is writing to a + * seekable stream (i.e., to a random access file). + * + *

For seekable streams, you don't need to calculate the CRC or + * uncompressed size for {@link #STORED} entries before + * invoking {@link #putArchiveEntry(ArchiveEntry)}. + * @return true if seekable + */ + public boolean isSeekable() { + return channel != null; + } + private boolean isTooLargeForZip32(final ZipArchiveEntry zipArchiveEntry){ + return zipArchiveEntry.getSize() >= ZIP64_MAGIC || zipArchiveEntry.getCompressedSize() >= ZIP64_MAGIC; + } + private boolean isZip64Required(final ZipArchiveEntry entry1, final Zip64Mode requestedMode) { + return requestedMode == Zip64Mode.Always || requestedMode == Zip64Mode.AlwaysWithCompatibility + || isTooLargeForZip32(entry1); + } + private void preClose() throws IOException { + if (finished) { + throw new IOException("Stream has already been finished"); + } + + if (entry == null) { + throw new IOException("No current entry to close"); + } + + if (!entry.hasWritten) { + write(ByteUtils.EMPTY_BYTE_ARRAY, 0, 0); + } + } + /** + * {@inheritDoc} + * @throws ClassCastException if entry is not an instance of ZipArchiveEntry + * @throws Zip64RequiredException if the entry's uncompressed or + * compressed size is known to exceed 4 GByte and {@link #setUseZip64} + * is {@link Zip64Mode#Never}. + */ + @Override + public void putArchiveEntry(final ArchiveEntry archiveEntry) throws IOException { + putArchiveEntry(archiveEntry, false); + } + + /** + * Writes the headers for an archive entry to the output stream. + * The caller must then write the content to the stream and call + * {@link #closeArchiveEntry()} to complete the process. + + * @param archiveEntry The archiveEntry + * @param phased If true size, compressedSize and crc required to be known up-front in the archiveEntry + * @throws ClassCastException if entry is not an instance of ZipArchiveEntry + * @throws Zip64RequiredException if the entry's uncompressed or + * compressed size is known to exceed 4 GByte and {@link #setUseZip64} + * is {@link Zip64Mode#Never}. + */ + private void putArchiveEntry(final ArchiveEntry archiveEntry, final boolean phased) throws IOException { + if (finished) { + throw new IOException("Stream has already been finished"); + } + + if (entry != null) { + closeArchiveEntry(); + } + + entry = new CurrentEntry((ZipArchiveEntry) archiveEntry); + entries.add(entry.entry); + + setDefaults(entry.entry); + + final Zip64Mode effectiveMode = getEffectiveZip64Mode(entry.entry); + validateSizeInformation(effectiveMode); + + if (shouldAddZip64Extra(entry.entry, effectiveMode)) { + + final Zip64ExtendedInformationExtraField z64 = getZip64Extra(entry.entry); + + final ZipEightByteInteger size; + final ZipEightByteInteger compressedSize; + if (phased) { + // sizes are already known + size = new ZipEightByteInteger(entry.entry.getSize()); + compressedSize = new ZipEightByteInteger(entry.entry.getCompressedSize()); + } else if (entry.entry.getMethod() == STORED + && entry.entry.getSize() != ArchiveEntry.SIZE_UNKNOWN) { + // actually, we already know the sizes + compressedSize = size = new ZipEightByteInteger(entry.entry.getSize()); + } else { + // just a placeholder, real data will be in data + // descriptor or inserted later via SeekableByteChannel + compressedSize = size = ZipEightByteInteger.ZERO; + } + z64.setSize(size); + z64.setCompressedSize(compressedSize); + entry.entry.setExtra(); + } + + if (entry.entry.getMethod() == DEFLATED && hasCompressionLevelChanged) { + def.setLevel(level); + hasCompressionLevelChanged = false; + } + writeLocalFileHeader((ZipArchiveEntry) archiveEntry, phased); + } + + /** + * When using random access output, write the local file header + * and potentially the ZIP64 extra containing the correct CRC and + * compressed/uncompressed sizes. + */ + private void rewriteSizesAndCrc(final boolean actuallyNeedsZip64) + throws IOException { + final long save = channel.position(); + + channel.position(entry.localDataStart); + writeOut(ZipLong.getBytes(entry.entry.getCrc())); + if (!hasZip64Extra(entry.entry) || !actuallyNeedsZip64) { + writeOut(ZipLong.getBytes(entry.entry.getCompressedSize())); + writeOut(ZipLong.getBytes(entry.entry.getSize())); + } else { + writeOut(ZipLong.ZIP64_MAGIC.getBytes()); + writeOut(ZipLong.ZIP64_MAGIC.getBytes()); + } + + if (hasZip64Extra(entry.entry)) { + final ByteBuffer name = getName(entry.entry); + final int nameLen = name.limit() - name.position(); + // seek to ZIP64 extra, skip header and size information + channel.position(entry.localDataStart + 3 * WORD + 2 * SHORT + + nameLen + 2 * SHORT); + // inside the ZIP64 extra uncompressed size comes + // first, unlike the LFH, CD or data descriptor + writeOut(ZipEightByteInteger.getBytes(entry.entry.getSize())); + writeOut(ZipEightByteInteger.getBytes(entry.entry.getCompressedSize())); + + if (!actuallyNeedsZip64) { + // do some cleanup: + // * rewrite version needed to extract + channel.position(entry.localDataStart - 5 * SHORT); + writeOut(ZipShort.getBytes(versionNeededToExtract(entry.entry.getMethod(), false, false))); + + // * remove ZIP64 extra so it doesn't get written + // to the central directory + entry.entry.removeExtraField(Zip64ExtendedInformationExtraField + .HEADER_ID); + entry.entry.setExtra(); + + // * reset hasUsedZip64 if it has been set because + // of this entry + if (entry.causedUseOfZip64) { + hasUsedZip64 = false; + } + } + } + channel.position(save); + } + + /** + * Set the file comment. + * @param comment the comment + */ + public void setComment(final String comment) { + this.comment = comment; + } + + + /** + * Whether to create Unicode Extra Fields. + * + *

Defaults to NEVER.

+ * + * @param b whether to create Unicode Extra Fields. + */ + public void setCreateUnicodeExtraFields(final UnicodeExtraFieldPolicy b) { + createUnicodeExtraFields = b; + } + + + /** + * Provides default values for compression method and last + * modification time. + */ + private void setDefaults(final ZipArchiveEntry entry) { + if (entry.getMethod() == -1) { // not specified + entry.setMethod(method); + } + + if (entry.getTime() == -1) { // not specified + entry.setTime(System.currentTimeMillis()); + } + } + + /** + * The encoding to use for file names and the file comment. + * + *

For a list of possible values see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html. + * Defaults to UTF-8.

+ * @param encoding the encoding to use for file names, use null + * for the platform's default encoding + */ + public void setEncoding(final String encoding) { + this.encoding = encoding; + this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding); + if (useUTF8Flag && !ZipEncodingHelper.isUTF8(encoding)) { + useUTF8Flag = false; + } + } + + /** + * Whether to fall back to UTF and the language encoding flag if + * the file name cannot be encoded using the specified encoding. + * + *

Defaults to false.

+ * + * @param b whether to fall back to UTF and the language encoding + * flag if the file name cannot be encoded using the specified + * encoding. + */ + public void setFallbackToUTF8(final boolean b) { + fallbackToUTF8 = b; + } + + /** + * Sets the compression level for subsequent entries. + * + *

Default is Deflater.DEFAULT_COMPRESSION.

+ * @param level the compression level. + * @throws IllegalArgumentException if an invalid compression + * level is specified. + */ + public void setLevel(final int level) { + if (level < Deflater.DEFAULT_COMPRESSION + || level > Deflater.BEST_COMPRESSION) { + throw new IllegalArgumentException("Invalid compression level: " + + level); + } + if (this.level == level) { + return; + } + hasCompressionLevelChanged = true; + this.level = level; + } + + /** + * Sets the default compression method for subsequent entries. + * + *

Default is DEFLATED.

+ * @param method an {@code int} from java.util.zip.ZipEntry + */ + public void setMethod(final int method) { + this.method = method; + } + + /** + * Whether to set the language encoding flag if the file name + * encoding is UTF-8. + * + *

Defaults to true.

+ * + * @param b whether to set the language encoding flag if the file + * name encoding is UTF-8 + */ + public void setUseLanguageEncodingFlag(final boolean b) { + useUTF8Flag = b && ZipEncodingHelper.isUTF8(encoding); + } + + /** + * Whether Zip64 extensions will be used. + * + *

When setting the mode to {@link Zip64Mode#Never Never}, + * {@link #putArchiveEntry}, {@link #closeArchiveEntry}, {@link + * #finish} or {@link #close} may throw a {@link + * Zip64RequiredException} if the entry's size or the total size + * of the archive exceeds 4GB or there are more than 65536 entries + * inside the archive. Any archive created in this mode will be + * readable by implementations that don't support Zip64.

+ * + *

When setting the mode to {@link Zip64Mode#Always Always}, + * Zip64 extensions will be used for all entries. Any archive + * created in this mode may be unreadable by implementations that + * don't support Zip64 even if all its contents would be.

+ * + *

When setting the mode to {@link Zip64Mode#AsNeeded + * AsNeeded}, Zip64 extensions will transparently be used for + * those entries that require them. This mode can only be used if + * the uncompressed size of the {@link ZipArchiveEntry} is known + * when calling {@link #putArchiveEntry} - + * this mode is not valid when the output stream is not seekable + * and the uncompressed size is unknown when {@link + * #putArchiveEntry} is called.

+ * + *

If no entry inside the resulting archive requires Zip64 + * extensions then {@link Zip64Mode#Never Never} will create the + * smallest archive. {@link Zip64Mode#AsNeeded AsNeeded} will + * create a slightly bigger archive if the uncompressed size of + * any entry has initially been unknown and create an archive + * identical to {@link Zip64Mode#Never Never} otherwise. {@link + * Zip64Mode#Always Always} will create an archive that is at + * least 24 bytes per entry bigger than the one {@link + * Zip64Mode#Never Never} would create.

+ * + *

Defaults to {@link Zip64Mode#AsNeeded AsNeeded} unless + * {@link #putArchiveEntry} is called with an entry of unknown + * size and data is written to a non-seekable stream - in this + * case the default is {@link Zip64Mode#Never Never}.

+ * + * @since 1.3 + * @param mode Whether Zip64 extensions will be used. + */ + public void setUseZip64(final Zip64Mode mode) { + zip64Mode = mode; + } + + /** + * Whether to add a Zip64 extended information extra field to the + * local file header. + * + *

Returns true if

+ * + *
    + *
  • mode is Always
  • + *
  • or we already know it is going to be needed
  • + *
  • or the size is unknown and we can ensure it won't hurt + * other implementations if we add it (i.e. we can erase its + * usage
  • + *
+ */ + private boolean shouldAddZip64Extra(final ZipArchiveEntry entry, final Zip64Mode mode) { + return mode == Zip64Mode.Always + || mode == Zip64Mode.AlwaysWithCompatibility + || entry.getSize() >= ZIP64_MAGIC + || entry.getCompressedSize() >= ZIP64_MAGIC + || (entry.getSize() == ArchiveEntry.SIZE_UNKNOWN + && channel != null && mode != Zip64Mode.Never); + } + + /** + * 4.4.1.4 If one of the fields in the end of central directory + * record is too small to hold required data, the field SHOULD be + * set to -1 (0xFFFF or 0xFFFFFFFF) and the ZIP64 format record + * SHOULD be created. + * @return true if zip64 End Of Central Directory is needed + */ + private boolean shouldUseZip64EOCD() { + int numberOfThisDisk = 0; + if(isSplitZip) { + numberOfThisDisk = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex(); + } + final int numOfEntriesOnThisDisk = numberOfCDInDiskData.get(numberOfThisDisk) == null ? 0 : numberOfCDInDiskData.get(numberOfThisDisk); + return numberOfThisDisk >= ZIP64_MAGIC_SHORT /* number of this disk */ + || cdDiskNumberStart >= ZIP64_MAGIC_SHORT /* number of the disk with the start of the central directory */ + || numOfEntriesOnThisDisk >= ZIP64_MAGIC_SHORT /* total number of entries in the central directory on this disk */ + || entries.size() >= ZIP64_MAGIC_SHORT /* total number of entries in the central directory */ + || cdLength >= ZIP64_MAGIC /* size of the central directory */ + || cdOffset >= ZIP64_MAGIC; /* offset of start of central directory with respect to + the starting disk number */ + } + + private boolean usesDataDescriptor(final int zipMethod, final boolean phased) { + return !phased && zipMethod == DEFLATED && channel == null; + } + + /** + * If the Zip64 mode is set to never, then all the data in End Of Central Directory + * should not exceed their limits. + * @throws Zip64RequiredException if Zip64 is actually needed + */ + private void validateIfZip64IsNeededInEOCD() throws Zip64RequiredException { + // exception will only be thrown if the Zip64 mode is never while Zip64 is actually needed + if (zip64Mode != Zip64Mode.Never) { + return; + } + + int numberOfThisDisk = 0; + if (isSplitZip) { + numberOfThisDisk = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex(); + } + if (numberOfThisDisk >= ZIP64_MAGIC_SHORT) { + throw new Zip64RequiredException(Zip64RequiredException + .NUMBER_OF_THIS_DISK_TOO_BIG_MESSAGE); + } + + if (cdDiskNumberStart >= ZIP64_MAGIC_SHORT) { + throw new Zip64RequiredException(Zip64RequiredException + .NUMBER_OF_THE_DISK_OF_CENTRAL_DIRECTORY_TOO_BIG_MESSAGE); + } + + final int numOfEntriesOnThisDisk = numberOfCDInDiskData.get(numberOfThisDisk) == null + ? 0 : numberOfCDInDiskData.get(numberOfThisDisk); + if (numOfEntriesOnThisDisk >= ZIP64_MAGIC_SHORT) { + throw new Zip64RequiredException(Zip64RequiredException + .TOO_MANY_ENTRIES_ON_THIS_DISK_MESSAGE); + } + + // number of entries + if (entries.size() >= ZIP64_MAGIC_SHORT) { + throw new Zip64RequiredException(Zip64RequiredException + .TOO_MANY_ENTRIES_MESSAGE); + } + + if (cdLength >= ZIP64_MAGIC) { + throw new Zip64RequiredException(Zip64RequiredException + .SIZE_OF_CENTRAL_DIRECTORY_TOO_BIG_MESSAGE); + } + + if (cdOffset >= ZIP64_MAGIC) { + throw new Zip64RequiredException(Zip64RequiredException + .ARCHIVE_TOO_BIG_MESSAGE); + } + } + + + /** + * Throws an exception if the size is unknown for a stored entry + * that is written to a non-seekable output or the entry is too + * big to be written without Zip64 extra but the mode has been set + * to Never. + */ + private void validateSizeInformation(final Zip64Mode effectiveMode) + throws ZipException { + // Size/CRC not required if SeekableByteChannel is used + if (entry.entry.getMethod() == STORED && channel == null) { + if (entry.entry.getSize() == ArchiveEntry.SIZE_UNKNOWN) { + throw new ZipException("Uncompressed size is required for" + + " STORED method when not writing to a" + + " file"); + } + if (entry.entry.getCrc() == ZipArchiveEntry.CRC_UNKNOWN) { + throw new ZipException("CRC checksum is required for STORED" + + " method when not writing to a file"); + } + entry.entry.setCompressedSize(entry.entry.getSize()); + } + + if ((entry.entry.getSize() >= ZIP64_MAGIC + || entry.entry.getCompressedSize() >= ZIP64_MAGIC) + && effectiveMode == Zip64Mode.Never) { + throw new Zip64RequiredException(Zip64RequiredException + .getEntryTooBigMessage(entry.entry)); + } + } + + + private int versionNeededToExtract(final int zipMethod, final boolean zip64, final boolean usedDataDescriptor) { + if (zip64) { + return ZIP64_MIN_VERSION; + } + if (usedDataDescriptor) { + return DATA_DESCRIPTOR_MIN_VERSION; + } + return versionNeededToExtractMethod(zipMethod); + } + + private int versionNeededToExtractMethod(final int zipMethod) { + return zipMethod == DEFLATED ? DEFLATE_MIN_VERSION : INITIAL_VERSION; + } + + /** + * Writes bytes to ZIP entry. + * @param b the byte array to write + * @param offset the start position to write from + * @param length the number of bytes to write + * @throws IOException on error + */ + @Override + public void write(final byte[] b, final int offset, final int length) throws IOException { + if (entry == null) { + throw new IllegalStateException("No current entry"); + } + ZipUtil.checkRequestedFeatures(entry.entry); + final long writtenThisTime = streamCompressor.write(b, offset, length, entry.entry.getMethod()); + count(writtenThisTime); + } + + /** + * Writes the "End of central dir record". + * @throws IOException on error + * @throws Zip64RequiredException if the archive's size exceeds 4 + * GByte or there are more than 65535 entries inside the archive + * and {@link #setUseZip64(Zip64Mode)} is {@link Zip64Mode#Never}. + */ + protected void writeCentralDirectoryEnd() throws IOException { + if(!hasUsedZip64 && isSplitZip) { + ((ZipSplitOutputStream)this.outputStream).prepareToWriteUnsplittableContent(eocdLength); + } + + validateIfZip64IsNeededInEOCD(); + + writeCounted(EOCD_SIG); + + // number of this disk + int numberOfThisDisk = 0; + if(isSplitZip) { + numberOfThisDisk = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex(); + } + writeCounted(ZipShort.getBytes(numberOfThisDisk)); + + // disk number of the start of central directory + writeCounted(ZipShort.getBytes((int)cdDiskNumberStart)); + + // number of entries + final int numberOfEntries = entries.size(); + + // total number of entries in the central directory on this disk + final int numOfEntriesOnThisDisk = isSplitZip + ? (numberOfCDInDiskData.get(numberOfThisDisk) == null ? 0 : numberOfCDInDiskData.get(numberOfThisDisk)) + : numberOfEntries; + final byte[] numOfEntriesOnThisDiskData = ZipShort + .getBytes(Math.min(numOfEntriesOnThisDisk, ZIP64_MAGIC_SHORT)); + writeCounted(numOfEntriesOnThisDiskData); + + // number of entries + final byte[] num = ZipShort.getBytes(Math.min(numberOfEntries, + ZIP64_MAGIC_SHORT)); + writeCounted(num); + + // length and location of CD + writeCounted(ZipLong.getBytes(Math.min(cdLength, ZIP64_MAGIC))); + writeCounted(ZipLong.getBytes(Math.min(cdOffset, ZIP64_MAGIC))); + + // ZIP file comment + final ByteBuffer data = this.zipEncoding.encode(comment); + final int dataLen = data.limit() - data.position(); + writeCounted(ZipShort.getBytes(dataLen)); + streamCompressor.writeCounted(data.array(), data.arrayOffset(), dataLen); + } + + private void writeCentralDirectoryInChunks() throws IOException { + final int NUM_PER_WRITE = 1000; + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(70 * NUM_PER_WRITE); + int count = 0; + for (final ZipArchiveEntry ze : entries) { + byteArrayOutputStream.write(createCentralFileHeader(ze)); + if (++count > NUM_PER_WRITE){ + writeCounted(byteArrayOutputStream.toByteArray()); + byteArrayOutputStream.reset(); + count = 0; + } + } + writeCounted(byteArrayOutputStream.toByteArray()); + } + + /** + * Writes the central file header entry. + * @param ze the entry to write + * @throws IOException on error + * @throws Zip64RequiredException if the archive's size exceeds 4 + * GByte and {@link #setUseZip64(Zip64Mode)} is {@link + * Zip64Mode#Never}. + */ + protected void writeCentralFileHeader(final ZipArchiveEntry ze) throws IOException { + final byte[] centralFileHeader = createCentralFileHeader(ze); + writeCounted(centralFileHeader); + } + + /** + * Write bytes to output or random access file. + * @param data the byte array to write + * @throws IOException on error + */ + private void writeCounted(final byte[] data) throws IOException { + streamCompressor.writeCounted(data); + } + + /** + * Writes the data descriptor entry. + * @param ze the entry to write + * @throws IOException on error + */ + protected void writeDataDescriptor(final ZipArchiveEntry ze) throws IOException { + if (!usesDataDescriptor(ze.getMethod(), false)) { + return; + } + writeCounted(DD_SIG); + writeCounted(ZipLong.getBytes(ze.getCrc())); + if (!hasZip64Extra(ze)) { + writeCounted(ZipLong.getBytes(ze.getCompressedSize())); + writeCounted(ZipLong.getBytes(ze.getSize())); + } else { + writeCounted(ZipEightByteInteger.getBytes(ze.getCompressedSize())); + writeCounted(ZipEightByteInteger.getBytes(ze.getSize())); + } + } + + /** + * Writes the local file header entry + * @param ze the entry to write + * @throws IOException on error + */ + protected void writeLocalFileHeader(final ZipArchiveEntry ze) throws IOException { + writeLocalFileHeader(ze, false); + } + + private void writeLocalFileHeader(final ZipArchiveEntry ze, final boolean phased) throws IOException { + final boolean encodable = zipEncoding.canEncode(ze.getName()); + final ByteBuffer name = getName(ze); + + if (createUnicodeExtraFields != UnicodeExtraFieldPolicy.NEVER) { + addUnicodeExtraFields(ze, encodable, name); + } + + long localHeaderStart = streamCompressor.getTotalBytesWritten(); + if (isSplitZip) { + // when creating a split zip, the offset should be + // the offset to the corresponding segment disk + final ZipSplitOutputStream splitOutputStream = (ZipSplitOutputStream)this.outputStream; + ze.setDiskNumberStart(splitOutputStream.getCurrentSplitSegmentIndex()); + localHeaderStart = splitOutputStream.getCurrentSplitSegmentBytesWritten(); + } + + final byte[] localHeader = createLocalFileHeader(ze, name, encodable, phased, localHeaderStart); + metaData.put(ze, new EntryMetaData(localHeaderStart, usesDataDescriptor(ze.getMethod(), phased))); + entry.localDataStart = localHeaderStart + LFH_CRC_OFFSET; // At crc offset + writeCounted(localHeader); + entry.dataStart = streamCompressor.getTotalBytesWritten(); + } + + /** + * Write bytes to output or random access file. + * @param data the byte array to write + * @throws IOException on error + */ + protected final void writeOut(final byte[] data) throws IOException { + streamCompressor.writeOut(data, 0, data.length); + } + + /** + * Write bytes to output or random access file. + * @param data the byte array to write + * @param offset the start position to write from + * @param length the number of bytes to write + * @throws IOException on error + */ + protected final void writeOut(final byte[] data, final int offset, final int length) + throws IOException { + streamCompressor.writeOut(data, offset, length); + } + + /** + * Write preamble data. For most of time, this is used to + * make self-extracting zips. + * + * @param preamble data to write + * @throws IOException if an entry already exists + * @since 1.21 + */ + public void writePreamble(final byte[] preamble) throws IOException { + writePreamble(preamble, 0, preamble.length); + } + + /** + * Write preamble data. For most of time, this is used to + * make self-extracting zips. + * + * @param preamble data to write + * @param offset the start offset in the data + * @param length the number of bytes to write + * @throws IOException if an entry already exists + * @since 1.21 + */ + public void writePreamble(final byte[] preamble, final int offset, final int length) throws IOException { + if (entry != null) { + throw new IllegalStateException("Preamble must be written before creating an entry"); + } + this.streamCompressor.writeCounted(preamble, offset, length); + } + + /** + * Writes the "ZIP64 End of central dir record" and + * "ZIP64 End of central dir locator". + * @throws IOException on error + * @since 1.3 + */ + protected void writeZip64CentralDirectory() throws IOException { + if (zip64Mode == Zip64Mode.Never) { + return; + } + + if (!hasUsedZip64 && shouldUseZip64EOCD()) { + // actually "will use" + hasUsedZip64 = true; + } + + if (!hasUsedZip64) { + return; + } + + long offset = streamCompressor.getTotalBytesWritten(); + long diskNumberStart = 0L; + if(isSplitZip) { + // when creating a split zip, the offset of should be + // the offset to the corresponding segment disk + final ZipSplitOutputStream zipSplitOutputStream = (ZipSplitOutputStream)this.outputStream; + offset = zipSplitOutputStream.getCurrentSplitSegmentBytesWritten(); + diskNumberStart = zipSplitOutputStream.getCurrentSplitSegmentIndex(); + } + + + writeOut(ZIP64_EOCD_SIG); + // size of zip64 end of central directory, we don't have any variable length + // as we don't support the extensible data sector, yet + writeOut(ZipEightByteInteger + .getBytes(SHORT /* version made by */ + + SHORT /* version needed to extract */ + + WORD /* disk number */ + + WORD /* disk with central directory */ + + DWORD /* number of entries in CD on this disk */ + + DWORD /* total number of entries */ + + DWORD /* size of CD */ + + (long) DWORD /* offset of CD */ + )); + + // version made by and version needed to extract + writeOut(ZipShort.getBytes(ZIP64_MIN_VERSION)); + writeOut(ZipShort.getBytes(ZIP64_MIN_VERSION)); + + // number of this disk + int numberOfThisDisk = 0; + if (isSplitZip) { + numberOfThisDisk = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex(); + } + writeOut(ZipLong.getBytes(numberOfThisDisk)); + + // disk number of the start of central directory + writeOut(ZipLong.getBytes(cdDiskNumberStart)); + + // total number of entries in the central directory on this disk + final int numOfEntriesOnThisDisk = isSplitZip + ? (numberOfCDInDiskData.get(numberOfThisDisk) == null ? 0 : numberOfCDInDiskData.get(numberOfThisDisk)) + : entries.size(); + final byte[] numOfEntriesOnThisDiskData = ZipEightByteInteger.getBytes(numOfEntriesOnThisDisk); + writeOut(numOfEntriesOnThisDiskData); + + // number of entries + final byte[] num = ZipEightByteInteger.getBytes(entries.size()); + writeOut(num); + + // length and location of CD + writeOut(ZipEightByteInteger.getBytes(cdLength)); + writeOut(ZipEightByteInteger.getBytes(cdOffset)); + + // no "zip64 extensible data sector" for now + + if(isSplitZip) { + // based on the zip specification, the End Of Central Directory record and + // the Zip64 End Of Central Directory locator record must be on the same segment + final int zip64EOCDLOCLength = WORD /* length of ZIP64_EOCD_LOC_SIG */ + + WORD /* disk number of ZIP64_EOCD_SIG */ + + DWORD /* offset of ZIP64_EOCD_SIG */ + + WORD /* total number of disks */; + + final long unsplittableContentSize = zip64EOCDLOCLength + eocdLength; + ((ZipSplitOutputStream)this.outputStream).prepareToWriteUnsplittableContent(unsplittableContentSize); + } + + // and now the "ZIP64 end of central directory locator" + writeOut(ZIP64_EOCD_LOC_SIG); + + // disk number holding the ZIP64 EOCD record + writeOut(ZipLong.getBytes(diskNumberStart)); + // relative offset of ZIP64 EOCD record + writeOut(ZipEightByteInteger.getBytes(offset)); + // total number of disks + if(isSplitZip) { + // the Zip64 End Of Central Directory Locator and the End Of Central Directory must be + // in the same split disk, it means they must be located in the last disk + final int totalNumberOfDisks = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex() + 1; + writeOut(ZipLong.getBytes(totalNumberOfDisks)); + } else { + writeOut(ONE); + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipConstants.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipConstants.java new file mode 100644 index 0000000000..17fbdbdc24 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipConstants.java @@ -0,0 +1,73 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +/** + * Various constants used throughout the package. + * + * @since 1.3 + */ +final class ZipConstants { + /** Masks last eight bits */ + static final int BYTE_MASK = 0xFF; + + /** length of a ZipShort in bytes */ + static final int SHORT = 2; + + /** length of a ZipLong in bytes */ + static final int WORD = 4; + + /** length of a ZipEightByteInteger in bytes */ + static final int DWORD = 8; + + /** Initial ZIP specification version */ + static final int INITIAL_VERSION = 10; + + /** + * ZIP specification version that introduced DEFLATE compression method. + * @since 1.15 + */ + static final int DEFLATE_MIN_VERSION = 20; + + /** ZIP specification version that introduced data descriptor method */ + static final int DATA_DESCRIPTOR_MIN_VERSION = 20; + + /** ZIP specification version that introduced ZIP64 */ + static final int ZIP64_MIN_VERSION = 45; + + /** + * Value stored in two-byte size and similar fields if ZIP64 + * extensions are used. + */ + static final int ZIP64_MAGIC_SHORT = 0xFFFF; + + /** + * Value stored in four-byte size and similar fields if ZIP64 + * extensions are used. + */ + static final long ZIP64_MAGIC = 0xFFFFFFFFL; + + private ZipConstants() { } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEightByteInteger.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEightByteInteger.java new file mode 100644 index 0000000000..aa9418c8c2 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEightByteInteger.java @@ -0,0 +1,238 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.Serializable; +import java.math.BigInteger; + +/** + * Utility class that represents an eight byte integer with conversion + * rules for the little endian byte order of ZIP files. + * @Immutable + * + * @since 1.2 + */ +public final class ZipEightByteInteger implements Serializable { + private static final long serialVersionUID = 1L; + + private static final int BYTE_1 = 1; + private static final int BYTE_1_MASK = 0xFF00; + private static final int BYTE_1_SHIFT = 8; + + private static final int BYTE_2 = 2; + private static final int BYTE_2_MASK = 0xFF0000; + private static final int BYTE_2_SHIFT = 16; + + private static final int BYTE_3 = 3; + private static final long BYTE_3_MASK = 0xFF000000L; + private static final int BYTE_3_SHIFT = 24; + + private static final int BYTE_4 = 4; + private static final long BYTE_4_MASK = 0xFF00000000L; + private static final int BYTE_4_SHIFT = 32; + + private static final int BYTE_5 = 5; + private static final long BYTE_5_MASK = 0xFF0000000000L; + private static final int BYTE_5_SHIFT = 40; + + private static final int BYTE_6 = 6; + private static final long BYTE_6_MASK = 0xFF000000000000L; + private static final int BYTE_6_SHIFT = 48; + + private static final int BYTE_7 = 7; + private static final long BYTE_7_MASK = 0x7F00000000000000L; + private static final int BYTE_7_SHIFT = 56; + + private static final int LEFTMOST_BIT_SHIFT = 63; + private static final byte LEFTMOST_BIT = (byte) 0x80; + + public static final ZipEightByteInteger ZERO = new ZipEightByteInteger(0); + + /** + * Get value as eight bytes in big endian byte order. + * @param value the value to convert + * @return value as eight bytes in big endian byte order + */ + public static byte[] getBytes(final BigInteger value) { + final byte[] result = new byte[8]; + final long val = value.longValue(); + result[0] = (byte) ((val & ZipConstants.BYTE_MASK)); + result[BYTE_1] = (byte) ((val & BYTE_1_MASK) >> BYTE_1_SHIFT); + result[BYTE_2] = (byte) ((val & BYTE_2_MASK) >> BYTE_2_SHIFT); + result[BYTE_3] = (byte) ((val & BYTE_3_MASK) >> BYTE_3_SHIFT); + result[BYTE_4] = (byte) ((val & BYTE_4_MASK) >> BYTE_4_SHIFT); + result[BYTE_5] = (byte) ((val & BYTE_5_MASK) >> BYTE_5_SHIFT); + result[BYTE_6] = (byte) ((val & BYTE_6_MASK) >> BYTE_6_SHIFT); + result[BYTE_7] = (byte) ((val & BYTE_7_MASK) >> BYTE_7_SHIFT); + if (value.testBit(LEFTMOST_BIT_SHIFT)) { + result[BYTE_7] |= LEFTMOST_BIT; + } + return result; + } + + /** + * Get value as eight bytes in big endian byte order. + * @param value the value to convert + * @return value as eight bytes in big endian byte order + */ + public static byte[] getBytes(final long value) { + return getBytes(BigInteger.valueOf(value)); + } + + /** + * Helper method to get the value as a Java long from an eight-byte array + * @param bytes the array of bytes + * @return the corresponding Java long value + */ + public static long getLongValue(final byte[] bytes) { + return getLongValue(bytes, 0); + } + + /** + * Helper method to get the value as a Java long from eight bytes + * starting at given array offset + * @param bytes the array of bytes + * @param offset the offset to start + * @return the corresponding Java long value + */ + public static long getLongValue(final byte[] bytes, final int offset) { + return getValue(bytes, offset).longValue(); + } + + /** + * Helper method to get the value as a Java long from an eight-byte array + * @param bytes the array of bytes + * @return the corresponding Java BigInteger value + */ + public static BigInteger getValue(final byte[] bytes) { + return getValue(bytes, 0); + } + + /** + * Helper method to get the value as a Java BigInteger from eight + * bytes starting at given array offset + * @param bytes the array of bytes + * @param offset the offset to start + * @return the corresponding Java BigInteger value + */ + public static BigInteger getValue(final byte[] bytes, final int offset) { + long value = ((long) bytes[offset + BYTE_7] << BYTE_7_SHIFT) & BYTE_7_MASK; + value += ((long) bytes[offset + BYTE_6] << BYTE_6_SHIFT) & BYTE_6_MASK; + value += ((long) bytes[offset + BYTE_5] << BYTE_5_SHIFT) & BYTE_5_MASK; + value += ((long) bytes[offset + BYTE_4] << BYTE_4_SHIFT) & BYTE_4_MASK; + value += ((long) bytes[offset + BYTE_3] << BYTE_3_SHIFT) & BYTE_3_MASK; + value += ((long) bytes[offset + BYTE_2] << BYTE_2_SHIFT) & BYTE_2_MASK; + value += ((long) bytes[offset + BYTE_1] << BYTE_1_SHIFT) & BYTE_1_MASK; + value += ((long) bytes[offset] & ZipConstants.BYTE_MASK); + final BigInteger val = BigInteger.valueOf(value); + return (bytes[offset + BYTE_7] & LEFTMOST_BIT) == LEFTMOST_BIT + ? val.setBit(LEFTMOST_BIT_SHIFT) : val; + } + + private final BigInteger value; + + /** + * Create instance from a number. + * @param value the BigInteger to store as a ZipEightByteInteger + */ + public ZipEightByteInteger(final BigInteger value) { + this.value = value; + } + + /** + * Create instance from bytes. + * @param bytes the bytes to store as a ZipEightByteInteger + */ + public ZipEightByteInteger (final byte[] bytes) { + this(bytes, 0); + } + + /** + * Create instance from the eight bytes starting at offset. + * @param bytes the bytes to store as a ZipEightByteInteger + * @param offset the offset to start + */ + public ZipEightByteInteger (final byte[] bytes, final int offset) { + value = ZipEightByteInteger.getValue(bytes, offset); + } + + /** + * Create instance from a number. + * @param value the long to store as a ZipEightByteInteger + */ + public ZipEightByteInteger(final long value) { + this(BigInteger.valueOf(value)); + } + + /** + * Override to make two instances with same value equal. + * @param o an object to compare + * @return true if the objects are equal + */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof ZipEightByteInteger)) { + return false; + } + return value.equals(((ZipEightByteInteger) o).getValue()); + } + + /** + * Get value as eight bytes in big endian byte order. + * @return value as eight bytes in big endian order + */ + public byte[] getBytes() { + return ZipEightByteInteger.getBytes(value); + } + + /** + * Get value as Java long. + * @return value as a long + */ + public long getLongValue() { + return value.longValue(); + } + + /** + * Get value as Java BigInteger. + * @return value as a BigInteger + */ + public BigInteger getValue() { + return value; + } + + /** + * Override to make two instances with same value equal. + * @return the hashCode of the value stored in the ZipEightByteInteger + */ + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public String toString() { + return "ZipEightByteInteger value: " + value; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncoding.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncoding.java new file mode 100644 index 0000000000..24fed12401 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncoding.java @@ -0,0 +1,90 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * An interface for encoders that do a pretty encoding of ZIP + * file names. + * + *

There are mostly two implementations, one that uses java.nio + * {@link java.nio.charset.Charset Charset} and one implementation, + * which copes with simple 8 bit charsets, because java-1.4 did not + * support Cp437 in java.nio.

+ * + *

The main reason for defining an own encoding layer comes from + * the problems with {@link java.lang.String#getBytes(String) + * String.getBytes}, which encodes unknown characters as ASCII + * quotation marks ('?'). Quotation marks are per definition an + * invalid file name on some operating systems like Windows, which + * leads to ignored ZIP entries.

+ * + *

All implementations should implement this interface in a + * reentrant way.

+ */ +public interface ZipEncoding { + /** + * Check, whether the given string may be losslessly encoded using this + * encoding. + * + * @param name A file name or ZIP comment. + * @return Whether the given name may be encoded with out any losses. + */ + boolean canEncode(String name); + + /** + * @param data The byte values to decode. + * @return The decoded string. + * @throws IOException on error + */ + String decode(byte [] data) throws IOException; + + /** + * Encode a file name or a comment to a byte array suitable for + * storing it to a serialized zip entry. + * + *

Examples for CP 437 (in pseudo-notation, right hand side is + * C-style notation):

+ *
+     *  encode("\u20AC_for_Dollar.txt") = "%U20AC_for_Dollar.txt"
+     *  encode("\u00D6lf\u00E4sser.txt") = "\231lf\204sser.txt"
+     * 
+ * + * @param name A file name or ZIP comment. + * @return A byte buffer with a backing array containing the + * encoded name. Unmappable characters or malformed + * character sequences are mapped to a sequence of utf-16 + * words encoded in the format {@code %Uxxxx}. It is + * assumed, that the byte buffer is positioned at the + * beginning of the encoded result, the byte buffer has a + * backing array and the limit of the byte buffer points + * to the end of the encoded result. + * @throws IOException on error + */ + ByteBuffer encode(String name) throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncodingHelper.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncodingHelper.java new file mode 100644 index 0000000000..fd274885f5 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipEncodingHelper.java @@ -0,0 +1,100 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; + +/** + * Static helper functions for robustly encoding file names in zip files. + */ +public abstract class ZipEncodingHelper { + + + /** + * name of the encoding UTF-8 + */ + static final String UTF8 = "UTF8"; + + /** + * the encoding UTF-8 + */ + static final ZipEncoding UTF8_ZIP_ENCODING = getZipEncoding(UTF8); + + /** + * Instantiates a zip encoding. An NIO based character set encoder/decoder will be returned. + * As a special case, if the character set is UTF-8, the nio encoder will be configured replace malformed and + * unmappable characters with '?'. This matches existing behavior from the older fallback encoder. + *

+ * If the requested character set cannot be found, the platform default will + * be used instead. + *

+ * @param name The name of the zip encoding. Specify {@code null} for + * the platform's default encoding. + * @return A zip encoding for the given encoding name. + */ + public static ZipEncoding getZipEncoding(final String name) { + Charset cs = Charset.defaultCharset(); + if (name != null) { + try { + cs = Charset.forName(name); + } catch (final UnsupportedCharsetException e) { // NOSONAR we use the default encoding instead + } + } + final boolean useReplacement = isUTF8(cs.name()); + return new NioZipEncoding(cs, useReplacement); + } + + static ByteBuffer growBufferBy(final ByteBuffer buffer, final int increment) { + buffer.limit(buffer.position()); + buffer.rewind(); + + final ByteBuffer on = ByteBuffer.allocate(buffer.capacity() + increment); + + on.put(buffer); + return on; + } + + /** + * Returns whether a given encoding is UTF-8. If the given name is null, then check the platform's default encoding. + * + * @param charsetName If the given name is null, then check the platform's default encoding. + */ + static boolean isUTF8(final String charsetName) { + final String actual = charsetName != null ? charsetName : Charset.defaultCharset().name(); + if (UTF_8.name().equalsIgnoreCase(actual)) { + return true; + } + for (String alias: UTF_8.aliases()) { + if (alias.equalsIgnoreCase(actual)) { + return true; + } + } + return false; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipExtraField.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipExtraField.java new file mode 100644 index 0000000000..aebb68e940 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipExtraField.java @@ -0,0 +1,102 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.zip.ZipException; + +/** + * General format of extra field data. + * + *

Extra fields usually appear twice per file, once in the local + * file data and once in the central directory. Usually they are the + * same, but they don't have to be. {@link + * java.util.zip.ZipOutputStream java.util.zip.ZipOutputStream} will + * only use the local file data in both places.

+ * + */ +public interface ZipExtraField { + /** + * Size of an extra field field header (id + length). + * @since 1.14 + */ + int EXTRAFIELD_HEADER_SIZE = 4; + + /** + * The actual data to put into central directory - without Header-ID or + * length specifier. + * @return the data + */ + byte[] getCentralDirectoryData(); + + /** + * Length of the extra field in the central directory - without + * Header-ID or length specifier. + * @return the length of the field in the central directory + */ + ZipShort getCentralDirectoryLength(); + + /** + * The Header-ID. + * + * @return The HeaderId value + */ + ZipShort getHeaderId(); + + /** + * The actual data to put into local file data - without Header-ID + * or length specifier. + * @return the data + */ + byte[] getLocalFileDataData(); + + /** + * Length of the extra field in the local file data - without + * Header-ID or length specifier. + * @return the length of the field in the local file data + */ + ZipShort getLocalFileDataLength(); + + /** + * Populate data from this array as if it was in central directory data. + * + * @param buffer the buffer to read data from + * @param offset offset into buffer to read data + * @param length the length of data + * @throws ZipException on error + */ + void parseFromCentralDirectoryData(byte[] buffer, int offset, int length) + throws ZipException; + + /** + * Populate data from this array as if it was in local file data. + * + * @param buffer the buffer to read data from + * @param offset offset into buffer to read data + * @param length the length of data + * @throws ZipException on error + */ + void parseFromLocalFileData(byte[] buffer, int offset, int length) + throws ZipException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipFile.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipFile.java new file mode 100644 index 0000000000..a787d5bf30 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipFile.java @@ -0,0 +1,1418 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import org.readium.r2.shared.util.archive.channel.compress.archivers.EntryStreamOffsets; +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel; +import org.readium.r2.shared.util.archive.channel.compress.utils.BoundedArchiveInputStream; +import org.readium.r2.shared.util.archive.channel.compress.utils.BoundedSeekableByteChannelInputStream; +import org.readium.r2.shared.util.archive.channel.compress.utils.CountingInputStream; +import org.readium.r2.shared.util.archive.channel.compress.utils.IOUtils; +import org.readium.r2.shared.util.archive.channel.compress.utils.InputStreamStatistics; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.SequenceInputStream; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.zip.Inflater; +import java.util.zip.ZipException; + +/** + * Replacement for {@code java.util.ZipFile}. + * + *

This class adds support for file name encodings other than UTF-8 + * (which is required to work on ZIP files created by native ZIP tools + * and is able to skip a preamble like the one found in self + * extracting archives. Furthermore it returns instances of + * {@code org.readium.r2.shared.util.archive.remote.zip.ZipArchiveEntry} + * instead of {@code java.util.zip.ZipEntry}.

+ * + *

It doesn't extend {@code java.util.zip.ZipFile} as it would + * have to reimplement all methods anyway. Like + * {@code java.util.ZipFile}, it uses SeekableByteChannel under the + * covers and supports compressed and uncompressed entries. As of + * Apache Commons Compress 1.3 it also transparently supports Zip64 + * extensions and thus individual entries and archives larger than 4 + * GB or with more than 65536 entries.

+ * + *

The method signatures mimic the ones of + * {@code java.util.zip.ZipFile}, with a couple of exceptions: + * + *

    + *
  • There is no getName method.
  • + *
  • entries has been renamed to getEntries.
  • + *
  • getEntries and getEntry return + * {@code org.readium.r2.shared.util.archive.remote.zip.ZipArchiveEntry} + * instances.
  • + *
  • close is allowed to throw IOException.
  • + *
+ */ +public class ZipFile implements Closeable { + + /** + * Extends ZipArchiveEntry to store the offset within the archive. + */ + private static class Entry extends ZipArchiveEntry { + + Entry() { + } + + @Override + public boolean equals(final Object other) { + if (super.equals(other)) { + // super.equals would return false if other were not an Entry + final Entry otherEntry = (Entry) other; + return getLocalHeaderOffset() + == otherEntry.getLocalHeaderOffset() + && super.getDataOffset() + == otherEntry.getDataOffset() + && super.getDiskNumberStart() + == otherEntry.getDiskNumberStart(); + } + return false; + } + + @Override + public int hashCode() { + return 3 * super.hashCode() + + (int) getLocalHeaderOffset()+(int)(getLocalHeaderOffset()>>32); + } + } + private static final class NameAndComment { + private final byte[] name; + private final byte[] comment; + private NameAndComment(final byte[] name, final byte[] comment) { + this.name = name; + this.comment = comment; + } + } + private static class StoredStatisticsStream extends CountingInputStream implements InputStreamStatistics { + StoredStatisticsStream(final InputStream in) { + super(in); + } + + @Override + public long getCompressedCount() { + return super.getBytesRead(); + } + + @Override + public long getUncompressedCount() { + return getCompressedCount(); + } + } + private static final int HASH_SIZE = 509; + static final int NIBLET_MASK = 0x0f; + static final int BYTE_SHIFT = 8; + private static final int POS_0 = 0; + + private static final int POS_1 = 1; + + private static final int POS_2 = 2; + + private static final int POS_3 = 3; + + private static final byte[] ONE_ZERO_BYTE = new byte[1]; + + /** + * Length of a "central directory" entry structure without file + * name, extra fields or comment. + */ + private static final int CFH_LEN = + /* version made by */ ZipConstants.SHORT + /* version needed to extract */ + ZipConstants.SHORT + /* general purpose bit flag */ + ZipConstants.SHORT + /* compression method */ + ZipConstants.SHORT + /* last mod file time */ + ZipConstants.SHORT + /* last mod file date */ + ZipConstants.SHORT + /* crc-32 */ + ZipConstants.WORD + /* compressed size */ + ZipConstants.WORD + /* uncompressed size */ + ZipConstants.WORD + /* file name length */ + ZipConstants. SHORT + /* extra field length */ + ZipConstants.SHORT + /* file comment length */ + ZipConstants.SHORT + /* disk number start */ + ZipConstants.SHORT + /* internal file attributes */ + ZipConstants.SHORT + /* external file attributes */ + ZipConstants.WORD + /* relative offset of local header */ + ZipConstants.WORD; + + private static final long CFH_SIG = + ZipLong.getValue(ZipArchiveOutputStream.CFH_SIG); + + /** + * Length of the "End of central directory record" - which is + * supposed to be the last structure of the archive - without file + * comment. + */ + static final int MIN_EOCD_SIZE = + /* end of central dir signature */ ZipConstants.WORD + /* number of this disk */ + ZipConstants.SHORT + /* number of the disk with the */ + /* start of the central directory */ + ZipConstants.SHORT + /* total number of entries in */ + /* the central dir on this disk */ + ZipConstants.SHORT + /* total number of entries in */ + /* the central dir */ + ZipConstants.SHORT + /* size of the central directory */ + ZipConstants.WORD + /* offset of start of central */ + /* directory with respect to */ + /* the starting disk number */ + ZipConstants.WORD + /* zipfile comment length */ + ZipConstants.SHORT; + + /** + * Maximum length of the "End of central directory record" with a + * file comment. + */ + private static final int MAX_EOCD_SIZE = MIN_EOCD_SIZE + /* maximum length of zipfile comment */ + ZipConstants.ZIP64_MAGIC_SHORT; + + /** + * Offset of the field that holds the location of the length of + * the central directory inside the "End of central directory + * record" relative to the start of the "End of central directory + * record". + */ + private static final int CFD_LENGTH_OFFSET = + /* end of central dir signature */ ZipConstants.WORD + /* number of this disk */ + ZipConstants.SHORT + /* number of the disk with the */ + /* start of the central directory */ + ZipConstants.SHORT + /* total number of entries in */ + /* the central dir on this disk */ + ZipConstants.SHORT + /* total number of entries in */ + /* the central dir */ + ZipConstants.SHORT; + + /** + * Offset of the field that holds the disk number of the first + * central directory entry inside the "End of central directory + * record" relative to the start of the "End of central directory + * record". + */ + private static final int CFD_DISK_OFFSET = + /* end of central dir signature */ ZipConstants.WORD + /* number of this disk */ + ZipConstants.SHORT; + /** + * Offset of the field that holds the location of the first + * central directory entry inside the "End of central directory + * record" relative to the "number of the disk with the start + * of the central directory". + */ + private static final int CFD_LOCATOR_RELATIVE_OFFSET = + /* total number of entries in */ + /* the central dir on this disk */ + ZipConstants.SHORT + /* total number of entries in */ + /* the central dir */ + ZipConstants.SHORT + /* size of the central directory */ + ZipConstants.WORD; + /** + * Length of the "Zip64 end of central directory locator" - which + * should be right in front of the "end of central directory + * record" if one is present at all. + */ + private static final int ZIP64_EOCDL_LENGTH = + /* zip64 end of central dir locator sig */ ZipConstants.WORD + /* number of the disk with the start */ + /* start of the zip64 end of */ + /* central directory */ + ZipConstants.WORD + /* relative offset of the zip64 */ + /* end of central directory record */ + ZipConstants.DWORD + /* total number of disks */ + ZipConstants.WORD; + /** + * Offset of the field that holds the location of the "Zip64 end + * of central directory record" inside the "Zip64 end of central + * directory locator" relative to the start of the "Zip64 end of + * central directory locator". + */ + private static final int ZIP64_EOCDL_LOCATOR_OFFSET = + /* zip64 end of central dir locator sig */ ZipConstants.WORD + /* number of the disk with the start */ + /* start of the zip64 end of */ + /* central directory */ + ZipConstants.WORD; + /** + * Offset of the field that holds the location of the first + * central directory entry inside the "Zip64 end of central + * directory record" relative to the start of the "Zip64 end of + * central directory record". + */ + private static final int ZIP64_EOCD_CFD_LOCATOR_OFFSET = + /* zip64 end of central dir */ + /* signature */ ZipConstants.WORD + /* size of zip64 end of central */ + /* directory record */ + ZipConstants.DWORD + /* version made by */ + ZipConstants.SHORT + /* version needed to extract */ + ZipConstants.SHORT + /* number of this disk */ + ZipConstants.WORD + /* number of the disk with the */ + /* start of the central directory */ + ZipConstants.WORD + /* total number of entries in the */ + /* central directory on this disk */ + ZipConstants.DWORD + /* total number of entries in the */ + /* central directory */ + ZipConstants.DWORD + /* size of the central directory */ + ZipConstants.DWORD; + /** + * Offset of the field that holds the disk number of the first + * central directory entry inside the "Zip64 end of central + * directory record" relative to the start of the "Zip64 end of + * central directory record". + */ + private static final int ZIP64_EOCD_CFD_DISK_OFFSET = + /* zip64 end of central dir */ + /* signature */ ZipConstants.WORD + /* size of zip64 end of central */ + /* directory record */ + ZipConstants.DWORD + /* version made by */ + ZipConstants.SHORT + /* version needed to extract */ + ZipConstants.SHORT + /* number of this disk */ + ZipConstants.WORD; + /** + * Offset of the field that holds the location of the first + * central directory entry inside the "Zip64 end of central + * directory record" relative to the "number of the disk + * with the start of the central directory". + */ + private static final int ZIP64_EOCD_CFD_LOCATOR_RELATIVE_OFFSET = + /* total number of entries in the */ + /* central directory on this disk */ ZipConstants.DWORD + /* total number of entries in the */ + /* central directory */ + ZipConstants.DWORD + /* size of the central directory */ + ZipConstants.DWORD; + /** + * Number of bytes in local file header up to the "length of + * file name" entry. + */ + private static final long LFH_OFFSET_FOR_FILENAME_LENGTH = + /* local file header signature */ ZipConstants.WORD + /* version needed to extract */ + ZipConstants.SHORT + /* general purpose bit flag */ + ZipConstants.SHORT + /* compression method */ + ZipConstants.SHORT + /* last mod file time */ + ZipConstants.SHORT + /* last mod file date */ + ZipConstants.SHORT + /* crc-32 */ + ZipConstants.WORD + /* compressed size */ + ZipConstants.WORD + /* uncompressed size */ + (long) ZipConstants.WORD; + + /** + * close a zipfile quietly; throw no io fault, do nothing + * on a null parameter + * @param zipfile file to close, can be null + */ + public static void closeQuietly(final ZipFile zipfile) { + IOUtils.closeQuietly(zipfile); + } + /** + * List of entries in the order they appear inside the central + * directory. + */ + private final List entries = + new LinkedList<>(); + /** + * Maps String to list of ZipArchiveEntrys, name -> actual entries. + */ + private final Map> nameMap = + new HashMap<>(HASH_SIZE); + + /** + * The encoding to use for file names and the file comment. + * + *

For a list of possible values see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html. + * Defaults to UTF-8.

+ */ + private final String encoding; + + /** + * The ZIP encoding to use for file names and the file comment. + */ + private final ZipEncoding zipEncoding; + + /** + * File name of actual source. + */ + private final String archiveName; + + /** + * The actual data source. + */ + private final SeekableByteChannel archive; + + /** + * Whether to look for and use Unicode extra fields. + */ + private final boolean useUnicodeExtraFields; + + /** + * Whether the file is closed. + */ + private volatile boolean closed = true; + + /** + * Whether the ZIP archive is a split ZIP archive + */ + private final boolean isSplitZipArchive; + + // cached buffers - must only be used locally in the class (COMPRESS-172 - reduce garbage collection) + private final byte[] dwordBuf = new byte[ZipConstants.DWORD]; + + private final byte[] wordBuf = new byte[ZipConstants.WORD]; + + private final byte[] cfhBuf = new byte[CFH_LEN]; + + private final byte[] shortBuf = new byte[ZipConstants.SHORT]; + + private final ByteBuffer dwordBbuf = ByteBuffer.wrap(dwordBuf); + + private final ByteBuffer wordBbuf = ByteBuffer.wrap(wordBuf); + + private final ByteBuffer cfhBbuf = ByteBuffer.wrap(cfhBuf); + + private final ByteBuffer shortBbuf = ByteBuffer.wrap(shortBuf); + + private long centralDirectoryStartDiskNumber, centralDirectoryStartRelativeOffset; + + private long centralDirectoryStartOffset; + + private long firstLocalFileHeaderOffset; + + /** + * Compares two ZipArchiveEntries based on their offset within the archive. + * + *

Won't return any meaningful results if one of the entries + * isn't part of the archive at all.

+ * + * @since 1.1 + */ + private static final Comparator offsetComparator = + (e1, e2) -> { + final int diskNumberStartComparison = + Long.compare(e1.getDiskNumberStart(), e2.getDiskNumberStart()); + if (diskNumberStartComparison != 0) { + return diskNumberStartComparison; + } else { + return Long.compare(e1.getLocalHeaderOffset(), e2.getLocalHeaderOffset()); + } + }; + + /** + * Opens the given channel for reading, assuming "UTF8" for file names. + * + * @param channel the archive. + * + * @throws IOException if an error occurs while reading the file. + * @since 1.13 + */ + public ZipFile(final SeekableByteChannel channel) + throws IOException { + this(channel, "unknown archive", ZipEncodingHelper.UTF8, true); + } + + /** + * Opens the given channel for reading, assuming the specified + * encoding for file names. + * + * @param channel the archive. + * @param encoding the encoding to use for file names, use null + * for the platform's default encoding + * + * @throws IOException if an error occurs while reading the file. + * @since 1.13 + */ + public ZipFile(final SeekableByteChannel channel, final String encoding) + throws IOException { + this(channel, "unknown archive", encoding, true); + } + + public ZipFile(final SeekableByteChannel channel, final boolean ignoreLocalFileHeader) + throws IOException { + this(channel, "unknown archive", ZipEncodingHelper.UTF8, true, false, ignoreLocalFileHeader); + } + + /** + * Opens the given channel for reading, assuming the specified + * encoding for file names. + * + * @param channel the archive. + * @param archiveName name of the archive, used for error messages only. + * @param encoding the encoding to use for file names, use null + * for the platform's default encoding + * @param useUnicodeExtraFields whether to use InfoZIP Unicode + * Extra Fields (if present) to set the file names. + * + * @throws IOException if an error occurs while reading the file. + * @since 1.13 + */ + public ZipFile(final SeekableByteChannel channel, final String archiveName, + final String encoding, final boolean useUnicodeExtraFields) + throws IOException { + this(channel, archiveName, encoding, useUnicodeExtraFields, false, false); + } + + /** + * Opens the given channel for reading, assuming the specified + * encoding for file names. + * + *

By default the central directory record and all local file headers of the archive will be read immediately + * which may take a considerable amount of time when the archive is big. The {@code ignoreLocalFileHeader} parameter + * can be set to {@code true} which restricts parsing to the central directory. Unfortunately the local file header + * may contain information not present inside of the central directory which will not be available when the argument + * is set to {@code true}. This includes the content of the Unicode extra field, so setting {@code + * ignoreLocalFileHeader} to {@code true} means {@code useUnicodeExtraFields} will be ignored effectively.

+ * + * @param channel the archive. + * @param archiveName name of the archive, used for error messages only. + * @param encoding the encoding to use for file names, use null + * for the platform's default encoding + * @param useUnicodeExtraFields whether to use InfoZIP Unicode + * Extra Fields (if present) to set the file names. + * @param ignoreLocalFileHeader whether to ignore information + * stored inside the local file header (see the notes in this method's javadoc) + * + * @throws IOException if an error occurs while reading the file. + * @since 1.19 + */ + public ZipFile(final SeekableByteChannel channel, final String archiveName, + final String encoding, final boolean useUnicodeExtraFields, + final boolean ignoreLocalFileHeader) + throws IOException { + this(channel, archiveName, encoding, useUnicodeExtraFields, false, ignoreLocalFileHeader); + } + + private ZipFile(final SeekableByteChannel channel, final String archiveName, + final String encoding, final boolean useUnicodeExtraFields, + final boolean closeOnError, final boolean ignoreLocalFileHeader) + throws IOException { + isSplitZipArchive = (channel instanceof ZipSplitReadOnlySeekableByteChannel); + + this.archiveName = archiveName; + this.encoding = encoding; + this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding); + this.useUnicodeExtraFields = useUnicodeExtraFields; + archive = channel; + boolean success = false; + try { + final Map entriesWithoutUTF8Flag = + populateFromCentralDirectory(); + if (!ignoreLocalFileHeader) { + resolveLocalFileHeaderData(entriesWithoutUTF8Flag); + } + fillNameMap(); + success = true; + } catch (final IOException e) { + throw new IOException("Error on ZipFile " + archiveName, e); + } finally { + closed = !success; + if (!success && closeOnError) { + IOUtils.closeQuietly(archive); + } + } + } + + /** + * Whether this class is able to read the given entry. + * + *

May return false if it is set up to use encryption or a + * compression method that hasn't been implemented yet.

+ * @since 1.1 + * @param ze the entry + * @return whether this class is able to read the given entry. + */ + public boolean canReadEntryData(final ZipArchiveEntry ze) { + return ZipUtil.canHandleEntryData(ze); + } + + /** + * Closes the archive. + * @throws IOException if an error occurs closing the archive. + */ + @Override + public void close() throws IOException { + // this flag is only written here and read in finalize() which + // can never be run in parallel. + // no synchronization needed. + closed = true; + + archive.close(); + } + + /** + * Transfer selected entries from this zipfile to a given #ZipArchiveOutputStream. + * Compression and all other attributes will be as in this file. + *

This method transfers entries based on the central directory of the ZIP file.

+ * + * @param target The zipArchiveOutputStream to write the entries to + * @param predicate A predicate that selects which entries to write + * @throws IOException on error + */ + public void copyRawEntries(final ZipArchiveOutputStream target, final ZipArchiveEntryPredicate predicate) + throws IOException { + final Enumeration src = getEntriesInPhysicalOrder(); + while (src.hasMoreElements()) { + final ZipArchiveEntry entry = src.nextElement(); + if (predicate.test( entry)) { + target.addRawArchiveEntry(entry, getRawInputStream(entry)); + } + } + } + + /** + * Creates new BoundedInputStream, according to implementation of + * underlying archive channel. + */ + private BoundedArchiveInputStream createBoundedInputStream(final long start, final long remaining) { + if (start < 0 || remaining < 0 || start + remaining < start) { + throw new IllegalArgumentException("Corrupted archive, stream boundaries" + + " are out of range"); + } + return new BoundedSeekableByteChannelInputStream(start, remaining, archive); + } + + private void fillNameMap() { + for (ZipArchiveEntry ze: entries) { + // entries is filled in populateFromCentralDirectory and + // never modified + final String name = ze.getName(); + if (!nameMap.containsKey(name)) { + nameMap.put(name, new LinkedList<>()); + } + final LinkedList entriesOfThatName = + Objects.requireNonNull(nameMap.get(name)); + entriesOfThatName.addLast(ze); + } + } + + /** + * Ensures that the close method of this zipfile is called when + * there are no more references to it. + * @see #close() + */ + @Override + protected void finalize() throws Throwable { + try { + if (!closed) { + System.err.println("Cleaning up unclosed ZipFile for archive " + + archiveName); + close(); + } + } finally { + super.finalize(); + } + } + + /** + * Gets an InputStream for reading the content before the first local file header. + * + * @return null if there is no content before the first local file header. + * Otherwise returns a stream to read the content before the first local file header. + * @since 1.23 + */ + public InputStream getContentBeforeFirstLocalFileHeader() { + return firstLocalFileHeaderOffset == 0 + ? null : createBoundedInputStream(0, firstLocalFileHeaderOffset); + } + + private long getDataOffset(final ZipArchiveEntry ze) throws IOException { + final long s = ze.getDataOffset(); + if (s == EntryStreamOffsets.OFFSET_UNKNOWN) { + setDataOffset(ze); + return ze.getDataOffset(); + } + return s; + } + + /** + * Gets the encoding to use for file names and the file comment. + * + * @return null if using the platform's default character encoding. + */ + public String getEncoding() { + return encoding; + } + + /** + * Gets all entries. + * + *

Entries will be returned in the same order they appear + * within the archive's central directory.

+ * + * @return all entries as {@link ZipArchiveEntry} instances + */ + public Enumeration getEntries() { + return Collections.enumeration(entries); + } + + /** + * Gets all named entries in the same order they appear within + * the archive's central directory. + * + * @param name name of the entry. + * @return the Iterable<ZipArchiveEntry> corresponding to the + * given name + * @since 1.6 + */ + public Iterable getEntries(final String name) { + final List entriesOfThatName = nameMap.get(name); + return entriesOfThatName != null ? entriesOfThatName + : Collections.emptyList(); + } + + /** + * Gets all entries in physical order. + * + *

Entries will be returned in the same order their contents + * appear within the archive.

+ * + * @return all entries as {@link ZipArchiveEntry} instances + * + * @since 1.1 + */ + public Enumeration getEntriesInPhysicalOrder() { + final ZipArchiveEntry[] allEntries = entries.toArray(ZipArchiveEntry.EMPTY_ARRAY); + Arrays.sort(allEntries, offsetComparator); + return Collections.enumeration(Arrays.asList(allEntries)); + } + + /** + * Gets all named entries in the same order their contents + * appear within the archive. + * + * @param name name of the entry. + * @return the Iterable<ZipArchiveEntry> corresponding to the + * given name + * @since 1.6 + */ + public Iterable getEntriesInPhysicalOrder(final String name) { + ZipArchiveEntry[] entriesOfThatName = ZipArchiveEntry.EMPTY_ARRAY; + final LinkedList linkedList = nameMap.get(name); + if (linkedList != null) { + entriesOfThatName = linkedList.toArray(entriesOfThatName); + Arrays.sort(entriesOfThatName, offsetComparator); + } + return Arrays.asList(entriesOfThatName); + } + + /** + * Gets a named entry or {@code null} if no entry by + * that name exists. + * + *

If multiple entries with the same name exist the first entry + * in the archive's central directory by that name is + * returned.

+ * + * @param name name of the entry. + * @return the ZipArchiveEntry corresponding to the given name - or + * {@code null} if not present. + */ + public ZipArchiveEntry getEntry(final String name) { + final LinkedList entriesOfThatName = nameMap.get(name); + return entriesOfThatName != null ? entriesOfThatName.getFirst() : null; + } + + /** + * Gets the offset of the first local file header in the file. + * + * @return the length of the content before the first local file header + * @since 1.23 + */ + public long getFirstLocalFileHeaderOffset() { + return firstLocalFileHeaderOffset; + } + + /** + * Gets an InputStream for reading the contents of the given entry. + * + * @param ze the entry to get the stream for. + * @return a stream to read the entry from. The returned stream + * implements {@link InputStreamStatistics}. + * @throws IOException if unable to create an input stream from the zipentry + */ + public InputStream getInputStream(final ZipArchiveEntry ze) + throws IOException { + if (!(ze instanceof Entry)) { + return null; + } + // cast validity is checked just above + ZipUtil.checkRequestedFeatures(ze); + + // doesn't get closed if the method is not supported - which + // should never happen because of the checkRequestedFeatures + // call above + final InputStream is = new BufferedInputStream(getRawInputStream(ze)); //NOSONAR + switch (ZipMethod.getMethodByCode(ze.getMethod())) { + case STORED: + return new StoredStatisticsStream(is); + case DEFLATED: + final Inflater inflater = new Inflater(true); + // Inflater with nowrap=true has this odd contract for a zero padding + // byte following the data stream; this used to be zlib's requirement + // and has been fixed a long time ago, but the contract persists so + // we comply. + // https://docs.oracle.com/javase/7/docs/api/java/util/zip/Inflater.html#Inflater(boolean) + return new InflaterInputStreamWithStatistics(new SequenceInputStream(is, new ByteArrayInputStream(ONE_ZERO_BYTE)), + inflater) { + @Override + public void close() throws IOException { + try { + super.close(); + } finally { + inflater.end(); + } + } + }; + case BZIP2: + case ENHANCED_DEFLATED: + case AES_ENCRYPTED: + case EXPANDING_LEVEL_1: + case EXPANDING_LEVEL_2: + case EXPANDING_LEVEL_3: + case EXPANDING_LEVEL_4: + case IMPLODING: + case JPEG: + case LZMA: + case PKWARE_IMPLODING: + case PPMD: + case TOKENIZATION: + case UNKNOWN: + case UNSHRINKING: + case WAVPACK: + case XZ: + default: + throw new UnsupportedZipFeatureException(ZipMethod.getMethodByCode(ze.getMethod()), ze); + } + } + + /** + * Gets the raw stream of the archive entry (compressed form). + * + *

This method does not relate to how/if we understand the payload in the + * stream, since we really only intend to move it on to somewhere else.

+ * + *

Since version 1.22, this method will make an attempt to read the entry's data + * stream offset, even if the {@code ignoreLocalFileHeader} parameter was {@code true} + * in the constructor. An IOException can also be thrown from the body of the method + * if this lookup fails for some reason.

+ * + * @param ze The entry to get the stream for + * @return The raw input stream containing (possibly) compressed data. + * @since 1.11 + * @throws IOException if there is a problem reading data offset (added in version 1.22). + */ + public InputStream getRawInputStream(final ZipArchiveEntry ze) throws IOException { + if (!(ze instanceof Entry)) { + return null; + } + + final long start = getDataOffset(ze); + if (start == EntryStreamOffsets.OFFSET_UNKNOWN) { + return null; + } + return createBoundedInputStream(start, ze.getCompressedSize()); + } + + // Readium-added + /** + *

Gets the raw stream of the stored archive entry starting from fromIndex.

+ * + *

This method does not relate to how/if we understand the payload in the + * stream, since we really only intend to move it on to somewhere else.

+ * + * @param ze The stored entry to get the stream for + * @param fromIndex The index in the entry that the stream will start from + * @return The raw input stream containing data. + * @throws IOException if there is a problem reading data offset. + */ + public InputStream getRawInputStream(final ZipArchiveEntry ze, final long fromIndex) throws IOException { + if (!(ze instanceof Entry)) { + return null; + } + + final long start = getDataOffset(ze); + if (start == EntryStreamOffsets.OFFSET_UNKNOWN) { + return null; + } + + if (ZipMethod.getMethodByCode(ze.getMethod()) != ZipMethod.STORED) { + throw new IllegalArgumentException("Cannot begin a stream at a specific index in compressed entries."); + } + + if (fromIndex >= ze.getSize()) { + throw new IllegalArgumentException("fromIndex out of bounds."); + } + + return createBoundedInputStream(start + fromIndex, ze.getSize() - fromIndex); + } + + /** + * Gets the entry's content as a String if isUnixSymlink() + * returns true for it, otherwise returns null. + *

This method assumes the symbolic link's file name uses the + * same encoding that as been specified for this ZipFile.

+ * + * @param entry ZipArchiveEntry object that represents the symbolic link + * @return entry's content as a String + * @throws IOException problem with content's input stream + * @since 1.5 + */ + public String getUnixSymlink(final ZipArchiveEntry entry) throws IOException { + if (entry != null && entry.isUnixSymlink()) { + try (InputStream in = getInputStream(entry)) { + return zipEncoding.decode(IOUtils.toByteArray(in)); + } + } + return null; + } + + /** + * Reads the central directory of the given archive and populates + * the internal tables with ZipArchiveEntry instances. + * + *

The ZipArchiveEntrys will know all data that can be obtained from + * the central directory alone, but not the data that requires the + * local file header or additional data to be read.

+ * + * @return a map of zipentries that didn't have the language + * encoding flag set when read. + */ + private Map populateFromCentralDirectory() + throws IOException { + final HashMap noUTF8Flag = + new HashMap<>(); + + positionAtCentralDirectory(); + centralDirectoryStartOffset = archive.position(); + + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + long sig = ZipLong.getValue(wordBuf); + + if (sig != CFH_SIG && startsWithLocalFileHeader()) { + throw new IOException("Central directory is empty, can't expand" + + " corrupt archive."); + } + + while (sig == CFH_SIG) { + readCentralDirectoryEntry(noUTF8Flag); + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + sig = ZipLong.getValue(wordBuf); + } + return noUTF8Flag; + } + + /** + * Searches for either the "Zip64 end of central directory + * locator" or the "End of central dir record", parses + * it and positions the stream at the first central directory + * record. + */ + private void positionAtCentralDirectory() + throws IOException { + positionAtEndOfCentralDirectoryRecord(); + boolean found = false; + final boolean searchedForZip64EOCD = + archive.position() > ZIP64_EOCDL_LENGTH; + if (searchedForZip64EOCD) { + archive.position(archive.position() - ZIP64_EOCDL_LENGTH); + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + found = Arrays.equals(ZipArchiveOutputStream.ZIP64_EOCD_LOC_SIG, + wordBuf); + } + if (!found) { + // not a ZIP64 archive + if (searchedForZip64EOCD) { + skipBytes(ZIP64_EOCDL_LENGTH - ZipConstants.WORD); + } + positionAtCentralDirectory32(); + } else { + positionAtCentralDirectory64(); + } + } + + /** + * Parses the "End of central dir record" and positions + * the stream at the first central directory record. + * + * Expects stream to be positioned at the beginning of the + * "End of central dir record". + */ + private void positionAtCentralDirectory32() + throws IOException { + final long endOfCentralDirectoryRecordOffset = archive.position(); + if (isSplitZipArchive) { + skipBytes(CFD_DISK_OFFSET); + shortBbuf.rewind(); + IOUtils.readFully(archive, shortBbuf); + centralDirectoryStartDiskNumber = ZipShort.getValue(shortBuf); + + skipBytes(CFD_LOCATOR_RELATIVE_OFFSET); + + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + centralDirectoryStartRelativeOffset = ZipLong.getValue(wordBuf); + ((ZipSplitReadOnlySeekableByteChannel) archive) + .position(centralDirectoryStartDiskNumber, centralDirectoryStartRelativeOffset); + } else { + skipBytes(CFD_LENGTH_OFFSET); + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + final long centralDirectoryLength = ZipLong.getValue(wordBuf); + + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + centralDirectoryStartDiskNumber = 0; + centralDirectoryStartRelativeOffset = ZipLong.getValue(wordBuf); + + firstLocalFileHeaderOffset = Long.max( + endOfCentralDirectoryRecordOffset - centralDirectoryLength - centralDirectoryStartRelativeOffset, + 0L); + archive.position(centralDirectoryStartRelativeOffset + firstLocalFileHeaderOffset); + } + } + + /** + * Parses the "Zip64 end of central directory locator", + * finds the "Zip64 end of central directory record" using the + * parsed information, parses that and positions the stream at the + * first central directory record. + * + * Expects stream to be positioned right behind the "Zip64 + * end of central directory locator"'s signature. + */ + private void positionAtCentralDirectory64() + throws IOException { + if (isSplitZipArchive) { + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + final long diskNumberOfEOCD = ZipLong.getValue(wordBuf); + + dwordBbuf.rewind(); + IOUtils.readFully(archive, dwordBbuf); + final long relativeOffsetOfEOCD = ZipEightByteInteger.getLongValue(dwordBuf); + ((ZipSplitReadOnlySeekableByteChannel) archive) + .position(diskNumberOfEOCD, relativeOffsetOfEOCD); + } else { + skipBytes(ZIP64_EOCDL_LOCATOR_OFFSET + - ZipConstants.WORD /* signature has already been read */); + dwordBbuf.rewind(); + IOUtils.readFully(archive, dwordBbuf); + archive.position(ZipEightByteInteger.getLongValue(dwordBuf)); + } + + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + if (!Arrays.equals(wordBuf, ZipArchiveOutputStream.ZIP64_EOCD_SIG)) { + throw new ZipException("Archive's ZIP64 end of central " + + "directory locator is corrupt."); + } + + if (isSplitZipArchive) { + skipBytes(ZIP64_EOCD_CFD_DISK_OFFSET + - ZipConstants.WORD /* signature has already been read */); + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + centralDirectoryStartDiskNumber = ZipLong.getValue(wordBuf); + + skipBytes(ZIP64_EOCD_CFD_LOCATOR_RELATIVE_OFFSET); + + dwordBbuf.rewind(); + IOUtils.readFully(archive, dwordBbuf); + centralDirectoryStartRelativeOffset = ZipEightByteInteger.getLongValue(dwordBuf); + ((ZipSplitReadOnlySeekableByteChannel) archive) + .position(centralDirectoryStartDiskNumber, centralDirectoryStartRelativeOffset); + } else { + skipBytes(ZIP64_EOCD_CFD_LOCATOR_OFFSET + - ZipConstants.WORD /* signature has already been read */); + dwordBbuf.rewind(); + IOUtils.readFully(archive, dwordBbuf); + centralDirectoryStartDiskNumber = 0; + centralDirectoryStartRelativeOffset = ZipEightByteInteger.getLongValue(dwordBuf); + archive.position(centralDirectoryStartRelativeOffset); + } + } + + /** + * Searches for the and positions the stream at the start of the + * "End of central dir record". + */ + private void positionAtEndOfCentralDirectoryRecord() + throws IOException { + final boolean found = tryToLocateSignature(MIN_EOCD_SIZE, MAX_EOCD_SIZE, + ZipArchiveOutputStream.EOCD_SIG); + if (!found) { + throw new ZipException("Archive is not a ZIP archive"); + } + } + + /** + * Reads an individual entry of the central directory, creats an + * ZipArchiveEntry from it and adds it to the global maps. + * + * @param noUTF8Flag map used to collect entries that don't have + * their UTF-8 flag set and whose name will be set by data read + * from the local file header later. The current entry may be + * added to this map. + */ + private void + readCentralDirectoryEntry(final Map noUTF8Flag) + throws IOException { + cfhBbuf.rewind(); + IOUtils.readFully(archive, cfhBbuf); + int off = 0; + final Entry ze = new Entry(); + + final int versionMadeBy = ZipShort.getValue(cfhBuf, off); + off += ZipConstants.SHORT; + ze.setVersionMadeBy(versionMadeBy); + ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK); + + ze.setVersionRequired(ZipShort.getValue(cfhBuf, off)); + off += ZipConstants.SHORT; // version required + + final GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(cfhBuf, off); + final boolean hasUTF8Flag = gpFlag.usesUTF8ForNames(); + final ZipEncoding entryEncoding = + hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding; + if (hasUTF8Flag) { + ze.setNameSource(ZipArchiveEntry.NameSource.NAME_WITH_EFS_FLAG); + } + ze.setGeneralPurposeBit(gpFlag); + ze.setRawFlag(ZipShort.getValue(cfhBuf, off)); + + off += ZipConstants.SHORT; + + //noinspection MagicConstant + ze.setMethod(ZipShort.getValue(cfhBuf, off)); + off += ZipConstants.SHORT; + + final long time = ZipUtil.dosToJavaTime(ZipLong.getValue(cfhBuf, off)); + ze.setTime(time); + off += ZipConstants.WORD; + + ze.setCrc(ZipLong.getValue(cfhBuf, off)); + off += ZipConstants.WORD; + + long size = ZipLong.getValue(cfhBuf, off); + if (size < 0) { + throw new IOException("broken archive, entry with negative compressed size"); + } + ze.setCompressedSize(size); + off += ZipConstants.WORD; + + size = ZipLong.getValue(cfhBuf, off); + if (size < 0) { + throw new IOException("broken archive, entry with negative size"); + } + ze.setSize(size); + off += ZipConstants.WORD; + + final int fileNameLen = ZipShort.getValue(cfhBuf, off); + off += ZipConstants.SHORT; + if (fileNameLen < 0) { + throw new IOException("broken archive, entry with negative fileNameLen"); + } + + final int extraLen = ZipShort.getValue(cfhBuf, off); + off += ZipConstants.SHORT; + if (extraLen < 0) { + throw new IOException("broken archive, entry with negative extraLen"); + } + + final int commentLen = ZipShort.getValue(cfhBuf, off); + off += ZipConstants.SHORT; + if (commentLen < 0) { + throw new IOException("broken archive, entry with negative commentLen"); + } + + ze.setDiskNumberStart(ZipShort.getValue(cfhBuf, off)); + off += ZipConstants.SHORT; + + ze.setInternalAttributes(ZipShort.getValue(cfhBuf, off)); + off += ZipConstants.SHORT; + + ze.setExternalAttributes(ZipLong.getValue(cfhBuf, off)); + off += ZipConstants.WORD; + + final byte[] fileName = IOUtils.readRange(archive, fileNameLen); + if (fileName.length < fileNameLen) { + throw new EOFException(); + } + ze.setName(entryEncoding.decode(fileName), fileName); + + // LFH offset, + ze.setLocalHeaderOffset(ZipLong.getValue(cfhBuf, off) + firstLocalFileHeaderOffset); + // data offset will be filled later + entries.add(ze); + + final byte[] cdExtraData = IOUtils.readRange(archive, extraLen); + if (cdExtraData.length < extraLen) { + throw new EOFException(); + } + try { + ze.setCentralDirectoryExtra(cdExtraData); + } catch (final RuntimeException ex) { + final ZipException z = new ZipException("Invalid extra data in entry " + ze.getName()); + z.initCause(ex); + throw z; + } + + setSizesAndOffsetFromZip64Extra(ze); + sanityCheckLFHOffset(ze); + + final byte[] comment = IOUtils.readRange(archive, commentLen); + if (comment.length < commentLen) { + throw new EOFException(); + } + ze.setComment(entryEncoding.decode(comment)); + + if (!hasUTF8Flag && useUnicodeExtraFields) { + noUTF8Flag.put(ze, new NameAndComment(fileName, comment)); + } + + ze.setStreamContiguous(true); + } + + /** + * Walks through all recorded entries and adds the data available + * from the local file header. + * + *

Also records the offsets for the data to read from the + * entries.

+ */ + private void resolveLocalFileHeaderData(final Map + entriesWithoutUTF8Flag) + throws IOException { + for (final ZipArchiveEntry zipArchiveEntry : entries) { + // entries is filled in populateFromCentralDirectory and + // never modified + final Entry ze = (Entry) zipArchiveEntry; + final int[] lens = setDataOffset(ze); + final int fileNameLen = lens[0]; + final int extraFieldLen = lens[1]; + skipBytes(fileNameLen); + final byte[] localExtraData = IOUtils.readRange(archive, extraFieldLen); + if (localExtraData.length < extraFieldLen) { + throw new EOFException(); + } + try { + ze.setExtra(localExtraData); + } catch (final RuntimeException ex) { + final ZipException z = new ZipException("Invalid extra data in entry " + ze.getName()); + z.initCause(ex); + throw z; + } + + if (entriesWithoutUTF8Flag.containsKey(ze)) { + final NameAndComment nc = entriesWithoutUTF8Flag.get(ze); + ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name, + nc.comment); + } + } + } + + private void sanityCheckLFHOffset(final ZipArchiveEntry ze) throws IOException { + if (ze.getDiskNumberStart() < 0) { + throw new IOException("broken archive, entry with negative disk number"); + } + if (ze.getLocalHeaderOffset() < 0) { + throw new IOException("broken archive, entry with negative local file header offset"); + } + if (isSplitZipArchive) { + if (ze.getDiskNumberStart() > centralDirectoryStartDiskNumber) { + throw new IOException("local file header for " + ze.getName() + " starts on a later disk than central directory"); + } + if (ze.getDiskNumberStart() == centralDirectoryStartDiskNumber + && ze.getLocalHeaderOffset() > centralDirectoryStartRelativeOffset) { + throw new IOException("local file header for " + ze.getName() + " starts after central directory"); + } + } else if (ze.getLocalHeaderOffset() > centralDirectoryStartOffset) { + throw new IOException("local file header for " + ze.getName() + " starts after central directory"); + } + } + + private int[] setDataOffset(final ZipArchiveEntry ze) throws IOException { + long offset = ze.getLocalHeaderOffset(); + if (isSplitZipArchive) { + ((ZipSplitReadOnlySeekableByteChannel) archive) + .position(ze.getDiskNumberStart(), offset + LFH_OFFSET_FOR_FILENAME_LENGTH); + // the offset should be updated to the global offset + offset = archive.position() - LFH_OFFSET_FOR_FILENAME_LENGTH; + } else { + archive.position(offset + LFH_OFFSET_FOR_FILENAME_LENGTH); + } + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + wordBbuf.flip(); + wordBbuf.get(shortBuf); + final int fileNameLen = ZipShort.getValue(shortBuf); + wordBbuf.get(shortBuf); + final int extraFieldLen = ZipShort.getValue(shortBuf); + ze.setDataOffset(offset + LFH_OFFSET_FOR_FILENAME_LENGTH + + ZipConstants.SHORT + ZipConstants.SHORT + fileNameLen + extraFieldLen); + if (ze.getDataOffset() + ze.getCompressedSize() > centralDirectoryStartOffset) { + throw new IOException("data for " + ze.getName() + " overlaps with central directory."); + } + return new int[] { fileNameLen, extraFieldLen }; + } + + /** + * If the entry holds a Zip64 extended information extra field, + * read sizes from there if the entry's sizes are set to + * 0xFFFFFFFFF, do the same for the offset of the local file + * header. + * + *

Ensures the Zip64 extra either knows both compressed and + * uncompressed size or neither of both as the internal logic in + * ExtraFieldUtils forces the field to create local header data + * even if they are never used - and here a field with only one + * size would be invalid.

+ */ + private void setSizesAndOffsetFromZip64Extra(final ZipArchiveEntry ze) + throws IOException { + final ZipExtraField extra = + ze.getExtraField(Zip64ExtendedInformationExtraField.HEADER_ID); + if (extra != null && !(extra instanceof Zip64ExtendedInformationExtraField)) { + throw new ZipException("archive contains unparseable zip64 extra field"); + } + final Zip64ExtendedInformationExtraField z64 = + (Zip64ExtendedInformationExtraField) extra; + if (z64 != null) { + final boolean hasUncompressedSize = ze.getSize() == ZipConstants.ZIP64_MAGIC; + final boolean hasCompressedSize = ze.getCompressedSize() == ZipConstants.ZIP64_MAGIC; + final boolean hasRelativeHeaderOffset = + ze.getLocalHeaderOffset() == ZipConstants.ZIP64_MAGIC; + final boolean hasDiskStart = ze.getDiskNumberStart() == ZipConstants.ZIP64_MAGIC_SHORT; + z64.reparseCentralDirectoryData(hasUncompressedSize, + hasCompressedSize, + hasRelativeHeaderOffset, + hasDiskStart); + + if (hasUncompressedSize) { + final long size = z64.getSize().getLongValue(); + if (size < 0) { + throw new IOException("broken archive, entry with negative size"); + } + ze.setSize(size); + } else if (hasCompressedSize) { + z64.setSize(new ZipEightByteInteger(ze.getSize())); + } + + if (hasCompressedSize) { + final long size = z64.getCompressedSize().getLongValue(); + if (size < 0) { + throw new IOException("broken archive, entry with negative compressed size"); + } + ze.setCompressedSize(size); + } else if (hasUncompressedSize) { + z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize())); + } + + if (hasRelativeHeaderOffset) { + ze.setLocalHeaderOffset(z64.getRelativeHeaderOffset().getLongValue()); + } + + if (hasDiskStart) { + ze.setDiskNumberStart(z64.getDiskStartNumber().getValue()); + } + } + } + + /** + * Skips the given number of bytes or throws an EOFException if + * skipping failed. + */ + private void skipBytes(final int count) throws IOException { + final long currentPosition = archive.position(); + final long newPosition = currentPosition + count; + if (newPosition > archive.size()) { + throw new EOFException(); + } + archive.position(newPosition); + } + + /** + * Checks whether the archive starts with a LFH. If it doesn't, + * it may be an empty archive. + */ + private boolean startsWithLocalFileHeader() throws IOException { + archive.position(firstLocalFileHeaderOffset); + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + return Arrays.equals(wordBuf, ZipArchiveOutputStream.LFH_SIG); + } + + /** + * Searches the archive backwards from minDistance to maxDistance + * for the given signature, positions the RandomaccessFile right + * at the signature if it has been found. + */ + private boolean tryToLocateSignature(final long minDistanceFromEnd, + final long maxDistanceFromEnd, + final byte[] sig) throws IOException { + boolean found = false; + long off = archive.size() - minDistanceFromEnd; + final long stopSearching = + Math.max(0L, archive.size() - maxDistanceFromEnd); + if (off >= 0) { + for (; off >= stopSearching; off--) { + archive.position(off); + try { + wordBbuf.rewind(); + IOUtils.readFully(archive, wordBbuf); + wordBbuf.flip(); + } catch (final EOFException ex) { // NOSONAR + break; + } + int curr = wordBbuf.get(); + if (curr == sig[POS_0]) { + curr = wordBbuf.get(); + if (curr == sig[POS_1]) { + curr = wordBbuf.get(); + if (curr == sig[POS_2]) { + curr = wordBbuf.get(); + if (curr == sig[POS_3]) { + found = true; + break; + } + } + } + } + } + } + if (found) { + archive.position(off); + } + return found; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipLong.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipLong.java new file mode 100644 index 0000000000..8628034e6d --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipLong.java @@ -0,0 +1,220 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.Serializable; + +import org.readium.r2.shared.util.archive.channel.compress.utils.ByteUtils; + +/** + * Utility class that represents a four byte integer with conversion + * rules for the little endian byte order of ZIP files. + * @Immutable + */ +public final class ZipLong implements Cloneable, Serializable { + private static final long serialVersionUID = 1L; + + /** Central File Header Signature */ + public static final ZipLong CFH_SIG = new ZipLong(0X02014B50L); + + /** Local File Header Signature */ + public static final ZipLong LFH_SIG = new ZipLong(0X04034B50L); + + /** + * Data Descriptor signature. + * + *

Actually, PKWARE uses this as marker for split/spanned + * archives and other archivers have started to use it as Data + * Descriptor signature (as well).

+ * @since 1.1 + */ + public static final ZipLong DD_SIG = new ZipLong(0X08074B50L); + + /** + * Value stored in size and similar fields if ZIP64 extensions are + * used. + * @since 1.3 + */ + static final ZipLong ZIP64_MAGIC = new ZipLong(ZipConstants.ZIP64_MAGIC); + + /** + * Marks ZIP archives that were supposed to be split or spanned + * but only needed a single segment in then end (so are actually + * neither split nor spanned). + * + *

This is the "PK00" prefix found in some archives.

+ * @since 1.5 + */ + public static final ZipLong SINGLE_SEGMENT_SPLIT_MARKER = + new ZipLong(0X30304B50L); + + /** + * Archive extra data record signature. + * @since 1.5 + */ + public static final ZipLong AED_SIG = new ZipLong(0X08064B50L); + + /** + * Get value as four bytes in big endian byte order. + * @param value the value to convert + * @return value as four bytes in big endian byte order + */ + public static byte[] getBytes(final long value) { + final byte[] result = new byte[ZipConstants.WORD]; + putLong(value, result, 0); + return result; + } + + /** + * Helper method to get the value as a Java long from a four-byte array + * @param bytes the array of bytes + * @return the corresponding Java long value + */ + public static long getValue(final byte[] bytes) { + return getValue(bytes, 0); + } + + /** + * Helper method to get the value as a Java long from four bytes starting at given array offset + * @param bytes the array of bytes + * @param offset the offset to start + * @return the corresponding Java long value + */ + public static long getValue(final byte[] bytes, final int offset) { + return ByteUtils.fromLittleEndian(bytes, offset, 4); + } + + /** + * put the value as four bytes in big endian byte order. + * @param value the Java long to convert to bytes + * @param buf the output buffer + * @param offset + * The offset within the output buffer of the first byte to be written. + * must be non-negative and no larger than {@code buf.length-4} + */ + + public static void putLong(final long value, final byte[] buf, final int offset) { + ByteUtils.toLittleEndian(buf, value, offset, 4); + } + + private final long value; + + /** + * Create instance from bytes. + * @param bytes the bytes to store as a ZipLong + */ + public ZipLong (final byte[] bytes) { + this(bytes, 0); + } + + /** + * Create instance from the four bytes starting at offset. + * @param bytes the bytes to store as a ZipLong + * @param offset the offset to start + */ + public ZipLong (final byte[] bytes, final int offset) { + value = ZipLong.getValue(bytes, offset); + } + + /** + * create instance from a java int. + * @param value the int to store as a ZipLong + * @since 1.15 + */ + public ZipLong(final int value) { + this.value = value; + } + + /** + * Create instance from a number. + * @param value the long to store as a ZipLong + */ + public ZipLong(final long value) { + this.value = value; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException cnfe) { + // impossible + throw new IllegalStateException(cnfe); //NOSONAR + } + } + + /** + * Override to make two instances with same value equal. + * @param o an object to compare + * @return true if the objects are equal + */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof ZipLong)) { + return false; + } + return value == ((ZipLong) o).getValue(); + } + + /** + * Get value as four bytes in big endian byte order. + * @return value as four bytes in big endian order + */ + public byte[] getBytes() { + return ZipLong.getBytes(value); + } + + /** + * Get value as a (signed) java int + * @return value as int + * @since 1.15 + */ + public int getIntValue() { return (int)value;} + + /** + * Get value as Java long. + * @return value as a long + */ + public long getValue() { + return value; + } + + /** + * Override to make two instances with same value equal. + * @return the value stored in the ZipLong + */ + @Override + public int hashCode() { + return (int) value; + } + + public void putLong(final byte[] buf, final int offset) { + putLong(value, buf, offset); + } + + @Override + public String toString() { + return "ZipLong value: " + value; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipMethod.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipMethod.java new file mode 100644 index 0000000000..2726e45208 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipMethod.java @@ -0,0 +1,230 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.ZipEntry; + +/** + * List of known compression methods + * + * Many of these methods are currently not supported by commons compress + * + * @since 1.5 + */ +public enum ZipMethod { + + /** + * Compression method 0 for uncompressed entries. + * + * @see ZipEntry#STORED + */ + STORED(ZipEntry.STORED), + + /** + * UnShrinking. + * dynamic Lempel-Ziv-Welch-Algorithm + * + * @see Explanation of fields: compression + * method: (2 bytes) + */ + UNSHRINKING(1), + + /** + * Reduced with compression factor 1. + * + * @see Explanation of fields: compression + * method: (2 bytes) + */ + EXPANDING_LEVEL_1(2), + + /** + * Reduced with compression factor 2. + * + * @see Explanation of fields: compression + * method: (2 bytes) + */ + EXPANDING_LEVEL_2(3), + + /** + * Reduced with compression factor 3. + * + * @see Explanation of fields: compression + * method: (2 bytes) + */ + EXPANDING_LEVEL_3(4), + + /** + * Reduced with compression factor 4. + * + * @see Explanation of fields: compression + * method: (2 bytes) + */ + EXPANDING_LEVEL_4(5), + + /** + * Imploding. + * + * @see Explanation of fields: compression + * method: (2 bytes) + */ + IMPLODING(6), + + /** + * Tokenization. + * + * @see Explanation of fields: compression + * method: (2 bytes) + */ + TOKENIZATION(7), + + /** + * Compression method 8 for compressed (deflated) entries. + * + * @see ZipEntry#DEFLATED + */ + DEFLATED(ZipEntry.DEFLATED), + + /** + * Compression Method 9 for enhanced deflate. + * + * @see https://www.winzip.com/wz54.htm + */ + ENHANCED_DEFLATED(9), + + /** + * PKWARE Data Compression Library Imploding. + * + * @see https://www.winzip.com/wz54.htm + */ + PKWARE_IMPLODING(10), + + /** + * Compression Method 12 for bzip2. + * + * @see https://www.winzip.com/wz54.htm + */ + BZIP2(12), + + /** + * Compression Method 14 for LZMA. + * + * @see https://www.7-zip.org/sdk.html + * @see https://www.winzip.com/wz54.htm + */ + LZMA(14), + + + /** + * Compression Method 95 for XZ. + * + * @see https://www.winzip.com/wz54.htm + */ + XZ(95), + + /** + * Compression Method 96 for Jpeg compression. + * + * @see https://www.winzip.com/wz54.htm + */ + JPEG(96), + + /** + * Compression Method 97 for WavPack. + * + * @see https://www.winzip.com/wz54.htm + */ + WAVPACK(97), + + /** + * Compression Method 98 for PPMd. + * + * @see https://www.winzip.com/wz54.htm + */ + PPMD(98), + + + /** + * Compression Method 99 for AES encryption. + * + * @see https://www.winzip.com/wz54.htm + */ + AES_ENCRYPTED(99), + + /** + * Unknown compression method. + */ + UNKNOWN(); + + static final int UNKNOWN_CODE = -1; + + private static final Map codeToEnum; + + static { + final Map cte = new HashMap<>(); + for (final ZipMethod method : values()) { + cte.put(method.getCode(), method); + } + codeToEnum = Collections.unmodifiableMap(cte); + } + + /** + * returns the {@link ZipMethod} for the given code or null if the + * method is not known. + * @param code the code + * @return the {@link ZipMethod} for the given code or null if the + * method is not known. + */ + public static ZipMethod getMethodByCode(final int code) { + return codeToEnum.get(code); + } + + private final int code; + + ZipMethod() { + this(UNKNOWN_CODE); + } + + /** + * private constructor for enum style class. + */ + ZipMethod(final int code) { + this.code = code; + } + + + /** + * the code of the compression method. + * + * @see ZipArchiveEntry#getMethod() + * + * @return an integer code for the method + */ + public int getCode() { + return code; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipShort.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipShort.java new file mode 100644 index 0000000000..3f50790eb1 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipShort.java @@ -0,0 +1,167 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import org.readium.r2.shared.util.archive.channel.compress.utils.ByteUtils; + +import java.io.Serializable; + +/** + * Utility class that represents a two byte integer with conversion + * rules for the little endian byte order of ZIP files. + * @Immutable + */ +public final class ZipShort implements Cloneable, Serializable { + /** + * ZipShort with a value of 0. + * @since 1.14 + */ + public static final ZipShort ZERO = new ZipShort(0); + + private static final long serialVersionUID = 1L; + + /** + * Get value as two bytes in big endian byte order. + * @param value the Java int to convert to bytes + * @return the converted int as a byte array in big endian byte order + */ + public static byte[] getBytes(final int value) { + final byte[] result = new byte[2]; + putShort(value, result, 0); + return result; + } + + /** + * Helper method to get the value as a java int from a two-byte array + * @param bytes the array of bytes + * @return the corresponding java int value + */ + public static int getValue(final byte[] bytes) { + return getValue(bytes, 0); + } + + /** + * Helper method to get the value as a java int from two bytes starting at given array offset + * @param bytes the array of bytes + * @param offset the offset to start + * @return the corresponding java int value + */ + public static int getValue(final byte[] bytes, final int offset) { + return (int) ByteUtils.fromLittleEndian(bytes, offset, 2); + } + + /** + * put the value as two bytes in big endian byte order. + * @param value the Java int to convert to bytes + * @param buf the output buffer + * @param offset + * The offset within the output buffer of the first byte to be written. + * must be non-negative and no larger than {@code buf.length-2} + */ + public static void putShort(final int value, final byte[] buf, final int offset) { + ByteUtils.toLittleEndian(buf, value, offset, 2); + } + + private final int value; + + /** + * Create instance from bytes. + * @param bytes the bytes to store as a ZipShort + */ + public ZipShort (final byte[] bytes) { + this(bytes, 0); + } + + /** + * Create instance from the two bytes starting at offset. + * @param bytes the bytes to store as a ZipShort + * @param offset the offset to start + */ + public ZipShort (final byte[] bytes, final int offset) { + value = ZipShort.getValue(bytes, offset); + } + + /** + * Create instance from a number. + * @param value the int to store as a ZipShort + */ + public ZipShort (final int value) { + this.value = value; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException cnfe) { + // impossible + throw new IllegalStateException(cnfe); //NOSONAR + } + } + + /** + * Override to make two instances with same value equal. + * @param o an object to compare + * @return true if the objects are equal + */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof ZipShort)) { + return false; + } + return value == ((ZipShort) o).getValue(); + } + + /** + * Get value as two bytes in big endian byte order. + * @return the value as a a two byte array in big endian byte order + */ + public byte[] getBytes() { + final byte[] result = new byte[2]; + ByteUtils.toLittleEndian(result, value, 0, 2); + return result; + } + + /** + * Get value as Java int. + * @return value as a Java int + */ + public int getValue() { + return value; + } + + /** + * Override to make two instances with same value equal. + * @return the value stored in the ZipShort + */ + @Override + public int hashCode() { + return value; + } + + @Override + public String toString() { + return "ZipShort value: " + value; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitOutputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitOutputStream.java new file mode 100644 index 0000000000..e6c05d89e0 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitOutputStream.java @@ -0,0 +1,252 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import org.readium.r2.shared.util.archive.channel.compress.utils.FileNameUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Used internally by {@link ZipArchiveOutputStream} when creating a split archive. + * + * @since 1.20 + */ +class ZipSplitOutputStream extends OutputStream { + private OutputStream outputStream; + private File zipFile; + private final long splitSize; + private int currentSplitSegmentIndex = 0; + private long currentSplitSegmentBytesWritten = 0; + private boolean finished = false; + private final byte[] singleByte = new byte[1]; + + /** + * 8.5.1 Capacities for split archives are as follows: + *

+ * Maximum number of segments = 4,294,967,295 - 1 + * Maximum .ZIP segment size = 4,294,967,295 bytes (refer to section 8.5.6) + * Minimum segment size = 64K + * Maximum PKSFX segment size = 2,147,483,647 bytes + */ + private final static long ZIP_SEGMENT_MIN_SIZE = 64 * 1024L; + private final static long ZIP_SEGMENT_MAX_SIZE = 4294967295L; + + /** + * Create a split zip. If the zip file is smaller than the split size, + * then there will only be one split zip, and its suffix is .zip, + * otherwise the split segments should be like .z01, .z02, ... .z(N-1), .zip + * + * @param zipFile the zip file to write to + * @param splitSize the split size + */ + public ZipSplitOutputStream(final File zipFile, final long splitSize) throws IllegalArgumentException, IOException { + if (splitSize < ZIP_SEGMENT_MIN_SIZE || splitSize > ZIP_SEGMENT_MAX_SIZE) { + throw new IllegalArgumentException("zip split segment size should between 64K and 4,294,967,295"); + } + + this.zipFile = zipFile; + this.splitSize = splitSize; + + this.outputStream = new FileOutputStream(zipFile); + // write the zip split signature 0x08074B50 to the zip file + writeZipSplitSignature(); + } + + /** + * Some data can not be written to different split segments, for example: + *

+ * 4.4.1.5 The end of central directory record and the Zip64 end + * of central directory locator record MUST reside on the same + * disk when splitting or spanning an archive. + * + * @param unsplittableContentSize + * @throws IllegalArgumentException + * @throws IOException + */ + public void prepareToWriteUnsplittableContent(final long unsplittableContentSize) throws IllegalArgumentException, IOException { + if (unsplittableContentSize > this.splitSize) { + throw new IllegalArgumentException("The unsplittable content size is bigger than the split segment size"); + } + + final long bytesRemainingInThisSegment = this.splitSize - this.currentSplitSegmentBytesWritten; + if (bytesRemainingInThisSegment < unsplittableContentSize) { + openNewSplitSegment(); + } + } + + @Override + public void write(final int i) throws IOException { + singleByte[0] = (byte)(i & 0xff); + write(singleByte); + } + + @Override + public void write(final byte[] b) throws IOException { + write(b, 0, b.length); + } + + /** + * Write the data to zip split segments, if the remaining space of current split segment + * is not enough, then a new split segment should be created + * + * @param b data to write + * @param off offset of the start of data in param b + * @param len the length of data to write + * @throws IOException + */ + @Override + public void write(final byte[] b, final int off, final int len) throws IOException { + if (len <= 0) { + return; + } + + if (currentSplitSegmentBytesWritten >= splitSize) { + openNewSplitSegment(); + write(b, off, len); + } else if (currentSplitSegmentBytesWritten + len > splitSize) { + final int bytesToWriteForThisSegment = (int) splitSize - (int) currentSplitSegmentBytesWritten; + write(b, off, bytesToWriteForThisSegment); + openNewSplitSegment(); + write(b, off + bytesToWriteForThisSegment, len - bytesToWriteForThisSegment); + } else { + outputStream.write(b, off, len); + currentSplitSegmentBytesWritten += len; + } + } + + @Override + public void close() throws IOException { + if (!finished) { + finish(); + } + } + + /** + * The last zip split segment's suffix should be .zip + * + * @throws IOException + */ + private void finish() throws IOException { + if (finished) { + throw new IOException("This archive has already been finished"); + } + + final String zipFileBaseName = FileNameUtils.getBaseName(zipFile.getName()); + final File lastZipSplitSegmentFile = new File(zipFile.getParentFile(), zipFileBaseName + ".zip"); + outputStream.close(); + if (!zipFile.renameTo(lastZipSplitSegmentFile)) { + throw new IOException("Failed to rename " + zipFile + " to " + lastZipSplitSegmentFile); + } + finished = true; + } + + /** + * Create a new zip split segment and prepare to write to the new segment + * + * @return + * @throws IOException + */ + private OutputStream openNewSplitSegment() throws IOException { + File newFile; + if (currentSplitSegmentIndex == 0) { + outputStream.close(); + newFile = createNewSplitSegmentFile(1); + if (!zipFile.renameTo(newFile)) { + throw new IOException("Failed to rename " + zipFile + " to " + newFile); + } + } + + newFile = createNewSplitSegmentFile(null); + + outputStream.close(); + outputStream = new FileOutputStream(newFile); + currentSplitSegmentBytesWritten = 0; + zipFile = newFile; + currentSplitSegmentIndex++; + + return outputStream; + } + + /** + * Write the zip split signature (0x08074B50) to the head of the first zip split segment + * + * @throws IOException + */ + private void writeZipSplitSignature() throws IOException { + outputStream.write(ZipArchiveOutputStream.DD_SIG); + currentSplitSegmentBytesWritten += ZipArchiveOutputStream.DD_SIG.length; + } + + /** + * Create the new zip split segment, the last zip segment should be .zip, and the zip split segments' suffix should be + * like .z01, .z02, .z03, ... .z99, .z100, ..., .z(N-1), .zip + *

+ * 8.3.3 Split ZIP files are typically written to the same location + * and are subject to name collisions if the spanned name + * format is used since each segment will reside on the same + * drive. To avoid name collisions, split archives are named + * as follows. + *

+ * Segment 1 = filename.z01 + * Segment n-1 = filename.z(n-1) + * Segment n = filename.zip + *

+ * NOTE: + * The zip split segment begin from 1,2,3,... , and we're creating a new segment, + * so the new segment suffix should be (currentSplitSegmentIndex + 2) + * + * @param zipSplitSegmentSuffixIndex + * @return + * @throws IOException + */ + private File createNewSplitSegmentFile(final Integer zipSplitSegmentSuffixIndex) throws IOException { + final int newZipSplitSegmentSuffixIndex = zipSplitSegmentSuffixIndex == null ? (currentSplitSegmentIndex + 2) : zipSplitSegmentSuffixIndex; + final String baseName = FileNameUtils.getBaseName(zipFile.getName()); + String extension = ".z"; + if (newZipSplitSegmentSuffixIndex <= 9) { + extension += "0" + newZipSplitSegmentSuffixIndex; + } else { + extension += newZipSplitSegmentSuffixIndex; + } + + final File newFile = new File(zipFile.getParent(), baseName + extension); + + if (newFile.exists()) { + throw new IOException("split zip segment " + baseName + extension + " already exists"); + } + return newFile; + } + + public int getCurrentSplitSegmentIndex() { + return currentSplitSegmentIndex; + } + + public long getCurrentSplitSegmentBytesWritten() { + return currentSplitSegmentBytesWritten; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitReadOnlySeekableByteChannel.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitReadOnlySeekableByteChannel.java new file mode 100644 index 0000000000..6cabfe77c3 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipSplitReadOnlySeekableByteChannel.java @@ -0,0 +1,149 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel; +import org.readium.r2.shared.util.archive.channel.compress.utils.MultiReadOnlySeekableByteChannel; + +/** + * {@link MultiReadOnlySeekableByteChannel} that knows what a split ZIP archive should look like. + * + *

If you want to read a split archive using {@link ZipFile} then create an instance of this class from the parts of + * the archive.

+ * + * @since 1.20 + */ +public class ZipSplitReadOnlySeekableByteChannel extends MultiReadOnlySeekableByteChannel { + + private static final Path[] EMPTY_PATH_ARRAY = {}; + private static final int ZIP_SPLIT_SIGNATURE_LENGTH = 4; + + /** + * Concatenates the given channels. + * + * @param channels the channels to concatenate, note that the LAST CHANNEL of channels should be the LAST SEGMENT(.zip) + * and theses channels should be added in correct order (e.g. .z01, .z02... .z99, .zip) + * @return SeekableByteChannel that concatenates all provided channels + * @throws NullPointerException if channels is null + * @throws IOException if reading channels fails + */ + public static SeekableByteChannel forOrderedSeekableByteChannels(final SeekableByteChannel... channels) throws IOException { + if (Objects.requireNonNull(channels, "channels must not be null").length == 1) { + return channels[0]; + } + return new ZipSplitReadOnlySeekableByteChannel(Arrays.asList(channels)); + } + + /** + * Concatenates the given channels. + * + * @param lastSegmentChannel channel of the last segment of split zip segments, its extension should be .zip + * @param channels the channels to concatenate except for the last segment, + * note theses channels should be added in correct order (e.g. .z01, .z02... .z99) + * @return SeekableByteChannel that concatenates all provided channels + * @throws NullPointerException if lastSegmentChannel or channels is null + * @throws IOException if the first channel doesn't seem to hold + * the beginning of a split archive + */ + public static SeekableByteChannel forOrderedSeekableByteChannels(final SeekableByteChannel lastSegmentChannel, + final Iterable channels) throws IOException { + Objects.requireNonNull(channels, "channels"); + Objects.requireNonNull(lastSegmentChannel, "lastSegmentChannel"); + + final List channelsList = new ArrayList<>(); + for (SeekableByteChannel channel: channels) { + channelsList.add(channel); + } + channelsList.add(lastSegmentChannel); + + return forOrderedSeekableByteChannels(channelsList.toArray(new SeekableByteChannel[0])); + } + + private final ByteBuffer zipSplitSignatureByteBuffer = + ByteBuffer.allocate(ZIP_SPLIT_SIGNATURE_LENGTH); + + /** + * Concatenates the given channels. + * + *

The channels should be add in ascending order, e.g. z01, + * z02, ... z99, zip please note that the .zip file is the last + * segment and should be added as the last one in the channels

+ * + * @param channels the channels to concatenate + * @throws NullPointerException if channels is null + * @throws IOException if the first channel doesn't seem to hold + * the beginning of a split archive + */ + public ZipSplitReadOnlySeekableByteChannel(final List channels) + throws IOException { + super(channels); + + // the first split zip segment should begin with zip split signature + assertSplitSignature(channels); + } + + /** + * Based on the zip specification: + * + *

+ * 8.5.3 Spanned/Split archives created using PKZIP for Windows + * (V2.50 or greater), PKZIP Command Line (V2.50 or greater), + * or PKZIP Explorer will include a special spanning + * signature as the first 4 bytes of the first segment of + * the archive. This signature (0x08074b50) will be + * followed immediately by the local header signature for + * the first file in the archive. + * + *

+ * the first 4 bytes of the first zip split segment should be the zip split signature(0x08074B50) + * + * @param channels channels to be validated + * @throws IOException + */ + private void assertSplitSignature(final List channels) + throws IOException { + final SeekableByteChannel channel = channels.get(0); + // the zip split file signature is at the beginning of the first split segment + channel.position(0L); + + zipSplitSignatureByteBuffer.rewind(); + channel.read(zipSplitSignatureByteBuffer); + final ZipLong signature = new ZipLong(zipSplitSignatureByteBuffer.array()); + if (!signature.equals(ZipLong.DD_SIG)) { + channel.position(0L); + throw new IOException("The first zip split segment does not begin with split zip file signature"); + } + + channel.position(0L); + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipUtil.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipUtil.java new file mode 100644 index 0000000000..5c1f749cf3 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/archivers/zip/ZipUtil.java @@ -0,0 +1,366 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.archivers.zip; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.zip.CRC32; +import java.util.zip.ZipEntry; + +/** + * Utility class for handling DOS and Java time conversions. + * @Immutable + */ +public abstract class ZipUtil { + /** + * Smallest date/time ZIP can handle. + */ + private static final byte[] DOS_TIME_MIN = ZipLong.getBytes(0x00002100L); + + /** + * Assumes a negative integer really is a positive integer that + * has wrapped around and re-creates the original value. + * + * @param i the value to treat as unsigned int. + * @return the unsigned int as a long. + */ + public static long adjustToLong(final int i) { + if (i < 0) { + return 2 * ((long) Integer.MAX_VALUE) + 2 + i; + } + return i; + } + + /** + * Converts a BigInteger into a long, and blows up + * (NumberFormatException) if the BigInteger is too big. + * + * @param big BigInteger to convert. + * @return long representation of the BigInteger. + */ + static long bigToLong(final BigInteger big) { + if (big.bitLength() <= 63) { // bitLength() doesn't count the sign bit. + return big.longValue(); + } + throw new NumberFormatException("The BigInteger cannot fit inside a 64 bit java long: [" + big + "]"); + } + + /** + * Whether this library is able to read or write the given entry. + */ + static boolean canHandleEntryData(final ZipArchiveEntry entry) { + return supportsEncryptionOf(entry) && supportsMethodOf(entry); + } + + /** + * Checks whether the entry requires features not (yet) supported + * by the library and throws an exception if it does. + */ + static void checkRequestedFeatures(final ZipArchiveEntry ze) + throws UnsupportedZipFeatureException { + if (!supportsEncryptionOf(ze)) { + throw + new UnsupportedZipFeatureException(UnsupportedZipFeatureException + .Feature.ENCRYPTION, ze); + } + if (!supportsMethodOf(ze)) { + final ZipMethod m = ZipMethod.getMethodByCode(ze.getMethod()); + if (m == null) { + throw + new UnsupportedZipFeatureException(UnsupportedZipFeatureException + .Feature.METHOD, ze); + } + throw new UnsupportedZipFeatureException(m, ze); + } + } + + + /** + * Create a copy of the given array - or return null if the + * argument is null. + */ + static byte[] copy(final byte[] from) { + if (from != null) { + return Arrays.copyOf(from, from.length); + } + return null; + } + + static void copy(final byte[] from, final byte[] to, final int offset) { + if (from != null) { + System.arraycopy(from, 0, to, offset, from.length); + } + } + + /** + * Converts DOS time to Java time (number of milliseconds since + * epoch). + * @param dosTime time to convert + * @return converted time + */ + public static long dosToJavaTime(final long dosTime) { + final Calendar cal = Calendar.getInstance(); + // CheckStyle:MagicNumberCheck OFF - no point + cal.set(Calendar.YEAR, (int) ((dosTime >> 25) & 0x7f) + 1980); + cal.set(Calendar.MONTH, (int) ((dosTime >> 21) & 0x0f) - 1); + cal.set(Calendar.DATE, (int) (dosTime >> 16) & 0x1f); + cal.set(Calendar.HOUR_OF_DAY, (int) (dosTime >> 11) & 0x1f); + cal.set(Calendar.MINUTE, (int) (dosTime >> 5) & 0x3f); + cal.set(Calendar.SECOND, (int) (dosTime << 1) & 0x3e); + cal.set(Calendar.MILLISECOND, 0); + // CheckStyle:MagicNumberCheck ON + return cal.getTime().getTime(); + } + + /** + * Convert a DOS date/time field to a Date object. + * + * @param zipDosTime contains the stored DOS time. + * @return a Date instance corresponding to the given time. + */ + public static Date fromDosTime(final ZipLong zipDosTime) { + final long dosTime = zipDosTime.getValue(); + return new Date(dosToJavaTime(dosTime)); + } + + /** + * If the stored CRC matches the one of the given name, return the + * Unicode name of the given field. + * + *

If the field is null or the CRCs don't match, return null + * instead.

+ */ + private static + String getUnicodeStringIfOriginalMatches(final AbstractUnicodeExtraField f, + final byte[] orig) { + if (f != null) { + final CRC32 crc32 = new CRC32(); + crc32.update(orig); + final long origCRC32 = crc32.getValue(); + + if (origCRC32 == f.getNameCRC32()) { + try { + return ZipEncodingHelper + .UTF8_ZIP_ENCODING.decode(f.getUnicodeName()); + } catch (final IOException ex) { + // UTF-8 unsupported? should be impossible the + // Unicode*ExtraField must contain some bad bytes + } + } + } + // TODO log this anywhere? + return null; + } + + /** + *

+ * Converts a long into a BigInteger. Negative numbers between -1 and + * -2^31 are treated as unsigned 32 bit (e.g., positive) integers. + * Negative numbers below -2^31 cause an IllegalArgumentException + * to be thrown. + *

+ * + * @param l long to convert to BigInteger. + * @return BigInteger representation of the provided long. + */ + static BigInteger longToBig(long l) { + if (l < Integer.MIN_VALUE) { + throw new IllegalArgumentException("Negative longs < -2^31 not permitted: [" + l + "]"); + } + if (l < 0 && l >= Integer.MIN_VALUE) { + // If someone passes in a -2, they probably mean 4294967294 + // (For example, Unix UID/GID's are 32 bit unsigned.) + l = ZipUtil.adjustToLong((int) l); + } + return BigInteger.valueOf(l); + } + + /** + * Reverses a byte[] array. Reverses in-place (thus provided array is + * mutated), but also returns same for convenience. + * + * @param array to reverse (mutated in-place, but also returned for + * convenience). + * + * @return the reversed array (mutated in-place, but also returned for + * convenience). + * @since 1.5 + */ + public static byte[] reverse(final byte[] array) { + final int z = array.length - 1; // position of last element + for (int i = 0; i < array.length / 2; i++) { + final byte x = array[i]; + array[i] = array[z - i]; + array[z - i] = x; + } + return array; + } + + /** + * If the entry has Unicode*ExtraFields and the CRCs of the + * names/comments match those of the extra fields, transfer the + * known Unicode values from the extra field. + */ + static void setNameAndCommentFromExtraFields(final ZipArchiveEntry ze, + final byte[] originalNameBytes, + final byte[] commentBytes) { + final ZipExtraField nameCandidate = ze.getExtraField(UnicodePathExtraField.UPATH_ID); + final UnicodePathExtraField name = nameCandidate instanceof UnicodePathExtraField + ? (UnicodePathExtraField) nameCandidate : null; + final String newName = getUnicodeStringIfOriginalMatches(name, + originalNameBytes); + if (newName != null) { + ze.setName(newName); + ze.setNameSource(ZipArchiveEntry.NameSource.UNICODE_EXTRA_FIELD); + } + + if (commentBytes != null && commentBytes.length > 0) { + final ZipExtraField cmtCandidate = ze.getExtraField(UnicodeCommentExtraField.UCOM_ID); + final UnicodeCommentExtraField cmt = cmtCandidate instanceof UnicodeCommentExtraField + ? (UnicodeCommentExtraField) cmtCandidate : null; + final String newComment = + getUnicodeStringIfOriginalMatches(cmt, commentBytes); + if (newComment != null) { + ze.setComment(newComment); + ze.setCommentSource(ZipArchiveEntry.CommentSource.UNICODE_EXTRA_FIELD); + } + } + } + + /** + * Converts a signed byte into an unsigned integer representation + * (e.g., -1 becomes 255). + * + * @param b byte to convert to int + * @return int representation of the provided byte + * @since 1.5 + */ + public static int signedByteToUnsignedInt(final byte b) { + if (b >= 0) { + return b; + } + return 256 + b; + } + + /** + * Whether this library supports the encryption used by the given + * entry. + * + * @return true if the entry isn't encrypted at all + */ + private static boolean supportsEncryptionOf(final ZipArchiveEntry entry) { + return !entry.getGeneralPurposeBit().usesEncryption(); + } + + /** + * Whether this library supports the compression method used by + * the given entry. + * + * @return true if the compression method is supported + */ + private static boolean supportsMethodOf(final ZipArchiveEntry entry) { + return entry.getMethod() == ZipEntry.STORED + || entry.getMethod() == ZipMethod.UNSHRINKING.getCode() + || entry.getMethod() == ZipMethod.IMPLODING.getCode() + || entry.getMethod() == ZipEntry.DEFLATED + || entry.getMethod() == ZipMethod.ENHANCED_DEFLATED.getCode() + || entry.getMethod() == ZipMethod.BZIP2.getCode(); + } + + static void toDosTime(final Calendar c, final long t, final byte[] buf, final int offset) { + c.setTimeInMillis(t); + + final int year = c.get(Calendar.YEAR); + if (year < 1980) { + copy(DOS_TIME_MIN, buf, offset); // stop callers from changing the array + return; + } + final int month = c.get(Calendar.MONTH) + 1; + final long value = ((year - 1980) << 25) + | (month << 21) + | (c.get(Calendar.DAY_OF_MONTH) << 16) + | (c.get(Calendar.HOUR_OF_DAY) << 11) + | (c.get(Calendar.MINUTE) << 5) + | (c.get(Calendar.SECOND) >> 1); + ZipLong.putLong(value, buf, offset); + } + + + /** + * Convert a Date object to a DOS date/time field. + * @param time the {@code Date} to convert + * @return the date as a {@code ZipLong} + */ + public static ZipLong toDosTime(final Date time) { + return new ZipLong(toDosTime(time.getTime())); + } + + /** + * Convert a Date object to a DOS date/time field. + * + *

Stolen from InfoZip's {@code fileio.c}

+ * @param t number of milliseconds since the epoch + * @return the date as a byte array + */ + public static byte[] toDosTime(final long t) { + final byte[] result = new byte[4]; + toDosTime(t, result, 0); + return result; + } + + /** + * Convert a Date object to a DOS date/time field. + * + *

Stolen from InfoZip's {@code fileio.c}

+ * @param t number of milliseconds since the epoch + * @param buf the output buffer + * @param offset + * The offset within the output buffer of the first byte to be written. + * must be non-negative and no larger than {@code buf.length-4} + */ + public static void toDosTime(final long t, final byte[] buf, final int offset) { + toDosTime(Calendar.getInstance(), t, buf, offset); + } + + /** + * Converts an unsigned integer to a signed byte (e.g., 255 becomes -1). + * + * @param i integer to convert to byte + * @return byte representation of the provided int + * @throws IllegalArgumentException if the provided integer is not inside the range [0,255]. + * @since 1.5 + */ + public static byte unsignedIntToSignedByte(final int i) { + if (i > 255 || i < 0) { + throw new IllegalArgumentException("Can only convert non-negative integers between [0,255] to byte: [" + i + "]"); + } + if (i < 128) { + return (byte) i; + } + return (byte) (i - 256); + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/InputStreamSupplier.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/InputStreamSupplier.java new file mode 100644 index 0000000000..a9b437670e --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/InputStreamSupplier.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.readium.r2.shared.util.archive.channel.compress.parallel; + +import java.io.InputStream; + +/** + * Supplies input streams. + * + * Implementations are required to support thread-handover. While an instance will + * not be accessed concurrently by multiple threads, it will be called by + * a different thread than it was created on. + * + * @since 1.10 + */ +public interface InputStreamSupplier { + + /** + * Supply an input stream for a resource. + * @return the input stream. Should never null, but may be an empty stream. + */ + InputStream get(); +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStore.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStore.java new file mode 100644 index 0000000000..6a8df42335 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStore.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.parallel; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; + +/** + *

Store intermediate payload in a scatter-gather scenario. + * Multiple threads write their payload to a backing store, which can + * subsequently be reversed to an {@link InputStream} to be used as input in the + * gather phase.

+ * + *

It is the responsibility of the allocator of an instance of this class + * to close this. Closing it should clear off any allocated structures + * and preferably delete files.

+ * + * @since 1.10 + */ +public interface ScatterGatherBackingStore extends Closeable { + + /** + * An input stream that contains the scattered payload + * + * @return An InputStream, should be closed by the caller of this method. + * @throws IOException when something fails + */ + InputStream getInputStream() throws IOException; + + /** + * Writes a piece of payload. + * + * @param data the data to write + * @param offset offset inside data to start writing from + * @param length the amount of data to write + * @throws IOException when something fails + */ + void writeOut(byte[] data, int offset, int length) throws IOException; + + /** + * Closes this backing store for further writing. + * @throws IOException when something fails + */ + void closeForWriting() throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStoreSupplier.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStoreSupplier.java new file mode 100644 index 0000000000..395bf2974c --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/parallel/ScatterGatherBackingStoreSupplier.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.parallel; + +import java.io.IOException; + +/** + * Supplies {@link ScatterGatherBackingStore} instances. + * + * @since 1.10 + */ +public interface ScatterGatherBackingStoreSupplier { + /** + * Create a ScatterGatherBackingStore. + * + * @return a ScatterGatherBackingStore, not null + * @throws IOException when something fails + */ + ScatterGatherBackingStore get() throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedArchiveInputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedArchiveInputStream.java new file mode 100644 index 0000000000..4677fd4d56 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedArchiveInputStream.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +/** + * NIO backed bounded input stream for reading a predefined amount of data from. + * @ThreadSafe this base class is thread safe but implementations must not be. + * @since 1.21 + */ +public abstract class BoundedArchiveInputStream extends InputStream { + + private final long end; + private ByteBuffer singleByteBuffer; + private long loc; + + /** + * Create a new bounded input stream. + * + * @param start position in the stream from where the reading of this bounded stream starts. + * @param remaining amount of bytes which are allowed to read from the bounded stream. + */ + public BoundedArchiveInputStream(final long start, final long remaining) { + this.end = start + remaining; + if (this.end < start) { + // check for potential vulnerability due to overflow + throw new IllegalArgumentException("Invalid length of stream at offset=" + start + ", length=" + remaining); + } + loc = start; + } + + @Override + public synchronized int read() throws IOException { + if (loc >= end) { + return -1; + } + if (singleByteBuffer == null) { + singleByteBuffer = ByteBuffer.allocate(1); + } else { + singleByteBuffer.rewind(); + } + final int read = read(loc, singleByteBuffer); + if (read < 1) { + return -1; + } + loc++; + return singleByteBuffer.get() & 0xff; + } + + @Override + public synchronized int read(final byte[] b, final int off, final int len) throws IOException { + if (loc >= end) { + return -1; + } + final long maxLen = Math.min(len, end - loc); + if (maxLen <= 0) { + return 0; + } + if (off < 0 || off > b.length || maxLen > b.length - off) { + throw new IndexOutOfBoundsException("offset or len are out of bounds"); + } + + final ByteBuffer buf = ByteBuffer.wrap(b, off, (int) maxLen); + final int ret = read(loc, buf); + if (ret > 0) { + loc += ret; + } + return ret; + } + + /** + * Read content of the stream into a {@link ByteBuffer}. + * @param pos position to start the read. + * @param buf buffer to add the read content. + * @return number of read bytes. + * @throws IOException if I/O fails. + */ + protected abstract int read(long pos, ByteBuffer buf) throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedInputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedInputStream.java new file mode 100644 index 0000000000..11fd2ec6f0 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedInputStream.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A stream that limits reading from a wrapped stream to a given number of bytes. + * @NotThreadSafe + * @since 1.6 + */ +public class BoundedInputStream extends InputStream { + private final InputStream in; + private long bytesRemaining; + + /** + * Creates the stream that will at most read the given amount of + * bytes from the given stream. + * @param in the stream to read from + * @param size the maximum amount of bytes to read + */ + public BoundedInputStream(final InputStream in, final long size) { + this.in = in; + bytesRemaining = size; + } + + @Override + public void close() { + // there isn't anything to close in this stream and the nested + // stream is controlled externally + } + + /** + * @return bytes remaining to read + * @since 1.21 + */ + public long getBytesRemaining() { + return bytesRemaining; + } + + @Override + public int read() throws IOException { + if (bytesRemaining > 0) { + --bytesRemaining; + return in.read(); + } + return -1; + } + + @Override + public int read(final byte[] b, final int off, final int len) throws IOException { + if (len == 0) { + return 0; + } + if (bytesRemaining == 0) { + return -1; + } + int bytesToRead = len; + if (bytesToRead > bytesRemaining) { + bytesToRead = (int) bytesRemaining; + } + final int bytesRead = in.read(b, off, bytesToRead); + if (bytesRead >= 0) { + bytesRemaining -= bytesRead; + } + return bytesRead; + } + + /** + * @since 1.20 + */ + @Override + public long skip(final long n) throws IOException { + final long bytesToSkip = Math.min(bytesRemaining, n); + final long bytesSkipped = in.skip(bytesToSkip); + bytesRemaining -= bytesSkipped; + + return bytesSkipped; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedSeekableByteChannelInputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedSeekableByteChannelInputStream.java new file mode 100644 index 0000000000..f25e923d4d --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/BoundedSeekableByteChannelInputStream.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel; + +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * InputStream that delegates requests to the underlying SeekableByteChannel, making sure that only bytes from a certain + * range can be read. + * @ThreadSafe + * @since 1.21 + */ +public class BoundedSeekableByteChannelInputStream extends BoundedArchiveInputStream { + + private final SeekableByteChannel channel; + + /** + * Create a bounded stream on the underlying {@link SeekableByteChannel} + * + * @param start Position in the stream from where the reading of this bounded stream starts + * @param remaining Amount of bytes which are allowed to read from the bounded stream + * @param channel Channel which the reads will be delegated to + */ + public BoundedSeekableByteChannelInputStream(final long start, final long remaining, + final SeekableByteChannel channel) { + super(start, remaining); + this.channel = channel; + } + + @Override + protected int read(final long pos, final ByteBuffer buf) throws IOException { + int read; + synchronized (channel) { + channel.position(pos); + read = channel.read(buf); + } + buf.flip(); + return read; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/ByteUtils.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/ByteUtils.java new file mode 100644 index 0000000000..7eb01be2d3 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/ByteUtils.java @@ -0,0 +1,269 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Utility methods for reading and writing bytes. + * @since 1.14 + */ +public final class ByteUtils { + + /** + * Used to consume bytes. + * @since 1.14 + */ + public interface ByteConsumer { + /** + * The contract is similar to {@link OutputStream#write(int)}, + * consume the lower eight bytes of the int as a byte. + * @param b the byte to consume + * @throws IOException if consuming fails + */ + void accept(int b) throws IOException; + } + + /** + * Used to supply bytes. + * @since 1.14 + */ + public interface ByteSupplier { + /** + * The contract is similar to {@link InputStream#read()}, return + * the byte as an unsigned int, -1 if there are no more bytes. + * @return the supplied byte or -1 if there are no more bytes + * @throws IOException if supplying fails + */ + int getAsByte() throws IOException; + } + + /** + * {@link ByteSupplier} based on {@link InputStream}. + * @since 1.14 + */ + public static class InputStreamByteSupplier implements ByteSupplier { + private final InputStream is; + public InputStreamByteSupplier(final InputStream is) { + this.is = is; + } + @Override + public int getAsByte() throws IOException { + return is.read(); + } + } + + /** + * {@link ByteConsumer} based on {@link OutputStream}. + * @since 1.14 + */ + public static class OutputStreamByteConsumer implements ByteConsumer { + private final OutputStream os; + public OutputStreamByteConsumer(final OutputStream os) { + this.os = os; + } + @Override + public void accept(final int b) throws IOException { + os.write(b); + } + } + + /** + * Empty array. + * + * @since 1.21 + */ + public static final byte[] EMPTY_BYTE_ARRAY = {}; + + private static void checkReadLength(final int length) { + if (length > 8) { + throw new IllegalArgumentException("Can't read more than eight bytes into a long value"); + } + } + + /** + * Reads the given byte array as a little endian long. + * @param bytes the byte array to convert + * @return the number read + */ + public static long fromLittleEndian(final byte[] bytes) { + return fromLittleEndian(bytes, 0, bytes.length); + } + + /** + * Reads the given byte array as a little endian long. + * @param bytes the byte array to convert + * @param off the offset into the array that starts the value + * @param length the number of bytes representing the value + * @return the number read + * @throws IllegalArgumentException if len is bigger than eight + */ + public static long fromLittleEndian(final byte[] bytes, final int off, final int length) { + checkReadLength(length); + long l = 0; + for (int i = 0; i < length; i++) { + l |= (bytes[off + i] & 0xffL) << (8 * i); + } + return l; + } + + /** + * Reads the given number of bytes from the given supplier as a little endian long. + * + *

Typically used by our InputStreams that need to count the + * bytes read as well.

+ * + * @param supplier the supplier for bytes + * @param length the number of bytes representing the value + * @return the number read + * @throws IllegalArgumentException if len is bigger than eight + * @throws IOException if the supplier fails or doesn't supply the + * given number of bytes anymore + */ + public static long fromLittleEndian(final ByteSupplier supplier, final int length) throws IOException { + checkReadLength(length); + long l = 0; + for (int i = 0; i < length; i++) { + final long b = supplier.getAsByte(); + if (b == -1) { + throw new IOException("Premature end of data"); + } + l |= (b << (i * 8)); + } + return l; + } + + /** + * Reads the given number of bytes from the given input as little endian long. + * @param in the input to read from + * @param length the number of bytes representing the value + * @return the number read + * @throws IllegalArgumentException if len is bigger than eight + * @throws IOException if reading fails or the stream doesn't + * contain the given number of bytes anymore + */ + public static long fromLittleEndian(final DataInput in, final int length) throws IOException { + // somewhat duplicates the ByteSupplier version in order to save the creation of a wrapper object + checkReadLength(length); + long l = 0; + for (int i = 0; i < length; i++) { + final long b = in.readUnsignedByte(); + l |= (b << (i * 8)); + } + return l; + } + + /** + * Reads the given number of bytes from the given stream as a little endian long. + * @param in the stream to read from + * @param length the number of bytes representing the value + * @return the number read + * @throws IllegalArgumentException if len is bigger than eight + * @throws IOException if reading fails or the stream doesn't + * contain the given number of bytes anymore + */ + public static long fromLittleEndian(final InputStream in, final int length) throws IOException { + // somewhat duplicates the ByteSupplier version in order to save the creation of a wrapper object + checkReadLength(length); + long l = 0; + for (int i = 0; i < length; i++) { + final long b = in.read(); + if (b == -1) { + throw new IOException("Premature end of data"); + } + l |= (b << (i * 8)); + } + return l; + } + + /** + * Inserts the given value into the array as a little endian + * sequence of the given length starting at the given offset. + * @param b the array to write into + * @param value the value to insert + * @param off the offset into the array that receives the first byte + * @param length the number of bytes to use to represent the value + */ + public static void toLittleEndian(final byte[] b, final long value, final int off, final int length) { + long num = value; + for (int i = 0; i < length; i++) { + b[off + i] = (byte) (num & 0xff); + num >>= 8; + } + } + + /** + * Provides the given value to the given consumer as a little endian + * sequence of the given length. + * @param consumer the consumer to provide the bytes to + * @param value the value to provide + * @param length the number of bytes to use to represent the value + * @throws IOException if writing fails + */ + public static void toLittleEndian(final ByteConsumer consumer, final long value, final int length) + throws IOException { + long num = value; + for (int i = 0; i < length; i++) { + consumer.accept((int) (num & 0xff)); + num >>= 8; + } + } + + /** + * Writes the given value to the given stream as a little endian + * array of the given length. + * @param out the output to write to + * @param value the value to write + * @param length the number of bytes to use to represent the value + * @throws IOException if writing fails + */ + public static void toLittleEndian(final DataOutput out, final long value, final int length) + throws IOException { + // somewhat duplicates the ByteConsumer version in order to save the creation of a wrapper object + long num = value; + for (int i = 0; i < length; i++) { + out.write((int) (num & 0xff)); + num >>= 8; + } + } + + /** + * Writes the given value to the given stream as a little endian + * array of the given length. + * @param out the stream to write to + * @param value the value to write + * @param length the number of bytes to use to represent the value + * @throws IOException if writing fails + */ + public static void toLittleEndian(final OutputStream out, final long value, final int length) + throws IOException { + // somewhat duplicates the ByteConsumer version in order to save the creation of a wrapper object + long num = value; + for (int i = 0; i < length; i++) { + out.write((int) (num & 0xff)); + num >>= 8; + } + } + + private ByteUtils() { /* no instances */ } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/CountingInputStream.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/CountingInputStream.java new file mode 100644 index 0000000000..2a5164cb80 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/CountingInputStream.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Input stream that tracks the number of bytes read. + * @since 1.3 + * @NotThreadSafe + */ +public class CountingInputStream extends FilterInputStream { + private long bytesRead; + + public CountingInputStream(final InputStream in) { + super(in); + } + + /** + * Increments the counter of already read bytes. + * Doesn't increment if the EOF has been hit (read == -1) + * + * @param read the number of bytes read + */ + protected final void count(final long read) { + if (read != -1) { + bytesRead += read; + } + } + + /** + * Returns the current number of bytes read from this stream. + * @return the number of read bytes + */ + public long getBytesRead() { + return bytesRead; + } + + @Override + public int read() throws IOException { + final int r = in.read(); + if (r >= 0) { + count(1); + } + return r; + } + + @Override + public int read(final byte[] b) throws IOException { + return read(b, 0, b.length); + } + + @Override + public int read(final byte[] b, final int off, final int len) throws IOException { + if (len == 0) { + return 0; + } + final int r = in.read(b, off, len); + if (r >= 0) { + count(r); + } + return r; + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/FileNameUtils.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/FileNameUtils.java new file mode 100644 index 0000000000..e27a8a57ee --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/FileNameUtils.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import java.io.File; + +/** + * Generic file name utilities. + * @since 1.20 + */ +public class FileNameUtils { + + /** + * Returns the extension (i.e. the part after the last ".") of a file. + * + *

Will return an empty string if the file name doesn't contain + * any dots. Only the last segment of a the file name is consulted + * - i.e. all leading directories of the {@code filename} + * parameter are skipped.

+ * + * @return the extension of filename + * @param filename the name of the file to obtain the extension of. + */ + public static String getExtension(final String filename) { + if (filename == null) { + return null; + } + + final String name = new File(filename).getName(); + final int extensionPosition = name.lastIndexOf('.'); + if (extensionPosition < 0) { + return ""; + } + return name.substring(extensionPosition + 1); + } + + /** + * Returns the basename (i.e. the part up to and not including the + * last ".") of the last path segment of a filename. + * + *

Will return the file name itself if it doesn't contain any + * dots. All leading directories of the {@code filename} parameter + * are skipped.

+ * + * @return the basename of filename + * @param filename the name of the file to obtain the basename of. + */ + public static String getBaseName(final String filename) { + if (filename == null) { + return null; + } + + final String name = new File(filename).getName(); + + final int extensionPosition = name.lastIndexOf('.'); + if (extensionPosition < 0) { + return name; + } + + return name.substring(0, extensionPosition); + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/IOUtils.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/IOUtils.java new file mode 100644 index 0000000000..2911408782 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/IOUtils.java @@ -0,0 +1,356 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import org.readium.r2.shared.util.archive.channel.jvm.ReadableByteChannel; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.file.LinkOption; + +/** + * Utility functions + * @Immutable (has mutable data but it is write-only) + */ +public final class IOUtils { + + private static final int COPY_BUF_SIZE = 8024; + private static final int SKIP_BUF_SIZE = 4096; + + /** + * Empty array of type {@link LinkOption}. + * + * @since 1.21 + */ + public static final LinkOption[] EMPTY_LINK_OPTIONS = {}; + + // This buffer does not need to be synchronized because it is write only; the contents are ignored + // Does not affect Immutability + private static final byte[] SKIP_BUF = new byte[SKIP_BUF_SIZE]; + + /** + * Closes the given Closeable and swallows any IOException that may occur. + * @param c Closeable to close, can be null + * @since 1.7 + */ + public static void closeQuietly(final Closeable c) { + if (c != null) { + try { + c.close(); + } catch (final IOException ignored) { // NOPMD NOSONAR + } + } + } + + /** + * Copies the content of a InputStream into an OutputStream. + * Uses a default buffer size of 8024 bytes. + * + * @param input + * the InputStream to copy + * @param output + * the target, may be null to simulate output to dev/null on Linux and NUL on Windows + * @return the number of bytes copied + * @throws IOException + * if an error occurs + */ + public static long copy(final InputStream input, final OutputStream output) throws IOException { + return copy(input, output, COPY_BUF_SIZE); + } + + /** + * Copies the content of a InputStream into an OutputStream + * + * @param input + * the InputStream to copy + * @param output + * the target, may be null to simulate output to dev/null on Linux and NUL on Windows + * @param buffersize + * the buffer size to use, must be bigger than 0 + * @return the number of bytes copied + * @throws IOException + * if an error occurs + * @throws IllegalArgumentException + * if buffersize is smaller than or equal to 0 + */ + public static long copy(final InputStream input, final OutputStream output, final int buffersize) throws IOException { + if (buffersize < 1) { + throw new IllegalArgumentException("buffersize must be bigger than 0"); + } + final byte[] buffer = new byte[buffersize]; + int n = 0; + long count=0; + while (-1 != (n = input.read(buffer))) { + if (output != null) { + output.write(buffer, 0, n); + } + count += n; + } + return count; + } + + /** + * Copies part of the content of a InputStream into an OutputStream. + * Uses a default buffer size of 8024 bytes. + * + * @param input + * the InputStream to copy + * @param output + * the target Stream + * @param len + * maximum amount of bytes to copy + * @return the number of bytes copied + * @throws IOException + * if an error occurs + * @since 1.21 + */ + public static long copyRange(final InputStream input, final long len, final OutputStream output) + throws IOException { + return copyRange(input, len, output, COPY_BUF_SIZE); + } + + /** + * Copies part of the content of a InputStream into an OutputStream + * + * @param input + * the InputStream to copy + * @param len + * maximum amount of bytes to copy + * @param output + * the target, may be null to simulate output to dev/null on Linux and NUL on Windows + * @param buffersize + * the buffer size to use, must be bigger than 0 + * @return the number of bytes copied + * @throws IOException + * if an error occurs + * @throws IllegalArgumentException + * if buffersize is smaller than or equal to 0 + * @since 1.21 + */ + public static long copyRange(final InputStream input, final long len, final OutputStream output, + final int buffersize) throws IOException { + if (buffersize < 1) { + throw new IllegalArgumentException("buffersize must be bigger than 0"); + } + final byte[] buffer = new byte[(int) Math.min(buffersize, len)]; + int n = 0; + long count = 0; + while (count < len && -1 != (n = input.read(buffer, 0, (int) Math.min(len - count, buffer.length)))) { + if (output != null) { + output.write(buffer, 0, n); + } + count += n; + } + return count; + } + + /** + * Reads as much from input as possible to fill the given array. + * + *

This method may invoke read repeatedly to fill the array and + * only read less bytes than the length of the array if the end of + * the stream has been reached.

+ * + * @param input stream to read from + * @param array buffer to fill + * @return the number of bytes actually read + * @throws IOException on error + */ + public static int readFully(final InputStream input, final byte[] array) throws IOException { + return readFully(input, array, 0, array.length); + } + + // toByteArray(InputStream) copied from: + // commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java?revision=1428941 + // January 8th, 2013 + // + // Assuming our copy() works just as well as theirs! :-) + + /** + * Reads as much from input as possible to fill the given array + * with the given amount of bytes. + * + *

This method may invoke read repeatedly to read the bytes and + * only read less bytes than the requested length if the end of + * the stream has been reached.

+ * + * @param input stream to read from + * @param array buffer to fill + * @param offset offset into the buffer to start filling at + * @param len of bytes to read + * @return the number of bytes actually read + * @throws IOException + * if an I/O error has occurred + */ + public static int readFully(final InputStream input, final byte[] array, final int offset, final int len) + throws IOException { + if (len < 0 || offset < 0 || len + offset > array.length || len + offset < 0) { + throw new IndexOutOfBoundsException(); + } + int count = 0, x = 0; + while (count != len) { + x = input.read(array, offset + count, len - count); + if (x == -1) { + break; + } + count += x; + } + return count; + } + + /** + * Reads {@code b.remaining()} bytes from the given channel + * starting at the current channel's position. + * + *

This method reads repeatedly from the channel until the + * requested number of bytes are read. This method blocks until + * the requested number of bytes are read, the end of the channel + * is detected, or an exception is thrown.

+ * + * @param channel the channel to read from + * @param byteBuffer the buffer into which the data is read. + * @throws IOException - if an I/O error occurs. + * @throws EOFException - if the channel reaches the end before reading all the bytes. + */ + public static void readFully(final ReadableByteChannel channel, final ByteBuffer byteBuffer) throws IOException { + final int expectedLength = byteBuffer.remaining(); + int read = 0; + while (read < expectedLength) { + final int readNow = channel.read(byteBuffer); + if (readNow <= 0) { + break; + } + read += readNow; + } + if (read < expectedLength) { + throw new EOFException(); + } + } + + /** + * Gets part of the contents of an {@code InputStream} as a {@code byte[]}. + * + * @param input the {@code InputStream} to read from + * @param len + * maximum amount of bytes to copy + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since 1.21 + */ + public static byte[] readRange(final InputStream input, final int len) throws IOException { + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + copyRange(input, len, output); + return output.toByteArray(); + } + + /** + * Gets part of the contents of an {@code ReadableByteChannel} as a {@code byte[]}. + * + * @param input the {@code ReadableByteChannel} to read from + * @param len + * maximum amount of bytes to copy + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since 1.21 + */ + public static byte[] readRange(final ReadableByteChannel input, final int len) throws IOException { + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + final ByteBuffer b = ByteBuffer.allocate(Math.min(len, COPY_BUF_SIZE)); + int read = 0; + while (read < len) { + // Make sure we never read more than len bytes + b.limit(Math.min(len - read, b.capacity())); + final int readNow = input.read(b); + if (readNow <= 0) { + break; + } + output.write(b.array(), 0, readNow); + b.rewind(); + read += readNow; + } + return output.toByteArray(); + } + + /** + * Skips the given number of bytes by repeatedly invoking skip on + * the given input stream if necessary. + * + *

In a case where the stream's skip() method returns 0 before + * the requested number of bytes has been skip this implementation + * will fall back to using the read() method.

+ * + *

This method will only skip less than the requested number of + * bytes if the end of the input stream has been reached.

+ * + * @param input stream to skip bytes in + * @param numToSkip the number of bytes to skip + * @return the number of bytes actually skipped + * @throws IOException on error + */ + public static long skip(final InputStream input, long numToSkip) throws IOException { + final long available = numToSkip; + while (numToSkip > 0) { + final long skipped = input.skip(numToSkip); + if (skipped == 0) { + break; + } + numToSkip -= skipped; + } + + while (numToSkip > 0) { + final int read = readFully(input, SKIP_BUF, 0, + (int) Math.min(numToSkip, SKIP_BUF_SIZE)); + if (read < 1) { + break; + } + numToSkip -= read; + } + return available - numToSkip; + } + + /** + * Gets the contents of an {@code InputStream} as a {@code byte[]}. + *

+ * This method buffers the input internally, so there is no need to use a + * {@code BufferedInputStream}. + * + * @param input the {@code InputStream} to read from + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since 1.5 + */ + public static byte[] toByteArray(final InputStream input) throws IOException { + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy(input, output); + return output.toByteArray(); + } + + /** Private constructor to prevent instantiation of this utility class. */ + private IOUtils(){ + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/InputStreamStatistics.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/InputStreamStatistics.java new file mode 100644 index 0000000000..a46c791873 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/InputStreamStatistics.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.utils; + +/** + * This interface provides statistics on the current decompression stream. + * The stream consumer can use that statistics to handle abnormal + * compression ratios, i.e. to prevent ZIP bombs. + * + * @since 1.17 + */ +public interface InputStreamStatistics { + /** + * @return the amount of raw or compressed bytes read by the stream + */ + long getCompressedCount(); + + /** + * @return the amount of decompressed bytes returned by the stream + */ + long getUncompressedCount(); +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/MultiReadOnlySeekableByteChannel.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/MultiReadOnlySeekableByteChannel.java new file mode 100644 index 0000000000..8739ed2035 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/compress/utils/MultiReadOnlySeekableByteChannel.java @@ -0,0 +1,239 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.readium.r2.shared.util.archive.channel.compress.utils; + +import org.readium.r2.shared.util.archive.channel.jvm.ClosedChannelException; +import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException; +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * Read-Only Implementation of {@link SeekableByteChannel} that + * concatenates a collection of other {@link SeekableByteChannel}s. + * + *

This is a lose port of MultiReadOnlySeekableByteChannel + * by Tim Underwood.

+ * + * @since 1.19 + */ +public class MultiReadOnlySeekableByteChannel implements SeekableByteChannel { + + private static final Path[] EMPTY_PATH_ARRAY = {}; + + /** + * Concatenates the given channels. + * + * @param channels the channels to concatenate + * @throws NullPointerException if channels is null + * @return SeekableByteChannel that concatenates all provided channels + */ + public static SeekableByteChannel forSeekableByteChannels(final SeekableByteChannel... channels) { + if (Objects.requireNonNull(channels, "channels must not be null").length == 1) { + return channels[0]; + } + return new MultiReadOnlySeekableByteChannel(Arrays.asList(channels)); + } + + private final List channels; + + private long globalPosition; + + private int currentChannelIdx; + + /** + * Concatenates the given channels. + * + * @param channels the channels to concatenate + * @throws NullPointerException if channels is null + */ + public MultiReadOnlySeekableByteChannel(final List channels) { + this.channels = Collections.unmodifiableList(new ArrayList<>( + Objects.requireNonNull(channels, "channels must not be null"))); + } + + @Override + public void close() throws IOException { + IOException first = null; + for (final SeekableByteChannel ch : channels) { + try { + ch.close(); + } catch (final IOException ex) { + if (first == null) { + first = ex; + } + } + } + if (first != null) { + throw new IOException("failed to close wrapped channel", first); + } + } + + @Override + public boolean isOpen() { + for (SeekableByteChannel channel: channels) { + if (!channel.isOpen()) { + return false; + } + } + + return true; + } + + /** + * Returns this channel's position. + * + *

This method violates the contract of {@link SeekableByteChannel#position()} as it will not throw any exception + * when invoked on a closed channel. Instead it will return the position the channel had when close has been + * called.

+ */ + @Override + public long position() { + return globalPosition; + } + + @Override + public synchronized SeekableByteChannel position(final long newPosition) throws IOException { + if (newPosition < 0) { + throw new IllegalArgumentException("Negative position: " + newPosition); + } + if (!isOpen()) { + throw new ClosedChannelException(); + } + + globalPosition = newPosition; + + long pos = newPosition; + + for (int i = 0; i < channels.size(); i++) { + final SeekableByteChannel currentChannel = channels.get(i); + final long size = currentChannel.size(); + + final long newChannelPos; + if (pos == -1L) { + // Position is already set for the correct channel, + // the rest of the channels get reset to 0 + newChannelPos = 0; + } else if (pos <= size) { + // This channel is where we want to be + currentChannelIdx = i; + final long tmp = pos; + pos = -1L; // Mark pos as already being set + newChannelPos = tmp; + } else { + // newPosition is past this channel. Set channel + // position to the end and substract channel size from + // pos + pos -= size; + newChannelPos = size; + } + + currentChannel.position(newChannelPos); + } + return this; + } + + /** + * set the position based on the given channel number and relative offset + * + * @param channelNumber the channel number + * @param relativeOffset the relative offset in the corresponding channel + * @return global position of all channels as if they are a single channel + * @throws IOException if positioning fails + */ + public synchronized SeekableByteChannel position(final long channelNumber, final long relativeOffset) throws IOException { + if (!isOpen()) { + throw new ClosedChannelException(); + } + long globalPosition = relativeOffset; + for (int i = 0; i < channelNumber; i++) { + globalPosition += channels.get(i).size(); + } + + return position(globalPosition); + } + + @Override + public synchronized int read(final ByteBuffer dst) throws IOException { + if (!isOpen()) { + throw new ClosedChannelException(); + } + if (!dst.hasRemaining()) { + return 0; + } + + int totalBytesRead = 0; + while (dst.hasRemaining() && currentChannelIdx < channels.size()) { + final SeekableByteChannel currentChannel = channels.get(currentChannelIdx); + final int newBytesRead = currentChannel.read(dst); + if (newBytesRead == -1) { + // EOF for this channel -- advance to next channel idx + currentChannelIdx += 1; + continue; + } + if (currentChannel.position() >= currentChannel.size()) { + // we are at the end of the current channel + currentChannelIdx++; + } + totalBytesRead += newBytesRead; + } + if (totalBytesRead > 0) { + globalPosition += totalBytesRead; + return totalBytesRead; + } + return -1; + } + + @Override + public long size() throws IOException { + if (!isOpen()) { + throw new ClosedChannelException(); + } + long acc = 0; + for (final SeekableByteChannel ch : channels) { + acc += ch.size(); + } + return acc; + } + + /** + * @throws NonWritableChannelException since this implementation is read-only. + */ + @Override + public SeekableByteChannel truncate(final long size) { + throw new NonWritableChannelException(); + } + + /** + * @throws NonWritableChannelException since this implementation is read-only. + */ + @Override + public int write(final ByteBuffer src) { + throw new NonWritableChannelException(); + } + +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/AsynchronousCloseException.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/AsynchronousCloseException.java new file mode 100644 index 0000000000..a74f2f1b03 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/AsynchronousCloseException.java @@ -0,0 +1,14 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +/** + * An {@code AsynchronousCloseException} is thrown when the underlying channel + * for an I/O operation is closed by another thread. + */ +public class AsynchronousCloseException extends ClosedChannelException { + private static final long serialVersionUID = 6891178312432313966L; + /** + * Constructs an {@code AsynchronousCloseException}. + */ + public AsynchronousCloseException() { + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ByteChannel.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ByteChannel.java new file mode 100644 index 0000000000..509bf5d808 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ByteChannel.java @@ -0,0 +1,13 @@ +package org.readium.r2.shared.util.archive.channel.jvm; +/** + * A ByteChannel is both readable and writable. + *

+ * The methods for the byte channel are precisely those defined by readable and + * writable byte channels. + * + * @see ReadableByteChannel + * @see WritableByteChannel + */ +public interface ByteChannel extends ReadableByteChannel, WritableByteChannel { + // No methods defined. +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/Channel.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/Channel.java new file mode 100644 index 0000000000..3412ebfd92 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/Channel.java @@ -0,0 +1,39 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +import java.io.Closeable; +import java.io.IOException; + +/** + * A channel is a conduit to I/O services covering such items as files, sockets, + * hardware devices, I/O ports or some software component. + *

+ * Channels are open upon creation, and can be closed explicitly. Once a channel + * is closed it cannot be re-opened, and any attempts to perform I/O operations + * on the closed channel result in a ClosedChannelException. + *

+ * Particular implementations or sub-interfaces of {@code Channel} dictate + * whether they are thread-safe or not. + */ +public interface Channel extends Closeable { + /** + * Returns true if this channel is open. + */ + public boolean isOpen(); + /** + * Closes an open channel. If the channel is already closed then this method + * has no effect. If there is a problem with closing the channel then the + * method throws an IOException and the exception contains reasons for the + * failure. + *

+ * If an attempt is made to perform an operation on a closed channel then a + * {@link ClosedChannelException} will be thrown on that attempt. + *

+ * If multiple threads attempt to simultaneously close a channel, then only + * one thread will run the closure code, and others will be blocked until + * the first returns. + * + * @throws IOException + * if a problem occurs closing the channel. + */ + public void close() throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedByInterruptException.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedByInterruptException.java new file mode 100644 index 0000000000..209a18df83 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedByInterruptException.java @@ -0,0 +1,18 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +/** + * A {@code ClosedByInterruptException} is thrown when a thread is interrupted + * in a blocking I/O operation. + *

+ * When the thread is interrupted by a call to {@code interrupt()}, it closes + * the channel, sets the interrupt status of the thread to {@code true} and + * throws a {@code ClosedByInterruptException}. + */ +public class ClosedByInterruptException extends AsynchronousCloseException { + private static final long serialVersionUID = -4488191543534286750L; + /** + * Constructs a {@code ClosedByInterruptException}. + */ + public ClosedByInterruptException() { + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedChannelException.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedChannelException.java new file mode 100644 index 0000000000..52033cd53d --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ClosedChannelException.java @@ -0,0 +1,15 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +import java.io.IOException; +/** + * A {@code ClosedChannelException} is thrown when a channel is closed for the + * type of operation attempted. + */ +public class ClosedChannelException extends IOException { + private static final long serialVersionUID = 882777185433553857L; + /** + * Constructs a {@code ClosedChannelException}. + */ + public ClosedChannelException() { + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonReadableChannelException.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonReadableChannelException.java new file mode 100644 index 0000000000..2bf28970e0 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonReadableChannelException.java @@ -0,0 +1,14 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +/** + * A {@code NonReadableChannelException} is thrown when attempting to read from + * a channel that is not open for reading. + */ +public class NonReadableChannelException extends IllegalStateException { + private static final long serialVersionUID = -3200915679294993514L; + /** + * Constructs a {@code NonReadableChannelException}. + */ + public NonReadableChannelException() { + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonWritableChannelException.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonWritableChannelException.java new file mode 100644 index 0000000000..88799aa269 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/NonWritableChannelException.java @@ -0,0 +1,14 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +/** + * A {@code NonWritableChannelException} is thrown when attempting to write to a + * channel that is not open for writing. + */ +public class NonWritableChannelException extends IllegalStateException { + private static final long serialVersionUID = -7071230488279011621L; + /** + * Constructs a {@code NonWritableChannelException}. + */ + public NonWritableChannelException() { + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ReadableByteChannel.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ReadableByteChannel.java new file mode 100644 index 0000000000..845898be59 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/ReadableByteChannel.java @@ -0,0 +1,48 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +import java.io.IOException; +import java.nio.ByteBuffer; +/** + * A {@code ReadableByteChannel} is a type of {@link Channel} that can read + * bytes. + *

+ * Read operations are synchronous on a {@code ReadableByteChannel}, that is, + * if a read is already in progress on the channel then subsequent reads will + * block until the first read completes. It is undefined whether non-read + * operations will block. + */ +public interface ReadableByteChannel extends Channel { + /** + * Reads bytes from the channel into the given buffer. + *

+ * The maximum number of bytes that will be read is the + * {@link java.nio.Buffer#remaining() remaining} number of bytes in the + * buffer when the method is invoked. The bytes will be read into the buffer + * starting at the buffer's current + * {@link java.nio.Buffer#position() position}. + *

+ * The call may block if other threads are also attempting to read from the + * same channel. + *

+ * Upon completion, the buffer's {@code position} is updated to the end of + * the bytes that were read. The buffer's + * {@link java.nio.Buffer#limit() limit} is not changed. + * + * @param buffer + * the byte buffer to receive the bytes. + * @return the number of bytes actually read. + * @throws AsynchronousCloseException + * if another thread closes the channel during the read. + * @throws ClosedByInterruptException + * if another thread interrupts the calling thread while the + * operation is in progress. The interrupt state of the calling + * thread is set and the channel is closed. + * @throws ClosedChannelException + * if the channel is closed. + * @throws IOException + * another I/O error occurs, details are in the message. + * @throws NonReadableChannelException + * if the channel was not opened for reading. + */ + public int read(ByteBuffer buffer) throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/SeekableByteChannel.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/SeekableByteChannel.java new file mode 100644 index 0000000000..19039764da --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/SeekableByteChannel.java @@ -0,0 +1,139 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +import java.io.IOException; +import java.nio.ByteBuffer; +/** + * An interface for channels that keep a pointer to a current position within an underlying + * byte-based data source such as a file. + * + *

SeekableByteChannels have a pointer into the underlying data source which is referred to as a + * position. The position can be manipulated by moving it within the data source, and the + * current position can be queried. + * + *

SeekableByteChannels also have an associated size. The size of the channel is the + * number of bytes that the data source currently contains. The size of the data source can be + * manipulated by adding more bytes to the end or by removing bytes from the end. See + * {@link #truncate}, {@link #position} and {@link #write} for details. The current size can also + * be queried. + * + * @hide Until ready for a public API change + * @since 1.7 + */ +public interface SeekableByteChannel extends ByteChannel { + /** + * Returns the current position as a positive number of bytes from the start of the underlying + * data source. + * + * @throws ClosedChannelException + * if this channel is closed. + * @throws IOException + * if another I/O error occurs. + */ + long position() throws IOException; + /** + * Sets the channel's position to {@code newPosition}. + * + *

The argument is the number of bytes counted from the start of the data source. The position + * cannot be set to a value that is negative. The new position can be set beyond the current + * size. If set beyond the current size, attempts to read will return end-of-file. Write + * operations will succeed but they will fill the bytes between the current end of the data + * source + * and the new position with the required number of (unspecified) byte values. + * + * @return the channel. + * @throws IllegalArgumentException + * if the new position is negative. + * @throws ClosedChannelException + * if this channel is closed. + * @throws IOException + * if another I/O error occurs. + */ + SeekableByteChannel position(long newPosition) throws IOException; + /** + * Returns the size of the data source underlying this channel in bytes. + * + * @throws ClosedChannelException + * if this channel is closed. + * @throws IOException + * if an I/O error occurs. + */ + long size() throws IOException; + /** + * Truncates the data source underlying this channel to a given size. Any bytes beyond the given + * size are removed. If there are no bytes beyond the given size then the contents are + * unmodified. + * + *

If the position is currently greater than the given size, then it is set to the new size. + * + * @return this channel. + * @throws IllegalArgumentException + * if the requested size is negative. + * @throws ClosedChannelException + * if this channel is closed. + * @throws NonWritableChannelException + * if the channel cannot be written to. + * @throws IOException + * if another I/O error occurs. + */ + SeekableByteChannel truncate(long size) throws IOException; + /** + * Writes bytes from the given byte buffer to this channel. + * + *

The bytes are written starting at the channel's current position, and after some number of + * bytes are written (up to the {@link java.nio.Buffer#remaining() remaining} number of bytes in + * the buffer) the channel's position is increased by the number of bytes actually written. + * + *

If the channel's position is beyond the current end of the underlying data source, then the + * data source is first extended up to the given position by the required number of unspecified + * byte values. + * + * @param buffer + * the byte buffer containing the bytes to be written. + * @return the number of bytes actually written. + * @throws NonWritableChannelException + * if the channel was not opened for writing. + * @throws ClosedChannelException + * if the channel was already closed. + * @throws AsynchronousCloseException + * if another thread closes the channel during the write. + * @throws ClosedByInterruptException + * if another thread interrupts the calling thread while this operation is in progress. The + * interrupt state of the calling thread is set and the channel is closed. + * @throws IOException + * if another I/O error occurs, details are in the message. + */ + @Override + int write(ByteBuffer buffer) throws IOException; + /** + * Reads bytes from this channel into the given buffer. + * + *

If the channels position is beyond the current end of the underlying data source then + * end-of-file (-1) is returned. + * + *

The bytes are read starting at the channel's current position, and after some number of + * bytes are read (up to the {@link java.nio.Buffer#remaining() remaining} number of bytes in the + * buffer) the channel's position is increased by the number of bytes actually read. The bytes + * will be read into the buffer starting at the buffer's current + * {@link java.nio.Buffer#position() position}. The buffer's {@link java.nio.Buffer#limit() + * limit} is not changed. + * + *

The call may block if other threads are also attempting to read from the same channel. + * + * @param buffer + * the byte buffer to receive the bytes. + * @return the number of bytes actually read, or -1 if the end of the data has been reached + * @throws AsynchronousCloseException + * if another thread closes the channel during the read. + * @throws ClosedByInterruptException + * if another thread interrupts the calling thread while the operation is in progress. The + * interrupt state of the calling thread is set and the channel is closed. + * @throws ClosedChannelException + * if the channel is closed. + * @throws IOException + * another I/O error occurs, details are in the message. + * @throws NonReadableChannelException + * if the channel was not opened for reading. + */ + @Override + int read(ByteBuffer buffer) throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/WritableByteChannel.java b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/WritableByteChannel.java new file mode 100644 index 0000000000..3db47ea6bb --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/jvm/WritableByteChannel.java @@ -0,0 +1,46 @@ +package org.readium.r2.shared.util.archive.channel.jvm; + +import java.io.IOException; +import java.nio.ByteBuffer; +/** + * A {@code WritableByteChannel} is a type of {@link Channel} that can write + * bytes. + *

+ * Write operations are synchronous on a {@code WritableByteChannel}, that is, + * if a write is already in progress on the channel then subsequent writes will + * block until the first write completes. It is undefined whether non-write + * operations will block. + */ +public interface WritableByteChannel extends Channel { + /** + * Writes bytes from the given buffer to the channel. + *

+ * The maximum number of bytes that will be written is the + * remaining() number of bytes in the buffer when the method + * invoked. The bytes will be written from the buffer starting at the + * buffer's position. + *

+ * The call may block if other threads are also attempting to write on the + * same channel. + *

+ * Upon completion, the buffer's position() is updated to the + * end of the bytes that were written. The buffer's limit() + * is unmodified. + * + * @param buffer + * the byte buffer containing the bytes to be written. + * @return the number of bytes actually written. + * @throws NonWritableChannelException + * if the channel was not opened for writing. + * @throws ClosedChannelException + * if the channel was already closed. + * @throws AsynchronousCloseException + * if another thread closes the channel during the write. + * @throws ClosedByInterruptException + * if another thread interrupt the calling thread during the + * write. + * @throws IOException + * another IO exception occurs, details are in the message. + */ + public int write(ByteBuffer buffer) throws IOException; +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt index b2f0ed2567..10ca73061e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt @@ -18,9 +18,12 @@ import org.readium.r2.shared.extensions.requireLengthFitInt * An [InputStream] counting the number of bytes read from a wrapped [inputStream]. */ @InternalReadiumApi -class CountingInputStream(inputStream: InputStream) : FilterInputStream(inputStream) { +class CountingInputStream( + inputStream: InputStream, + initialCount: Long = 0 +) : FilterInputStream(inputStream) { - var count: Long = 0 + var count: Long = initialCount private set private var mark: Long = -1 diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt index c210082c42..a1e62eb3f7 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt @@ -13,6 +13,7 @@ import java.io.File import java.io.InputStream import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.readium.r2.shared.extensions.tryOrNull import timber.log.Timber /** Provides an access to a file's content to sniff its format. */ @@ -66,15 +67,18 @@ internal class SnifferBytesContent(val getBytes: () -> ByteArray) : SnifferConte private suspend fun bytes(): ByteArray { if (!this::_bytes.isInitialized) { - _bytes = withContext(Dispatchers.IO) { getBytes() } + withContext(Dispatchers.IO) { + _bytes = getBytes() + } } return _bytes } - override suspend fun read(): ByteArray? = bytes() + override suspend fun read(): ByteArray? = + tryOrNull { bytes() } override suspend fun stream(): InputStream? = - ByteArrayInputStream(bytes()) + tryOrNull { ByteArrayInputStream(bytes()) } } /** Used to sniff a content URI. */ diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt index 53ef4b20f7..6d3dafae0c 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt @@ -130,7 +130,7 @@ class SnifferContext internal constructor( loadedContentAsArchive = true _contentAsArchive = withContext(Dispatchers.IO) { (content as? SnifferFileContent)?.let { - DefaultArchiveFactory().open(it.file, password = null) + tryOrNull { DefaultArchiveFactory().open(it.file, password = null) } } } } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/util/archive/ArchiveTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/util/archive/ArchiveTest.kt index 8ebbe189da..2d1d181666 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/util/archive/ArchiveTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/util/archive/ArchiveTest.kt @@ -19,6 +19,7 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized +import org.readium.r2.shared.util.archive.channel.ChannelZipArchiveFactory @RunWith(Parameterized::class) class ArchiveTest(val archive: Archive) { @@ -32,13 +33,15 @@ class ArchiveTest(val archive: Archive) { assertNotNull(epubZip) val zipArchive = runBlocking { DefaultArchiveFactory().open(File(epubZip.path), password = null) } assertNotNull(zipArchive) + val apacheZipArchive = runBlocking { ChannelZipArchiveFactory().openFile(File(epubZip.path)) } + assertNotNull(apacheZipArchive) val epubExploded = ArchiveTest::class.java.getResource("epub") assertNotNull(epubExploded) val explodedArchive = runBlocking { DefaultArchiveFactory().open(File(epubExploded.path), password = null) } assertNotNull(explodedArchive) - return listOf(zipArchive, explodedArchive) + return listOf(zipArchive, apacheZipArchive, explodedArchive) } } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationParser.kt deleted file mode 100644 index 3a82ea8fd0..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationParser.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.streamer - -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.PublicationAsset -import org.readium.r2.shared.util.logging.WarningLogger - -/** - * Parses a Publication from an asset. - */ -interface PublicationParser { - - /** - * Constructs a [Publication.Builder] to build a [Publication] from a publication asset. - * - * @param asset Digital medium (e.g. a file) used to access the publication. - * @param fetcher Initial leaf fetcher which should be used to read the publication's resources. - * This can be used to: - * - support content protection technologies - * - parse exploded archives or in archiving formats unknown to the parser, e.g. RAR - * If the asset is not an archive, it will be reachable at the HREF /, - * e.g. with a PDF. - * @param warnings Used to report non-fatal parsing warnings, such as publication authoring - * mistakes. This is useful to warn users of potential rendering issues or help authors - * debug their publications. - */ - suspend fun parse(asset: PublicationAsset, fetcher: Fetcher, warnings: WarningLogger? = null): Publication.Builder? -} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt index 3c135b2a1d..d1b3f8f09b 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt @@ -14,15 +14,20 @@ import org.readium.r2.shared.PdfSupport import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.ContentProtection import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.asset.DefaultPublicationAssetFactory import org.readium.r2.shared.publication.asset.PublicationAsset +import org.readium.r2.shared.publication.asset.PublicationAssetFactory import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.archive.ArchiveFactory import org.readium.r2.shared.util.archive.DefaultArchiveFactory +import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.pdf.PdfDocumentFactory import org.readium.r2.streamer.parser.FallbackContentProtection +import org.readium.r2.streamer.parser.PublicationParser import org.readium.r2.streamer.parser.audio.AudioParser import org.readium.r2.streamer.parser.epub.EpubParser import org.readium.r2.streamer.parser.epub.setLayoutStyle @@ -43,9 +48,13 @@ internal typealias PublicationTry = Try? = null, private val httpClient: DefaultHttpClient = DefaultHttpClient(), + private val publicationAssetFactory: PublicationAssetFactory = + DefaultPublicationAssetFactory(archiveFactory, httpClient), private val onCreatePublication: Publication.Builder.() -> Unit = {} ) { - private val context = context.applicationContext private val contentProtections: List = contentProtections + listOf(FallbackContentProtection()) + /** + * Parses a [Publication] available at [url]. + * + * If you are opening the publication to render it in a Navigator, you must set [allowUserInteraction] + * to true to prompt the user for its credentials when the publication is protected. However, + * set it to false if you just want to import the [Publication] without reading its content, to + * avoid prompting the user. + * + * When using Content Protections, you can use [sender] to provide a free object which can be + * used to give some context. For example, it could be the source Activity or Fragment which + * would be used to present a credentials dialog. + * + * The [warnings] logger can be used to observe non-fatal parsing warnings, caused by + * publication authoring mistakes. This can be useful to warn users of potential rendering + * issues. + * + * @param url Publication url. Supported protocols depend on your [PublicationAssetFactory]. + * @param credentials Credentials that Content Protections can use to attempt to unlock a + * publication, for example a password. + * @param allowUserInteraction Indicates whether the user can be prompted, for example for its + * credentials. + * @param sender Free object that can be used by reading apps to give some UX context when + * presenting dialogs. + * @param onCreatePublication Transformation which will be applied on the Publication Builder. + * It can be used to modify the [Manifest], the root [Fetcher] or the list of service + * factories of the [Publication]. + * @param warnings Logger used to broadcast non-fatal parsing warnings. + * @return Null if the asset was not recognized by any parser, or a + * [Publication.OpeningException] in case of failure. + */ + suspend fun open( + url: Url, + mediaType: MediaType, + credentials: String? = null, + allowUserInteraction: Boolean, + sender: Any? = null, + onCreatePublication: Publication.Builder.() -> Unit = {}, + warnings: WarningLogger? = null + ): PublicationTry = + publicationAssetFactory + .createAsset(url, mediaType) + .flatMap { asset -> open(asset, credentials, allowUserInteraction, sender, onCreatePublication, warnings) } + /** * Parses a [Publication] from the given asset. * @@ -104,26 +157,18 @@ class Streamer constructor( warnings: WarningLogger? = null ): PublicationTry = try { - @Suppress("NAME_SHADOWING") - var asset = asset - var fetcher = asset.createFetcher(PublicationAsset.Dependencies(archiveFactory = archiveFactory), credentials = credentials) - .getOrThrow() - val protectedAsset = contentProtections .lazyMapFirstNotNullOrNull { - it.open(asset, fetcher, credentials, allowUserInteraction, sender) + it.open(asset, credentials, allowUserInteraction, sender) } ?.getOrThrow() - if (protectedAsset != null) { - asset = protectedAsset.asset - fetcher = protectedAsset.fetcher - } + val newAsset = protectedAsset?.asset ?: asset val builder = parsers .lazyMapFirstNotNullOrNull { try { - it.parse(asset, fetcher, warnings) + it.parse(newAsset, warnings) } catch (e: Exception) { throw Publication.OpeningException.ParsingFailed(e) } @@ -137,7 +182,7 @@ class Streamer constructor( builder.apply(onCreatePublication) val publication = builder.build() - .apply { addLegacyProperties(asset.mediaType()) } + .apply { addLegacyProperties(asset.mediaType) } Try.success(publication) } catch (e: Publication.OpeningException) { @@ -148,7 +193,7 @@ class Streamer constructor( listOfNotNull( EpubParser(), pdfFactory?.let { PdfParser(context, it) }, - ReadiumWebPubParser(context, pdfFactory, httpClient), + ReadiumWebPubParser(context, pdfFactory), ImageParser(), AudioParser() ) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/container/PublicationContainer.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/container/PublicationContainer.kt deleted file mode 100644 index d89b51ef5e..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/container/PublicationContainer.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Module: r2-streamer-kotlin - * Developers: Mickaël Menu - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.streamer.container - -import java.io.InputStream -import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.RootFile -import org.readium.r2.shared.drm.DRM -import org.readium.r2.shared.extensions.tryOr -import org.readium.r2.shared.fetcher.ResourceInputStream -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.mediatype.MediaType - -/** - * Temporary solution to migrate to [Publication.get] while ensuring backward compatibility with - * [Container]. - */ -internal class PublicationContainer( - private val publication: Publication, - path: String, - mediaType: MediaType, - override var drm: DRM? = null -) : Container { - - override var rootFile = RootFile(rootPath = path, mimetype = mediaType.toString()) - - @Deprecated("Use [publication.get()] to access publication content.") - override fun data(relativePath: String): ByteArray = runBlocking { - publication.get(relativePath).read().getOrThrow() - } - - @Deprecated("Use [publication.get()] to access publication content.") - override fun dataLength(relativePath: String): Long = runBlocking { - tryOr(0) { - publication.get(relativePath).length().getOrThrow() - } - } - - @Deprecated("Use [publication.get()] to access publication content.") - override fun dataInputStream(relativePath: String): InputStream = - ResourceInputStream(publication.get(relativePath)).buffered() - - private fun Publication.get(href: String) = get(Link(href)) -} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/FallbackContentProtection.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/FallbackContentProtection.kt index 9ee1481285..b32ebcffb8 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/FallbackContentProtection.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/FallbackContentProtection.kt @@ -43,17 +43,15 @@ internal class FallbackContentProtection : ContentProtection { override suspend fun open( asset: PublicationAsset, - fetcher: Fetcher, credentials: String?, allowUserInteraction: Boolean, sender: Any? ): Try? { - val scheme: Scheme = sniffScheme(fetcher, asset.mediaType()) + val scheme: Scheme = sniffScheme(asset.fetcher, asset.mediaType) ?: return null val protectedFile = ContentProtection.ProtectedAsset( asset = asset, - fetcher = fetcher, onCreatePublication = { servicesBuilder.contentProtectionServiceFactory = Service.createFactory(scheme) } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt index d118a578fc..469ccd0354 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt @@ -1,21 +1,27 @@ /* - * Module: r2-streamer-kotlin - * Developers: Quentin Gliosca, Aferdita Muriqi, Clément Baumann - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2020 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.streamer.parser -import java.io.File import org.readium.r2.shared.publication.Publication -import org.readium.r2.streamer.container.Container - -data class PubBox(var publication: Publication, var container: Container) +import org.readium.r2.shared.publication.asset.PublicationAsset +import org.readium.r2.shared.util.logging.WarningLogger +/** + * Parses a Publication from an asset. + */ interface PublicationParser { - fun parse(fileAtPath: String, fallbackTitle: String = File(fileAtPath).name): PubBox? + /** + * Constructs a [Publication.Builder] to build a [Publication] from a publication asset. + * + * @param asset Publication asset. + * @param warnings Used to report non-fatal parsing warnings, such as publication authoring + * mistakes. This is useful to warn users of potential rendering issues or help authors + * debug their publications. + */ + suspend fun parse(asset: PublicationAsset, warnings: WarningLogger? = null): Publication.Builder? } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioBookParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioBookParser.kt deleted file mode 100644 index 030f1faf11..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioBookParser.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Module: r2-streamer-kotlin - * Developers: Aferdita Muriqi, Irteza Sheikh - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.streamer.parser.audio - -import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Manifest -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.streamer.container.ContainerError -import org.readium.r2.streamer.container.PublicationContainer -import org.readium.r2.streamer.extensions.fromArchiveOrDirectory -import org.readium.r2.streamer.extensions.readAsJsonOrNull -import org.readium.r2.streamer.parser.PubBox -import org.readium.r2.streamer.parser.PublicationParser - -class AudioBookConstant { - companion object { - @Deprecated("Use [MediaType.AUDIOBOOK.toString()] instead", replaceWith = ReplaceWith("MediaType.AUDIOBOOK.toString()")) - val mimetype get() = MediaType.READIUM_AUDIOBOOK.toString() - } -} - -/** - * AudiobookParser : Handle any Audiobook Package file. Opening, listing files - * get name of the resource, creating the Publication - * for rendering - */ -class AudioBookParser : PublicationParser { - - /** - * This functions parse a manifest.json and build PubBox object from it - */ - override fun parse(fileAtPath: String, fallbackTitle: String): PubBox? = runBlocking { - _parse(fileAtPath) - } - - private suspend fun _parse(fileAtPath: String): PubBox? { - val fetcher = Fetcher.fromArchiveOrDirectory(fileAtPath) - ?: throw ContainerError.missingFile(fileAtPath) - - val manifest = fetcher.readAsJsonOrNull("manifest.json") - ?.let { Manifest.fromJSON(it, packaged = true) } - ?: return null - - val publication = Publication( - manifest = manifest - ).apply { - @Suppress("DEPRECATION") - type = Publication.TYPE.AUDIO - } - - val container = PublicationContainer( - publication = publication, - path = fileAtPath, - mediaType = MediaType.READIUM_AUDIOBOOK - ) - - return PubBox(publication, container) - } -} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt index 8d39de6c63..b4affbfe9d 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt @@ -1,10 +1,7 @@ /* - * Module: r2-streamer-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.streamer.parser.audio @@ -15,10 +12,10 @@ import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.asset.PublicationAsset import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.streamer.PublicationParser import org.readium.r2.streamer.extensions.guessTitle import org.readium.r2.streamer.extensions.isHiddenOrThumbs import org.readium.r2.streamer.extensions.lowercasedExtension +import org.readium.r2.streamer.parser.PublicationParser /** * Parses an audiobook Publication from an unstructured archive format containing audio files, @@ -28,12 +25,12 @@ import org.readium.r2.streamer.extensions.lowercasedExtension */ class AudioParser : PublicationParser { - override suspend fun parse(asset: PublicationAsset, fetcher: Fetcher, warnings: WarningLogger?): Publication.Builder? { + override suspend fun parse(asset: PublicationAsset, warnings: WarningLogger?): Publication.Builder? { - if (!accepts(asset, fetcher)) + if (!accepts(asset.mediaType, asset.fetcher)) return null - val readingOrder = fetcher.links() + val readingOrder = asset.fetcher.links() .filter { link -> with(File(link.href)) { lowercasedExtension in audioExtensions && !isHiddenOrThumbs } } .sortedBy(Link::href) .toMutableList() @@ -41,7 +38,7 @@ class AudioParser : PublicationParser { if (readingOrder.isEmpty()) throw Exception("No audio file found in the publication.") - val title = fetcher.guessTitle() ?: asset.name + val title = asset.fetcher.guessTitle() ?: asset.name val manifest = Manifest( metadata = Metadata( @@ -53,15 +50,15 @@ class AudioParser : PublicationParser { return Publication.Builder( manifest = manifest, - fetcher = fetcher, + fetcher = asset.fetcher, servicesBuilder = Publication.ServicesBuilder( locator = AudioLocatorService.createFactory() ) ) } - private suspend fun accepts(asset: PublicationAsset, fetcher: Fetcher): Boolean { - if (asset.mediaType() == MediaType.ZAB) + private suspend fun accepts(mediaType: MediaType, fetcher: Fetcher): Boolean { + if (mediaType == MediaType.ZAB) return true val allowedExtensions = audioExtensions + diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/cbz/CBZParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/cbz/CBZParser.kt deleted file mode 100644 index 8b254c96f1..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/cbz/CBZParser.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Module: r2-streamer-kotlin - * Developers: Aferdita Muriqi, Clément Baumann - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.streamer.parser.cbz - -import java.io.File -import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.LocalizedString -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.FileAsset -import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.streamer.container.ContainerError -import org.readium.r2.streamer.container.PublicationContainer -import org.readium.r2.streamer.extensions.fromArchiveOrDirectory -import org.readium.r2.streamer.parser.PubBox -import org.readium.r2.streamer.parser.PublicationParser -import org.readium.r2.streamer.parser.image.ImageParser - -@Deprecated("Use [MediaType] instead") -class CBZConstant { - companion object { - @Deprecated("Use [MediaType.CBZ.toString()] instead", replaceWith = ReplaceWith("MediaType.CBZ.toString()")) - val mimetypeCBZ get() = MediaType.CBZ.toString() - @Deprecated("RAR archives are not supported in Readium, don't use this constant", level = DeprecationLevel.ERROR) - const val mimetypeCBR = "application/x-cbr" - @Deprecated("Use [MediaType.JPEG.toString()] instead", replaceWith = ReplaceWith("MediaType.JPEG.toString()")) - val mimetypeJPEG get() = MediaType.JPEG.toString() - @Deprecated("Use [MediaType.PNG.toString()] instead", replaceWith = ReplaceWith("MediaType.PNG.toString()")) - val mimetypePNG = MediaType.PNG.toString() - } -} - -/** - * CBZParser : Handle any CBZ file. Opening, listing files - * get name of the resource, creating the Publication - * for rendering - */ -class CBZParser : PublicationParser { - - private val imageParser = ImageParser() - - override fun parse(fileAtPath: String, fallbackTitle: String): PubBox? = runBlocking { - makePubBox(fileAtPath, fallbackTitle) - } - - private suspend fun makePubBox(fileAtPath: String, fallbackTitle: String): PubBox? { - - val file = File(fileAtPath) - - val fetcher = Fetcher.fromArchiveOrDirectory(fileAtPath) - ?: throw ContainerError.missingFile(fileAtPath) - - val publication = imageParser.parse(FileAsset(file), fetcher) - ?.apply { - val title = LocalizedString(fallbackTitle) - val metadata = manifest.metadata.copy(localizedTitle = title) - manifest = manifest.copy(metadata = metadata) - } - ?.build() - ?.apply { - @Suppress("DEPRECATION") - type = Publication.TYPE.CBZ - } - ?: return null - - val container = PublicationContainer( - publication = publication, - path = file.canonicalPath, - mediaType = MediaType.CBZ - ) - - return PubBox(publication, container) - } -} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/divina/DiViNaParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/divina/DiViNaParser.kt deleted file mode 100644 index 489f80153f..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/divina/DiViNaParser.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Module: r2-streamer-kotlin - * Developers: Aferdita Muriqi - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.streamer.parser.divina - -import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Manifest -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.services.PerResourcePositionsService -import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.streamer.container.ContainerError -import org.readium.r2.streamer.container.PublicationContainer -import org.readium.r2.streamer.extensions.fromArchiveOrDirectory -import org.readium.r2.streamer.extensions.readAsJsonOrNull -import org.readium.r2.streamer.parser.PubBox -import org.readium.r2.streamer.parser.PublicationParser - -class DiViNaConstant { - companion object { - @Deprecated("Use [MediaType.DIVINA_MANIFEST.toString()] instead", replaceWith = ReplaceWith("MediaType.DIVINA_MANIFEST.toString()"), level = DeprecationLevel.ERROR) - val mimetype get() = MediaType.DIVINA_MANIFEST.toString() - } -} - -/** - * DiViNaParser : Handle any DiViNa file. Opening, listing files - * get name of the resource, creating the Publication - * for rendering - */ -class DiViNaParser : PublicationParser { - override fun parse(fileAtPath: String, fallbackTitle: String): PubBox? = runBlocking { - _parse(fileAtPath) - } - - private suspend fun _parse(fileAtPath: String): PubBox? { - val fetcher = Fetcher.fromArchiveOrDirectory(fileAtPath) - ?: throw ContainerError.missingFile(fileAtPath) - - val manifest = fetcher.readAsJsonOrNull("manifest.json") - .let { Manifest.fromJSON(it) } - ?: return null - - val publication = Publication( - manifest = manifest, - servicesBuilder = Publication.ServicesBuilder( - positions = PerResourcePositionsService.createFactory(fallbackMediaType = "image/*") - ) - ).apply { - @Suppress("DEPRECATION") - type = Publication.TYPE.DiViNa - } - - val container = PublicationContainer( - publication = publication, - path = fileAtPath, - mediaType = MediaType.DIVINA - ) - return PubBox(publication, container) - } -} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt index ef38fcf073..f7c2d799ac 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt @@ -8,8 +8,6 @@ package org.readium.r2.streamer.parser.epub -import java.io.File -import kotlinx.coroutines.runBlocking import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.ReadiumCSSName import org.readium.r2.shared.Search @@ -19,7 +17,6 @@ import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.TransformingFetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.FileAsset import org.readium.r2.shared.publication.asset.PublicationAsset import org.readium.r2.shared.publication.encryption.Encryption import org.readium.r2.shared.publication.services.content.DefaultContentService @@ -28,15 +25,9 @@ import org.readium.r2.shared.publication.services.search.StringSearchService import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.use -import org.readium.r2.streamer.PublicationParser import org.readium.r2.streamer.container.Container -import org.readium.r2.streamer.container.ContainerError -import org.readium.r2.streamer.container.PublicationContainer -import org.readium.r2.streamer.extensions.fromArchiveOrDirectory import org.readium.r2.streamer.extensions.readAsXmlOrNull -import org.readium.r2.streamer.fetcher.LcpDecryptor -import org.readium.r2.streamer.parser.PubBox +import org.readium.r2.streamer.parser.PublicationParser @Suppress("DEPRECATION") object EPUBConstant { @@ -85,34 +76,30 @@ object EPUBConstant { * @param reflowablePositionsStrategy Strategy used to calculate the number of positions in a * reflowable resource. */ +@OptIn(ExperimentalReadiumApi::class, Search::class) class EpubParser( private val reflowablePositionsStrategy: EpubPositionsService.ReflowableStrategy = EpubPositionsService.ReflowableStrategy.recommended -) : PublicationParser, org.readium.r2.streamer.parser.PublicationParser { +) : PublicationParser { - override suspend fun parse(asset: PublicationAsset, fetcher: Fetcher, warnings: WarningLogger?): Publication.Builder? = - _parse(asset, fetcher, asset.name) - - @OptIn(Search::class, ExperimentalReadiumApi::class) - suspend fun _parse(asset: PublicationAsset, fetcher: Fetcher, fallbackTitle: String): Publication.Builder? { - - if (asset.mediaType() != MediaType.EPUB) + override suspend fun parse(asset: PublicationAsset, warnings: WarningLogger?): Publication.Builder? { + if (asset.mediaType != MediaType.EPUB) return null - val opfPath = getRootFilePath(fetcher).addPrefix("/") - val opfXmlDocument = fetcher.get(opfPath).readAsXml().getOrThrow() + val opfPath = getRootFilePath(asset.fetcher).addPrefix("/") + val opfXmlDocument = asset.fetcher.get(opfPath).readAsXml().getOrThrow() val packageDocument = PackageDocument.parse(opfXmlDocument, opfPath) ?: throw Exception("Invalid OPF file.") val manifest = ManifestAdapter( - fallbackTitle = fallbackTitle, + fallbackTitle = asset.name, packageDocument = packageDocument, - navigationData = parseNavigationData(packageDocument, fetcher), - encryptionData = parseEncryptionData(fetcher), - displayOptions = parseDisplayOptions(fetcher) + navigationData = parseNavigationData(packageDocument, asset.fetcher), + encryptionData = parseEncryptionData(asset.fetcher), + displayOptions = parseDisplayOptions(asset.fetcher) ).adapt() @Suppress("NAME_SHADOWING") - var fetcher = fetcher + var fetcher = asset.fetcher manifest.metadata.identifier?.let { fetcher = TransformingFetcher(fetcher, EpubDeobfuscator(it)::transform) } @@ -132,50 +119,6 @@ class EpubParser( ) } - override fun parse( - fileAtPath: String, - fallbackTitle: String - ): PubBox? = runBlocking { - - val file = File(fileAtPath) - val asset = FileAsset(file) - - var fetcher = Fetcher.fromArchiveOrDirectory(fileAtPath) - ?: throw ContainerError.missingFile(fileAtPath) - - val drm = if (fetcher.isProtectedWithLcp()) DRM(DRM.Brand.lcp) else null - if (drm?.brand == DRM.Brand.lcp) { - fetcher = TransformingFetcher(fetcher, LcpDecryptor(drm)::transform) - } - - val builder = try { - _parse(asset, fetcher, fallbackTitle) - } catch (e: Exception) { - return@runBlocking null - } ?: return@runBlocking null - - val publication = builder.build() - .apply { - @Suppress("DEPRECATION") - type = Publication.TYPE.EPUB - - // This might need to be moved as it's not really about parsing the EPUB but it - // sets values needed (in UserSettings & ContentFilter) - setLayoutStyle() - } - - val container = PublicationContainer( - publication = publication, - path = file.canonicalPath, - mediaType = MediaType.EPUB, - drm = drm - ).apply { - rootFile.rootFilePath = getRootFilePath(fetcher) - } - - PubBox(publication, container) - } - private suspend fun getRootFilePath(fetcher: Fetcher): String = fetcher.readAsXmlOrNull("/META-INF/container.xml") ?.getFirst("rootfiles", Namespaces.OPC) @@ -254,6 +197,3 @@ internal fun Publication.setLayoutStyle() { ReadiumCssLayout.CJK_HORIZONTAL -> EPUBConstant.cjkHorizontalPreset } } - -private suspend fun Fetcher.isProtectedWithLcp(): Boolean = - get("/META-INF/license.lcpl").use { it.length().isSuccess } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt index d23ff85ea0..3b20ee61a1 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt @@ -1,10 +1,7 @@ /* - * Module: r2-streamer-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.streamer.parser.image @@ -16,10 +13,10 @@ import org.readium.r2.shared.publication.asset.PublicationAsset import org.readium.r2.shared.publication.services.PerResourcePositionsService import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.streamer.PublicationParser import org.readium.r2.streamer.extensions.guessTitle import org.readium.r2.streamer.extensions.isHiddenOrThumbs import org.readium.r2.streamer.extensions.lowercasedExtension +import org.readium.r2.streamer.parser.PublicationParser /** * Parses an image–based Publication from an unstructured archive format containing bitmap files, @@ -29,16 +26,12 @@ import org.readium.r2.streamer.extensions.lowercasedExtension */ class ImageParser : PublicationParser { - override suspend fun parse( - asset: PublicationAsset, - fetcher: Fetcher, - warnings: WarningLogger? - ): Publication.Builder? { + override suspend fun parse(asset: PublicationAsset, warnings: WarningLogger?): Publication.Builder? { - if (!accepts(asset, fetcher)) + if (!accepts(asset.mediaType, asset.fetcher)) return null - val readingOrder = fetcher.links() + val readingOrder = asset.fetcher.links() .filter { !File(it.href).isHiddenOrThumbs && it.mediaType.isBitmap } .sortedBy(Link::href) .toMutableList() @@ -46,7 +39,7 @@ class ImageParser : PublicationParser { if (readingOrder.isEmpty()) throw Exception("No bitmap found in the publication.") - val title = fetcher.guessTitle() ?: asset.name + val title = asset.fetcher.guessTitle() ?: asset.name // First valid resource is the cover. readingOrder[0] = readingOrder[0].copy(rels = setOf("cover")) @@ -61,15 +54,15 @@ class ImageParser : PublicationParser { return Publication.Builder( manifest = manifest, - fetcher = fetcher, + fetcher = asset.fetcher, servicesBuilder = Publication.ServicesBuilder( positions = PerResourcePositionsService.createFactory(fallbackMediaType = "image/*") ) ) } - private suspend fun accepts(asset: PublicationAsset, fetcher: Fetcher): Boolean { - if (asset.mediaType() == MediaType.CBZ) + private suspend fun accepts(mediaType: MediaType, fetcher: Fetcher): Boolean { + if (mediaType == MediaType.CBZ) return true val allowedExtensions = listOf("acbf", "txt", "xml") diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt index 69121026d4..d38e0de90f 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt @@ -1,23 +1,15 @@ /* - * Module: r2-shared-kotlin - * Developers: Mickaël Menu - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.streamer.parser.pdf import android.content.Context -import java.io.File -import kotlinx.coroutines.runBlocking import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.PdfSupport -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.FileFetcher import org.readium.r2.shared.publication.* -import org.readium.r2.shared.publication.asset.FileAsset import org.readium.r2.shared.publication.asset.PublicationAsset import org.readium.r2.shared.publication.services.InMemoryCacheService import org.readium.r2.shared.publication.services.InMemoryCoverService @@ -25,9 +17,7 @@ import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.pdf.PdfDocumentFactory import org.readium.r2.shared.util.pdf.toLinks -import org.readium.r2.streamer.PublicationParser -import org.readium.r2.streamer.container.PublicationContainer -import org.readium.r2.streamer.parser.PubBox +import org.readium.r2.streamer.parser.PublicationParser /** * Parses a PDF file into a Readium [Publication]. @@ -37,27 +27,24 @@ import org.readium.r2.streamer.parser.PubBox class PdfParser( context: Context, private val pdfFactory: PdfDocumentFactory<*> -) : PublicationParser, org.readium.r2.streamer.parser.PublicationParser { +) : PublicationParser { private val context = context.applicationContext - override suspend fun parse(asset: PublicationAsset, fetcher: Fetcher, warnings: WarningLogger?): Publication.Builder? = - _parse(asset, fetcher, asset.name) - - suspend fun _parse(asset: PublicationAsset, fetcher: Fetcher, fallbackTitle: String): Publication.Builder? { - if (asset.mediaType() != MediaType.PDF) + override suspend fun parse(asset: PublicationAsset, warnings: WarningLogger?): Publication.Builder? { + if (asset.mediaType != MediaType.PDF) return null - val fileHref = fetcher.links().firstOrNull { it.mediaType == MediaType.PDF }?.href + val fileHref = asset.fetcher.links().firstOrNull { it.mediaType == MediaType.PDF }?.href ?: throw Exception("Unable to find PDF file.") - val document = pdfFactory.open(fetcher.get(fileHref), password = null) + val document = pdfFactory.open(asset.fetcher.get(fileHref), password = null) val tableOfContents = document.outline.toLinks(fileHref) val manifest = Manifest( metadata = Metadata( identifier = document.identifier, conformsTo = setOf(Publication.Profile.PDF), - localizedTitle = LocalizedString(document.title?.ifBlank { null } ?: fallbackTitle), + localizedTitle = LocalizedString(document.title?.ifBlank { null } ?: asset.name), authors = listOfNotNull(document.author).map { Contributor(name = it) }, readingProgression = document.readingProgression, numberOfPages = document.pageCount, @@ -72,27 +59,6 @@ class PdfParser( cover = document.cover(context)?.let { InMemoryCoverService.createFactory(it) } ) - return Publication.Builder(manifest, fetcher, servicesBuilder) - } - - override fun parse(fileAtPath: String, fallbackTitle: String): PubBox? = runBlocking { - - val file = File(fileAtPath) - val asset = FileAsset(file) - val baseFetcher = FileFetcher(href = "/${file.name}", file = file) - val builder = try { - _parse(asset, baseFetcher, fallbackTitle) - } catch (e: Exception) { - return@runBlocking null - } ?: return@runBlocking null - - val publication = builder.build() - val container = PublicationContainer( - publication = publication, - path = file.canonicalPath, - mediaType = MediaType.PDF - ) - - PubBox(publication, container) + return Publication.Builder(manifest, asset.fetcher, servicesBuilder) } } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt index f7864ae0dc..e97725c407 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt @@ -1,162 +1,74 @@ /* - * Module: r2-streamer-kotlin - * Developers: Mickaël Menu - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.streamer.parser.readium import android.content.Context -import java.io.File -import java.io.FileNotFoundException -import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.PdfSupport -import org.readium.r2.shared.drm.DRM -import org.readium.r2.shared.fetcher.* import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.FileAsset import org.readium.r2.shared.publication.asset.PublicationAsset import org.readium.r2.shared.publication.services.* -import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.pdf.PdfDocumentFactory -import org.readium.r2.shared.util.use -import org.readium.r2.streamer.PublicationParser -import org.readium.r2.streamer.container.ContainerError -import org.readium.r2.streamer.container.PublicationContainer import org.readium.r2.streamer.extensions.readAsJsonOrNull -import org.readium.r2.streamer.fetcher.LcpDecryptor -import org.readium.r2.streamer.parser.PubBox +import org.readium.r2.streamer.parser.PublicationParser import org.readium.r2.streamer.parser.audio.AudioLocatorService -import org.readium.r2.streamer.toPublicationType /** * Parses any Readium Web Publication package or manifest, e.g. WebPub, Audiobook, DiViNa, LCPDF... */ -@OptIn(PdfSupport::class) class ReadiumWebPubParser( private val context: Context? = null, private val pdfFactory: PdfDocumentFactory<*>?, - private val httpClient: HttpClient, -) : PublicationParser, org.readium.r2.streamer.parser.PublicationParser { +) : PublicationParser { - override suspend fun parse( - asset: PublicationAsset, - fetcher: Fetcher, - warnings: WarningLogger? - ): Publication.Builder? { - val mediaType = asset.mediaType() + override suspend fun parse(asset: PublicationAsset, warnings: WarningLogger?): Publication.Builder? { + val mediaType = asset.mediaType - if (!mediaType.isReadiumWebPubProfile) + if (!mediaType.isReadiumWebPublication) return null - val isPackage = !mediaType.isRwpm - val manifestJson = - if (isPackage) { - fetcher.readAsJsonOrNull("/manifest.json") - } else { - // For a single manifest file, reads the first (and only) file in the fetcher. - fetcher.links().firstOrNull() - ?.let { fetcher.readAsJsonOrNull(it.href) } - } + asset.fetcher.readAsJsonOrNull("/manifest.json") ?: throw Exception("Manifest not found") - val manifest = Manifest.fromJSON(manifestJson, packaged = isPackage) + val manifest = Manifest.fromJSON(manifestJson, packaged = !mediaType.isRwpm) ?: throw Exception("Failed to parse the RWPM Manifest") - @Suppress("NAME_SHADOWING") - var fetcher = fetcher - - // For a manifest, we discard the [fetcher] provided by the Streamer, because it was only - // used to read the manifest file. We use an [HttpFetcher] instead to serve the remote - // resources. - if (!isPackage) { - val baseUrl = manifest.linkWithRel("self")?.let { File(it.href).parent } - fetcher = HttpFetcher(httpClient, baseUrl) - } - // Checks the requirements from the LCPDF specification. // https://readium.org/lcp-specs/notes/lcp-for-pdf.html val readingOrder = manifest.readingOrder - if (asset.mediaType() == MediaType.LCP_PROTECTED_PDF && (readingOrder.isEmpty() || !readingOrder.all { it.mediaType.matches(MediaType.PDF) })) { + if (mediaType == MediaType.LCP_PROTECTED_PDF && + (readingOrder.isEmpty() || !readingOrder.all { it.mediaType.matches(MediaType.PDF) }) + ) { throw Exception("Invalid LCP Protected PDF.") } val servicesBuilder = Publication.ServicesBuilder().apply { cacheServiceFactory = InMemoryCacheService.createFactory(context) - when (asset.mediaType()) { + when (mediaType) { MediaType.LCP_PROTECTED_PDF -> positionsServiceFactory = pdfFactory?.let { LcpdfPositionsService.create(it) } - MediaType.DIVINA_MANIFEST, MediaType.DIVINA -> + MediaType.DIVINA -> positionsServiceFactory = PerResourcePositionsService.createFactory("image/*") - MediaType.READIUM_AUDIOBOOK, MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.LCP_PROTECTED_AUDIOBOOK -> + MediaType.READIUM_AUDIOBOOK, MediaType.LCP_PROTECTED_AUDIOBOOK -> locatorServiceFactory = AudioLocatorService.createFactory() } } - return Publication.Builder(manifest, fetcher, servicesBuilder) - } - - override fun parse(fileAtPath: String, fallbackTitle: String): PubBox? = runBlocking { - - val file = File(fileAtPath) - val asset = FileAsset(file) - val mediaType = asset.mediaType() - var baseFetcher = try { - ArchiveFetcher.fromPath(file.path) ?: FileFetcher(href = "/${file.name}", file = file) - } catch (e: SecurityException) { - return@runBlocking null - } catch (e: FileNotFoundException) { - throw ContainerError.missingFile(fileAtPath) - } - - val drm = if (baseFetcher.isProtectedWithLcp()) DRM(DRM.Brand.lcp) else null - if (drm?.brand == DRM.Brand.lcp) { - baseFetcher = TransformingFetcher(baseFetcher, LcpDecryptor(drm)::transform) - } - - val builder = try { - parse(asset, baseFetcher) - } catch (e: Exception) { - return@runBlocking null - } ?: return@runBlocking null - - val publication = builder.build() - .apply { - @Suppress("DEPRECATION") - type = mediaType.toPublicationType() - } - - val container = PublicationContainer( - publication = publication, - path = file.canonicalPath, - mediaType = mediaType, - drm = drm - ).apply { - if (!mediaType.isRwpm) { - rootFile.rootFilePath = "manifest.json" - } - } - - PubBox(publication, container) + return Publication.Builder(manifest, asset.fetcher, servicesBuilder) } } -private suspend fun Fetcher.isProtectedWithLcp(): Boolean = - get("license.lcpl").use { it.length().isSuccess } - /** Returns whether this media type is of a Readium Web Publication profile. */ -private val MediaType.isReadiumWebPubProfile: Boolean get() = matchesAny( - MediaType.READIUM_WEBPUB, MediaType.READIUM_WEBPUB_MANIFEST, - MediaType.READIUM_AUDIOBOOK, MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.LCP_PROTECTED_AUDIOBOOK, - MediaType.DIVINA, MediaType.DIVINA_MANIFEST, MediaType.LCP_PROTECTED_PDF +private val MediaType.isReadiumWebPublication: Boolean get() = matchesAny( + MediaType.READIUM_WEBPUB, MediaType.DIVINA, MediaType.LCP_PROTECTED_PDF, + MediaType.READIUM_AUDIOBOOK, MediaType.LCP_PROTECTED_AUDIOBOOK, ) diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt index cacdcc0f3f..e9d020777b 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt @@ -10,12 +10,12 @@ package org.readium.r2.streamer import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.asset.PublicationAsset +import org.readium.r2.streamer.parser.PublicationParser internal fun Resource.readBlocking(range: LongRange? = null) = runBlocking { read(range) } -internal fun PublicationParser.parseBlocking(asset: PublicationAsset, fetcher: Fetcher): - Publication.Builder? = runBlocking { parse(asset, fetcher) } +internal fun PublicationParser.parseBlocking(asset: PublicationAsset): + Publication.Builder? = runBlocking { parse(asset) } diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt index 342492ec3e..a7c1b52584 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt @@ -15,52 +15,56 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Test -import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.fetcher.ArchiveFetcher +import org.readium.r2.shared.fetcher.FileFetcher import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.asset.FileAsset -import org.readium.r2.shared.publication.asset.PublicationAsset import org.readium.r2.shared.publication.firstWithRel -import org.readium.r2.shared.util.archive.DefaultArchiveFactory +import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.streamer.parseBlocking class ImageParserTest { private val parser = ImageParser() - private val cbzAsset = assetForResource("futuristic_tales.cbz") - private val cbzFetcher = fetcherForAsset(cbzAsset) - - private val jpgAsset = assetForResource("futuristic_tales.jpg") - private val jpgFetcher = fetcherForAsset(jpgAsset) + private val cbzAsset = runBlocking { + val path = pathForResource("futuristic_tales.cbz") + val file = File(path) + val fetcher = checkNotNull(ArchiveFetcher.fromPath(path)) + FileAsset(file, MediaType.CBZ, fetcher) + } - private fun assetForResource(resource: String): PublicationAsset { + private val jpgAsset = run { + val path = pathForResource("futuristic_tales.jpg") + val file = File(path) + val fetcher = FileFetcher("/image.jpg", file) + FileAsset(file, MediaType.JPEG, fetcher) + } + private fun pathForResource(resource: String): String { val path = ImageParserTest::class.java.getResource(resource)?.path assertNotNull(path) - return FileAsset(File(path!!)) - } - - private fun fetcherForAsset(asset: PublicationAsset): Fetcher = runBlocking { - asset.createFetcher(PublicationAsset.Dependencies(DefaultArchiveFactory()), credentials = null).getOrThrow() + return path!! } @Test fun `CBZ is accepted`() { - assertNotNull(parser.parseBlocking(cbzAsset, cbzFetcher)) + assertNotNull(parser.parseBlocking(cbzAsset)) } @Test fun `JPG is accepted`() { - assertNotNull(parser.parseBlocking(jpgAsset, jpgFetcher)) + assertNotNull(parser.parseBlocking(jpgAsset)) } @Test fun `conformsTo contains the Divina profile`() { - assertEquals(setOf(Publication.Profile.DIVINA), parser.parseBlocking(cbzAsset, cbzFetcher)?.manifest?.metadata?.conformsTo) + val manifest = parser.parseBlocking(cbzAsset)?.manifest + assertEquals(setOf(Publication.Profile.DIVINA), manifest?.metadata?.conformsTo) } @Test fun `readingOrder is sorted alphabetically`() { - val builder = parser.parseBlocking(cbzAsset, cbzFetcher) + val builder = parser.parseBlocking(cbzAsset) assertNotNull(builder) val readingOrder = builder!!.manifest.readingOrder .map { it.href.removePrefix("/Cory Doctorow's Futuristic Tales of the Here and Now") } @@ -70,7 +74,7 @@ class ImageParserTest { @Test fun `the cover is the first item in the readingOrder`() { - val builder = parser.parseBlocking(cbzAsset, cbzFetcher) + val builder = parser.parseBlocking(cbzAsset) assertNotNull(builder) with(builder!!.manifest.readingOrder) { assertEquals( @@ -82,7 +86,7 @@ class ImageParserTest { @Test fun `title is based on archive's root directory when any`() { - val builder = parser.parseBlocking(cbzAsset, cbzFetcher) + val builder = parser.parseBlocking(cbzAsset) assertNotNull(builder) assertEquals("Cory Doctorow's Futuristic Tales of the Here and Now", builder!!.manifest.metadata.title) } diff --git a/test-app/build.gradle.kts b/test-app/build.gradle.kts index 6fb8969723..018fa7d8cd 100644 --- a/test-app/build.gradle.kts +++ b/test-app/build.gradle.kts @@ -102,7 +102,6 @@ dependencies { implementation(libs.kotlinx.coroutines.core) implementation(libs.jsoup) - implementation(libs.bundles.media2) implementation(libs.bundles.media3) // Room database diff --git a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt index 0abdd0406b..6a404cea2d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt @@ -12,6 +12,10 @@ import org.readium.r2.lcp.LcpService import org.readium.r2.navigator.preferences.FontFamily import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.archive.CompositeArchiveFactory +import org.readium.r2.shared.util.archive.DefaultArchiveFactory +import org.readium.r2.shared.util.archive.channel.ChannelZipArchiveFactory +import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.streamer.Streamer /** @@ -36,7 +40,12 @@ class Readium(context: Context) { lcpService.getOrNull()?.contentProtection() ), // Only required if you want to support PDF files using the PDFium adapter. - pdfFactory = PdfiumDocumentFactory(context) + pdfFactory = PdfiumDocumentFactory(context), + // Build a composite archive factory to enable remote zip reading. + archiveFactory = CompositeArchiveFactory( + primaryFactory = DefaultArchiveFactory(), + fallbackFactory = ChannelZipArchiveFactory(httpClient = DefaultHttpClient()) + ) ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt index b9c64e07f6..5777e59e10 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt @@ -23,15 +23,13 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.withContext import org.joda.time.DateTime import org.readium.r2.lcp.LcpService -import org.readium.r2.shared.extensions.mediaType +import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.FileAsset import org.readium.r2.shared.publication.indexOfFirstWithHref import org.readium.r2.shared.publication.services.cover -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.util.* import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.streamer.Streamer import org.readium.r2.testapp.db.BooksDao @@ -48,8 +46,11 @@ class BookRepository( private val booksDao: BooksDao, private val storageDir: File, private val lcpService: Try, - private val streamer: Streamer + private val streamer: Streamer, ) { + private val coverDir: File = + File(storageDir, "covers/") + .apply { if (!exists()) mkdirs() } fun books(): LiveData> = booksDao.getAllBooks() @@ -108,7 +109,8 @@ class BookRepository( private suspend fun insertBookIntoDatabase( href: String, mediaType: MediaType, - publication: Publication + publication: Publication, + cover: String ): Long { val book = Book( creation = DateTime().toDate().time, @@ -117,7 +119,8 @@ class BookRepository( href = href, identifier = publication.metadata.identifier ?: "", type = mediaType.toString(), - progression = "{}" + progression = "{}", + cover = cover ) return booksDao.insertBook(book) } @@ -141,31 +144,48 @@ class BookRepository( class UnableToOpenPublication( val exception: Publication.OpeningException ) : ImportException(cause = exception) + + class UnsupportedProtocol( + private val protocol: String + ) : ImportException() } - suspend fun addBook( + suspend fun addContentBook( contentUri: Uri ): Try = contentUri.copyToTempFile(context, storageDir) .mapFailure { ImportException.IOException } - .map { addBook(it) } + .flatMap { addLocalBook(it) } + + suspend fun addRemoteBook( + url: Url + ): Try { + val bytes = { url.readBytes() } + val mediaType = MediaType.ofBytes(bytes, fileExtension = url.extension) + ?: MediaType.BINARY - suspend fun addBook( + return addBook(url, mediaType) + } + + suspend fun addLocalBook( tempFile: File, coverUrl: String? = null ): Try { - val sourceMediaType = tempFile.mediaType() - val publicationAsset: FileAsset = - if (sourceMediaType != MediaType.LCP_LICENSE_DOCUMENT) - FileAsset(tempFile, sourceMediaType) - else { + val sourceMediaType = MediaType.ofFile(tempFile) + + val (publicationFile, mediaType) = + if (sourceMediaType != MediaType.LCP_LICENSE_DOCUMENT) { + tempFile to sourceMediaType + } else { lcpService - .flatMap { it.acquirePublication(tempFile) } + .flatMap { + it.acquirePublication(tempFile) + } .fold( { - val mediaType = - MediaType.of(fileExtension = File(it.suggestedFilename).extension) - FileAsset(it.localFile, mediaType) + val file = it.localFile + val mediaType = MediaType.of(fileExtension = File(it.suggestedFilename).extension) + file to mediaType }, { tryOrNull { tempFile.delete() } @@ -174,36 +194,58 @@ class BookRepository( ) } - val mediaType = publicationAsset.mediaType() + if (mediaType == null) { + val exception = Publication.OpeningException.UnsupportedFormat( + Exception("Unsupported media type") + ) + return Try.failure(ImportException.UnableToOpenPublication(exception)) + } + val fileName = "${UUID.randomUUID()}.${mediaType.fileExtension}" - val libraryAsset = FileAsset(File(storageDir, fileName), mediaType) + val libraryFile = File(storageDir, fileName) + val libraryUrl = libraryFile.toUrl() try { - publicationAsset.file.moveTo(libraryAsset.file) + publicationFile.moveTo(libraryFile) } catch (e: Exception) { Timber.d(e) - tryOrNull { publicationAsset.file.delete() } + tryOrNull { libraryFile.delete() } return Try.failure(ImportException.IOException) } - streamer.open(libraryAsset, allowUserInteraction = false) + return addBook( + libraryUrl, mediaType, coverUrl + ).onFailure { + tryOrNull { libraryFile.delete() } + } + } + + private suspend fun addBook( + url: Url, + mediaType: MediaType, + coverUrl: String? = null, + ): Try { + streamer.open(url, mediaType, allowUserInteraction = false) .onSuccess { publication -> + val coverBitmap: Bitmap? = coverUrl + ?.let { getBitmapFromURL(it) } + ?: publication.cover() + val coverFile = + tryOrNull { storeCover(coverBitmap) } + ?: return Try.failure(ImportException.IOException) + val id = insertBookIntoDatabase( - libraryAsset.file.path, - libraryAsset.mediaType(), - publication + url.toString(), + mediaType, + publication, + coverFile.path ) - if (id == -1L) + if (id == -1L) { + coverFile.delete() return Try.failure(ImportException.ImportDatabaseFailed) - - val cover: Bitmap? = coverUrl - ?.let { getBitmapFromURL(it) } - ?: publication.cover() - storeCoverImage(cover, id.toString()) - Try.success(Unit) + } } .onFailure { - tryOrNull { libraryAsset.file.delete() } Timber.d(it) return Try.failure(ImportException.UnableToOpenPublication(it)) } @@ -211,20 +253,15 @@ class BookRepository( return Try.success(Unit) } - private suspend fun storeCoverImage(cover: Bitmap?, imageName: String) = + private suspend fun storeCover(cover: Bitmap?): File = withContext(Dispatchers.IO) { - // TODO Figure out where to store these cover images - val coverImageDir = File(storageDir, "covers/") - if (!coverImageDir.exists()) { - coverImageDir.mkdirs() - } - val coverImageFile = File(storageDir, "covers/$imageName.png") - + val coverImageFile = File(coverDir, "${UUID.randomUUID()}.png") val resized = cover?.let { Bitmap.createScaledBitmap(it, 120, 200, true) } val fos = FileOutputStream(coverImageFile) resized?.compress(Bitmap.CompressFormat.PNG, 80, fos) fos.flush() fos.close() + coverImageFile } private suspend fun getBitmapFromURL(src: String): Bitmap? = @@ -243,8 +280,12 @@ class BookRepository( } suspend fun deleteBook(book: Book) { - book.id?.let { deleteBookFromDatabase(it) } - tryOrNull { File(book.href).delete() } - tryOrNull { File(storageDir, "covers/${book.id}.png").delete() } + val id = book.id!! + val url = URL(book.href) + if (url.protocol == "file") { + tryOrLog { File(url.path).delete() } + } + File(book.cover).delete() + deleteBookFromDatabase(id) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt index 651e35405f..d57c6cdc9e 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt @@ -46,10 +46,8 @@ class BookshelfAdapter( fun bind(book: Book) { binding.bookshelfTitleText.text = book.title - val coverImageFile = - File("${binding.root.context?.filesDir?.path}/covers/${book.id}.png") Picasso.get() - .load(coverImageFile) + .load(File(book.cover)) .placeholder(R.drawable.cover) .into(binding.bookshelfCoverImage) binding.root.singleClick { diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt index d40da78c98..2de8664dce 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt @@ -9,7 +9,6 @@ package org.readium.r2.testapp.bookshelf import android.graphics.Rect import android.net.Uri import android.os.Bundle -import android.text.TextUtils import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -23,6 +22,7 @@ import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar +import org.readium.r2.shared.util.Url import org.readium.r2.testapp.R import org.readium.r2.testapp.databinding.FragmentBookshelfBinding import org.readium.r2.testapp.domain.model.Book @@ -102,17 +102,15 @@ class BookshelfFragment : Fragment() { .setPositiveButton(getString(R.string.ok), null) .show() urlDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - if (TextUtils.isEmpty(urlEditText.text)) { + val url = Url(urlEditText.text.toString()) + if (url == null || !URLUtil.isValidUrl(urlEditText.text.toString())) { urlEditText.error = getString(R.string.invalid_url) - } else if (!URLUtil.isValidUrl(urlEditText.text.toString())) { - urlEditText.error = getString(R.string.invalid_url) - } else { - val url = urlEditText.text.toString() - val uri = Uri.parse(url) - binding.bookshelfProgressBar.visibility = View.VISIBLE - bookshelfViewModel.addPublicationFromUri(uri) - urlDialog.dismiss() + return@setOnClickListener } + + binding.bookshelfProgressBar.visibility = View.VISIBLE + bookshelfViewModel.addRemotePublication(url) + urlDialog.dismiss() } } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt index ec97f4a1ed..355228c4ea 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.readium.r2.shared.UserException +import org.readium.r2.shared.util.Url import org.readium.r2.testapp.BuildConfig import org.readium.r2.testapp.R import org.readium.r2.testapp.domain.model.Book @@ -24,6 +25,7 @@ import org.readium.r2.testapp.reader.ReaderActivityContract import org.readium.r2.testapp.reader.ReaderRepository import org.readium.r2.testapp.utils.EventChannel import org.readium.r2.testapp.utils.extensions.copyToTempFile +import timber.log.Timber class BookshelfViewModel(application: Application) : AndroidViewModel(application) { @@ -52,7 +54,7 @@ class BookshelfViewModel(application: Application) : AndroidViewModel(applicatio val file = app.assets.open("Samples/$element").copyToTempFile(app.storageDir) if (file != null) - app.bookRepository.addBook(file) + app.bookRepository.addLocalBook(file) else if (BuildConfig.DEBUG) error("Unable to load sample into the library") } @@ -69,24 +71,44 @@ class BookshelfViewModel(application: Application) : AndroidViewModel(applicatio fun addPublicationFromUri(uri: Uri) = viewModelScope.launch { app.bookRepository - .addBook(uri) - .onFailure { exception -> - val errorMessage = when (exception) { - is BookRepository.ImportException.UnableToOpenPublication -> - exception.exception.getUserMessage(app) - BookRepository.ImportException.ImportDatabaseFailed -> - app.getString(R.string.unable_add_pub_database) - is BookRepository.ImportException.LcpAcquisitionFailed -> - "Error: " + exception.message - BookRepository.ImportException.IOException -> - app.getString(R.string.unexpected_io_exception) - } - channel.send(Event.ImportPublicationError(errorMessage)) - } - .onSuccess { - channel.send(Event.ImportPublicationSuccess) + .addContentBook(uri) + .exceptionOrNull() + .let { sendImportFeedback(it) } + } + + fun addRemotePublication(url: Url) { + viewModelScope.launch { + val exception = + if (!url.protocol.startsWith("http")) { + BookRepository.ImportException.UnsupportedProtocol(url.protocol) + } else { + app.bookRepository + .addRemoteBook(url) + .exceptionOrNull() } + sendImportFeedback(exception) } + } + + private fun sendImportFeedback(exception: BookRepository.ImportException?) { + if (exception == null) { + channel.send(Event.ImportPublicationSuccess) + } else { + val errorMessage = when (exception) { + is BookRepository.ImportException.UnableToOpenPublication -> + exception.exception.getUserMessage(app) + BookRepository.ImportException.ImportDatabaseFailed -> + app.getString(R.string.unable_add_pub_database) + is BookRepository.ImportException.LcpAcquisitionFailed -> + "Error: " + exception.message + BookRepository.ImportException.IOException -> + app.getString(R.string.unexpected_io_exception) + is BookRepository.ImportException.UnsupportedProtocol -> + app.getString(R.string.unsupported_protocol) + } + channel.send(Event.ImportPublicationError(errorMessage)) + } + } fun openPublication( bookId: Long, @@ -98,6 +120,7 @@ class BookshelfViewModel(application: Application) : AndroidViewModel(applicatio if (exception is ReaderRepository.CancellationException) return@launch + Timber.e(exception) val message = when (exception) { is UserException -> exception.getUserMessage(app) else -> exception.message diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt index d231a42f06..c82dc9d813 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt @@ -71,7 +71,7 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) url.downloadTo(dest) }.flatMap { val opdsCover = publication.images.firstOrNull()?.href - app.bookRepository.addBook(dest, opdsCover) + app.bookRepository.addLocalBook(dest, opdsCover) }.onSuccess { detailChannel.send(Event.DetailEvent.ImportPublicationSuccess) }.onFailure { diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt index 309693610d..9223cbc06c 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt @@ -6,13 +6,9 @@ package org.readium.r2.testapp.domain.model -import android.net.Uri -import android.os.Build import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey -import java.net.URI -import java.nio.file.Paths import org.readium.r2.shared.util.mediatype.MediaType @Entity(tableName = Book.TABLE_NAME) @@ -33,35 +29,12 @@ data class Book( @ColumnInfo(name = PROGRESSION) val progression: String? = null, @ColumnInfo(name = TYPE) - val type: String + val type: String, + @ColumnInfo(name = COVER) + val cover: String, ) { - val fileName: String? - get() { - val url = URI(href) - if (!url.scheme.isNullOrEmpty() && url.isAbsolute) { - val uri = Uri.parse(href) - return uri.lastPathSegment - } - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val path = Paths.get(href) - path.fileName.toString() - } else { - val uri = Uri.parse(href) - uri.lastPathSegment - } - } - - val url: URI? - get() { - val url = URI(href) - if (url.isAbsolute && url.scheme.isNullOrEmpty()) { - return null - } - return url - } - - suspend fun mediaType(): MediaType? = MediaType.of(type) + suspend fun mediaType(): MediaType = MediaType.of(type)!! companion object { @@ -74,5 +47,6 @@ data class Book( const val IDENTIFIER = "identifier" const val PROGRESSION = "progression" const val TYPE = "type" + const val COVER = "cover" } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt index 9f6596dd14..fc77b39293 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt @@ -10,7 +10,6 @@ import android.app.Activity import android.app.Application import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences as JetpackPreferences -import java.io.File import org.json.JSONObject import org.readium.adapters.pdfium.navigator.PdfiumEngineProvider import org.readium.r2.navigator.epub.EpubNavigatorFactory @@ -21,10 +20,10 @@ import org.readium.r2.navigator.pdf.PdfNavigatorFactory import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.FileAsset import org.readium.r2.shared.publication.services.isRestricted import org.readium.r2.shared.publication.services.protectionError import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url import org.readium.r2.testapp.Readium import org.readium.r2.testapp.bookshelf.BookRepository import org.readium.r2.testapp.reader.preferences.AndroidTtsPreferencesManagerFactory @@ -75,11 +74,10 @@ class ReaderRepository( val book = bookRepository.get(bookId) ?: throw Exception("Cannot find book in database.") - val file = File(book.href) - require(file.exists()) - val asset = FileAsset(file) - - val publication = readium.streamer.open(asset, allowUserInteraction = true, sender = activity) + val publication = readium.streamer.open( + Url(book.href)!!, book.mediaType(), + allowUserInteraction = true, sender = activity + ) .getOrThrow() // The publication is protected with a DRM and not unlocked. diff --git a/test-app/src/main/res/values/arrays.xml b/test-app/src/main/res/values/arrays.xml index fc15ea0ae4..53fb24feba 100644 --- a/test-app/src/main/res/values/arrays.xml +++ b/test-app/src/main/res/values/arrays.xml @@ -1,8 +1,8 @@ - Select from Device - Enter a URL + Import from device + Add a remote publication diff --git a/test-app/src/main/res/values/strings.xml b/test-app/src/main/res/values/strings.xml index ba9c0e7aa3..db8d60656a 100644 --- a/test-app/src/main/res/values/strings.xml +++ b/test-app/src/main/res/values/strings.xml @@ -170,6 +170,7 @@ End of chapter Unable to add publication due to an unexpected error on your device + Unsupported protocol Publication added to your library Unable to add publication to the database Failed parsing Catalog From 85238fafe2c0b9872b7025ebb971601beedad279 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Thu, 20 Apr 2023 13:34:34 +0200 Subject: [PATCH 04/65] Fail with `HttpFetcher` when the server does not support byte ranges (#349) --- .../org/readium/r2/shared/fetcher/HttpFetcher.kt | 13 +++++++++++++ .../java/org/readium/r2/shared/util/Deprecated.kt | 9 +++++++++ .../main/java/org/readium/r2/shared/util/Try.kt | 14 ++------------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt index 8dce558b5b..c6f28e5d7a 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt @@ -135,6 +135,19 @@ class HttpFetcher( } return client.stream(request) + .fold( + { response -> + if (response.response.statusCode == 206) { + Try.success(response) + } else { + val exception = Exception("Server seems not to support range requests.") + Try.failure(HttpException.wrap(exception)) + } + }, + { exception -> + Try.failure(exception) + } + ) .map { CountingInputStream(it.body) } .mapFailure { Resource.Exception.wrapHttp(it) } .onSuccess { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt index 6f9c2d4fa8..8d8dd13579 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt @@ -12,3 +12,12 @@ import org.readium.r2.shared.publication.asset.FileAsset @Deprecated("Renamed into `FileAsset`", ReplaceWith("FileAsset"), level = DeprecationLevel.ERROR) typealias File = FileAsset + +/** + * Returns the encapsulated result of the given transform function applied to the encapsulated |Throwable] exception + * if this instance represents failure or the original encapsulated value if it is success. + */ +@Suppress("Unused_parameter") +@Deprecated(message = "Use getOrElse instead.", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("getOrElse")) +inline fun Try.recover(transform: (exception: F) -> R): Try = + TODO() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt index 10aa580641..b38243c739 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt @@ -48,7 +48,7 @@ sealed class Try { override val isFailure: Boolean get() = true override fun getOrThrow(): S { throw exception } override fun getOrNull(): S? = null - override fun exceptionOrNull(): F? = exception + override fun exceptionOrNull(): F = exception } /** @@ -75,7 +75,7 @@ sealed class Try { * Returns the result of [onSuccess] for the encapsulated value if this instance represents success or * the result of [onFailure] function for the encapsulated [Throwable] exception if it is failure. */ - inline fun fold(onSuccess: (value: Success) -> R, onFailure: (exception: Throwable) -> R): R = + inline fun fold(onSuccess: (value: Success) -> R, onFailure: (exception: Failure) -> R): R = if (isSuccess) onSuccess(getOrThrow()) else @@ -125,16 +125,6 @@ inline fun Try.flatMap(transform: (value: S) -> Try< else Try.failure(exceptionOrNull()!!) -/** - * Returns the encapsulated result of the given transform function applied to the encapsulated |Throwable] exception - * if this instance represents failure or the original encapsulated value if it is success. - */ -inline fun Try.recover(transform: (exception: F) -> R): Try = - if (isSuccess) - Try.success(getOrThrow()) - else - Try.success(transform(exceptionOrNull()!!)) - /** * Returns the encapsulated result of the given transform function applied to the encapsulated |Throwable] exception * if this instance represents failure or the original encapsulated value if it is success. From 64e5c04f3e7424572819c61f56dc3aed4826c1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mickae=CC=88l=20Menu?= Date: Fri, 19 May 2023 10:34:58 +0200 Subject: [PATCH 05/65] Update documentation copyright year --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 5de1a594b2..fc3ccb7bfe 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,7 +10,7 @@ repo_name: kotlin-toolkit repo_url: https://github.com/readium/kotlin-toolkit # Copyright (shown at the footer) -copyright: 'Copyright © 2022 Readium Foundation' +copyright: 'Copyright © 2023 Readium Foundation' # Material theme theme: From 1919591885720b7ce34c7335ffa92c48a60669f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 7 Jun 2023 13:59:23 +0200 Subject: [PATCH 06/65] Extract the `Media3Adapter` (#354) --- .../readium/r2/navigator/media3/api/Media3Adapter.kt | 12 ++++++++++++ .../r2/navigator/media3/api/MediaNavigator.kt | 12 +++++------- .../navigator/media3/api/TextAwareMediaNavigator.kt | 7 +++++-- .../r2/navigator/media3/audio/AudiobookNavigator.kt | 11 +++++++---- .../media3/syncmedia/GuidedAudioNavigator.kt | 11 +++++++---- .../readium/r2/navigator/media3/tts/TtsNavigator.kt | 8 ++++++-- .../org/readium/r2/testapp/reader/MediaService.kt | 9 +++++---- 7 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/Media3Adapter.kt diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/Media3Adapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/Media3Adapter.kt new file mode 100644 index 0000000000..b5822a9b22 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/Media3Adapter.kt @@ -0,0 +1,12 @@ +package org.readium.r2.navigator.media3.api + +import androidx.media3.common.Player +import org.readium.r2.shared.ExperimentalReadiumApi + +/** + * An object able to pass as a Jetpack media3 [Player]. + */ +@ExperimentalReadiumApi +interface Media3Adapter { + fun asMedia3Player(): Player +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt index c7746d049d..993c90d215 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt @@ -17,8 +17,11 @@ import org.readium.r2.shared.util.Href * A [Navigator] which can play multimedia content. */ @ExperimentalReadiumApi -interface MediaNavigator : Navigator, Closeable { +interface MediaNavigator< + L : MediaNavigator.Location, + P : MediaNavigator.Playback, + R : MediaNavigator.ReadingOrder + > : Navigator, Closeable { /** * Location of the navigator. @@ -115,9 +118,4 @@ interface MediaNavigator : MediaNavigator { +interface TextAwareMediaNavigator< + L : TextAwareMediaNavigator.Location, + P : TextAwareMediaNavigator.Playback, + R : TextAwareMediaNavigator.ReadingOrder + > : MediaNavigator { /** * Location of the navigator. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt index f1022cad16..94f541cd0e 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.StateFlow import org.readium.r2.navigator.extensions.sum import org.readium.r2.navigator.extensions.time import org.readium.r2.navigator.media3.api.AudioNavigator +import org.readium.r2.navigator.media3.api.Media3Adapter import org.readium.r2.navigator.media3.api.MediaNavigator import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.shared.ExperimentalReadiumApi @@ -33,7 +34,10 @@ class AudiobookNavigator, override val readingOrder: ReadingOrder, -) : AudioNavigator, +) : + MediaNavigator, + AudioNavigator, + Media3Adapter, Configurable by audioEngine { companion object { @@ -188,9 +192,8 @@ class AudiobookNavigator Unit): Boolean { val itemIndex = readingOrder.items.indexOfFirst { it.href.string == locator.href } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt index 36a87bdb9f..9563d835d3 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt @@ -10,6 +10,7 @@ import androidx.media3.common.Player import kotlin.time.Duration import kotlinx.coroutines.flow.StateFlow import org.readium.r2.navigator.media3.api.AudioNavigator +import org.readium.r2.navigator.media3.api.Media3Adapter import org.readium.r2.navigator.media3.api.MediaNavigator import org.readium.r2.navigator.media3.api.TextAwareMediaNavigator import org.readium.r2.navigator.media3.audio.AudiobookNavigator @@ -23,8 +24,11 @@ import org.readium.r2.shared.util.Href @ExperimentalReadiumApi class GuidedAudioNavigator>( private val audioNavigator: AudiobookNavigator, -) : AudioNavigator, +) : + MediaNavigator, + AudioNavigator, TextAwareMediaNavigator, + Media3Adapter, Configurable { data class Location( @@ -84,9 +88,8 @@ class GuidedAudioNavigator = audioNavigator.settings diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt index 00f5d5bf27..c060421725 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt @@ -13,6 +13,7 @@ import androidx.media3.common.Player import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.StateFlow +import org.readium.r2.navigator.media3.api.Media3Adapter import org.readium.r2.navigator.media3.api.MediaMetadataProvider import org.readium.r2.navigator.media3.api.MediaNavigator import org.readium.r2.navigator.media3.api.TextAwareMediaNavigator @@ -39,7 +40,10 @@ class TtsNavigator, override val publication: Publication, private val player: TtsPlayer, private val sessionAdapter: TtsSessionAdapter, -) : TextAwareMediaNavigator, +) : + MediaNavigator, + TextAwareMediaNavigator, + Media3Adapter, Configurable by player { companion object { @@ -214,7 +218,7 @@ class TtsNavigator, return player.hasNextUtterance() } - override fun asPlayer(): Player = + override fun asMedia3Player(): Player = sessionAdapter override fun close() { diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt index 089419b9ed..b1a9d0f3ca 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt @@ -18,6 +18,7 @@ import androidx.media3.session.MediaSession import androidx.media3.session.MediaSessionService import kotlinx.coroutines.* import kotlinx.coroutines.flow.* +import org.readium.r2.navigator.media3.api.Media3Adapter import org.readium.r2.navigator.media3.api.MediaNavigator import org.readium.r2.shared.ExperimentalReadiumApi import timber.log.Timber @@ -59,12 +60,12 @@ class MediaService : MediaSessionService() { sessionMutable.value = null } - fun openSession( - navigator: AnyMediaNavigator, + fun openSession( + navigator: N, bookId: Long - ) { + ) where N : AnyMediaNavigator, N : Media3Adapter { val activityIntent = createSessionActivityIntent() - val mediaSession = MediaSession.Builder(applicationContext, navigator.asPlayer()) + val mediaSession = MediaSession.Builder(applicationContext, navigator.asMedia3Player()) .setSessionActivity(activityIntent) .setId(bookId.toString()) .build() From 1a2738c513035737d1a30f5b3f8a13865a24cb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Fri, 9 Jun 2023 12:10:44 +0200 Subject: [PATCH 07/65] HTML content iterator improvements (#356) --- .../r2/navigator/media3/api/MediaNavigator.kt | 1 - .../media3/tts/TtsContentIterator.kt | 12 +-- .../r2/navigator/media3/tts/TtsNavigator.kt | 13 +-- .../r2/navigator/media3/tts/TtsPlayer.kt | 4 +- .../readium/r2/shared/publication/Locator.kt | 12 ++- .../iterators/HtmlResourceContentIterator.kt | 92 +++++++++++++++---- .../iterators/PublicationContentIterator.kt | 23 +++-- .../HtmlResourceContentIteratorTest.kt | 36 +++++++- .../r2/streamer/parser/epub/EpubParser.kt | 2 +- .../r2/testapp/reader/MediaServiceFacade.kt | 7 +- 10 files changed, 146 insertions(+), 56 deletions(-) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt index 993c90d215..4a489354b2 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/MediaNavigator.kt @@ -6,7 +6,6 @@ package org.readium.r2.navigator.media3.api -import androidx.media3.common.Player import kotlinx.coroutines.flow.StateFlow import org.readium.r2.navigator.Navigator import org.readium.r2.shared.ExperimentalReadiumApi diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsContentIterator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsContentIterator.kt index 04e738242b..b7a88a5672 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsContentIterator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsContentIterator.kt @@ -9,7 +9,6 @@ package org.readium.r2.navigator.media3.tts import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.html.cssSelector import org.readium.r2.shared.publication.indexOfFirstWithHref import org.readium.r2.shared.publication.services.content.Content import org.readium.r2.shared.publication.services.content.ContentService @@ -32,7 +31,7 @@ internal class TtsContentIterator( ) { data class Utterance( val resourceIndex: Int, - val cssSelector: String, + val locations: Locator.Locations, val text: String, val textBefore: String?, val textAfter: String?, @@ -186,16 +185,13 @@ internal class TtsContentIterator( val resourceIndex = publication.readingOrder.indexOfFirstWithHref(locator.href) ?: throw IllegalStateException("Content Element cannot be found in readingOrder.") - val cssSelector = locator.locations.cssSelector - ?: throw IllegalStateException("Css selectors are expected in iterator locators.") - return Utterance( - text = text, - language = language, resourceIndex = resourceIndex, + locations = locator.locations, + text = text, textBefore = locator.text.before, textAfter = locator.text.after, - cssSelector = cssSelector, + language = language, ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt index c060421725..e64f57be67 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt @@ -132,7 +132,6 @@ class TtsNavigator, data class Location( override val href: Href, - val cssSelector: String, override val utterance: String, override val range: IntRange?, override val textBefore: String?, @@ -276,14 +275,9 @@ class TtsNavigator, val utteranceHighlight = publication .locatorFromLink(currentLink)!! - .copyWithLocations( - progression = null, - otherLocations = buildMap { - put("cssSelector", position.cssSelector) - } - ).copy( - text = - Locator.Text( + .copy( + locations = position.locations, + text = Locator.Text( highlight = text, before = position.textBefore, after = position.textAfter @@ -295,7 +289,6 @@ class TtsNavigator, return Location( href = Href(currentLink.href), - cssSelector = position.cssSelector, textBefore = position.textBefore, textAfter = position.textAfter, utterance = text, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt index 3cfe0511fd..bea5943d0b 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt @@ -129,7 +129,7 @@ internal class TtsPlayer, data class Position( val resourceIndex: Int, - val cssSelector: String, + val locations: Locator.Locations, val textBefore: String?, val textAfter: String?, ) @@ -542,7 +542,7 @@ internal class TtsPlayer, range = null, position = Utterance.Position( resourceIndex = resourceIndex, - cssSelector = cssSelector, + locations = locations, textAfter = textAfter, textBefore = textBefore ) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt index 9875a5877f..a658b86e32 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt @@ -130,11 +130,13 @@ data class Locator( fun substring(range: IntRange): Text { highlight ?: return this - return copy( - before = (before ?: "") + highlight.substring(0, range.first), - highlight = highlight.substring(range), - after = highlight.substring(range.last) + (after ?: "") - ) + return tryOr(this) { + copy( + before = (before ?: "") + highlight.substring(0, range.first), + highlight = highlight.substring(range), + after = highlight.substring(range.last) + (after ?: "") + ) + } } companion object { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index af8c534f30..7590eadb7c 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -19,9 +19,11 @@ import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.html.cssSelector import org.readium.r2.shared.publication.services.content.Content import org.readium.r2.shared.publication.services.content.Content.* +import org.readium.r2.shared.publication.services.positionsByReadingOrder import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.Language import org.readium.r2.shared.util.mediatype.MediaType @@ -40,20 +42,38 @@ import org.readium.r2.shared.util.use * Locators will contain a `before` context of up to `beforeMaxLength` characters. */ @ExperimentalReadiumApi -class HtmlResourceContentIterator( +class HtmlResourceContentIterator internal constructor( private val resource: Resource, + private val totalProgressionRange: ClosedRange?, private val locator: Locator, private val beforeMaxLength: Int = 50 ) : Content.Iterator { - companion object { - /** - * Creates a new factory for [HtmlResourceContentIterator]. - */ - fun createFactory(): ResourceContentIteratorFactory = { res, locator -> - if (res.link().mediaType.matchesAny(MediaType.HTML, MediaType.XHTML)) - HtmlResourceContentIterator(res, locator) - else null + class Factory : ResourceContentIteratorFactory { + override suspend fun create( + publication: Publication, + readingOrderIndex: Int, + resource: Resource, + locator: Locator + ): Content.Iterator? { + if (!resource.link().mediaType.matchesAny(MediaType.HTML, MediaType.XHTML)) { + return null + } + + val positions = publication.positionsByReadingOrder() + return HtmlResourceContentIterator( + resource, + totalProgressionRange = positions.getOrNull(readingOrderIndex) + ?.firstOrNull()?.locations?.totalProgression + ?.let { start -> + val end = positions.getOrNull(readingOrderIndex + 1) + ?.firstOrNull()?.locations?.totalProgression + ?: 1.0 + + start..end + }, + locator = locator + ) } } @@ -129,7 +149,44 @@ class HtmlResourceContentIterator( beforeMaxLength = beforeMaxLength ) NodeTraversor.traverse(contentParser, document.body()) - return contentParser.result() + val elements = contentParser.result() + val elementCount = elements.elements.size + if (elementCount == 0) { + return elements + } + + return elements.copy( + elements = elements.elements.mapIndexed { index, element -> + val progression = index.toDouble() / elementCount + element.copy( + progression = progression, + totalProgression = totalProgressionRange?.let { + totalProgressionRange.start + progression * (totalProgressionRange.endInclusive - totalProgressionRange.start) + } + ) + } + ) + } + + private fun Content.Element.copy(progression: Double?, totalProgression: Double?): Content.Element { + fun Locator.update(): Locator = + copyWithLocations( + progression = progression, + totalProgression = totalProgression + ) + + return when (this) { + is TextElement -> copy( + locator = locator.update(), + segments = segments.map { + it.copy(locator = it.locator.update()) + } + ) + is AudioElement -> copy(locator = locator.update()) + is VideoElement -> copy(locator = locator.update()) + is ImageElement -> copy(locator = locator.update()) + else -> this + } } /** @@ -295,7 +352,7 @@ class HtmlResourceContentIterator( segmentsAcc[segmentsAcc.size - 1] = segmentsAcc.last().run { copy(text = text.trimEnd()) } elements.add( - Content.TextElement( + TextElement( locator = baseLocator.copy( locations = Locator.Locations( otherLocations = buildMap { @@ -367,12 +424,15 @@ class HtmlResourceContentIterator( } } -private fun Locator.Text.Companion.trimmingText(text: String, before: String?): Locator.Text = - Locator.Text( - before = ((before ?: "") + text.takeWhile { it.isWhitespace() }).takeUnless { it.isBlank() }, - highlight = text.trim(), - after = text.takeLastWhile { it.isWhitespace() }.takeUnless { it.isBlank() } +private fun Locator.Text.Companion.trimmingText(text: String, before: String?): Locator.Text { + val leadingWhitespace = text.takeWhile { it.isWhitespace() } + val trailingWhitespace = text.takeLastWhile { it.isWhitespace() } + return Locator.Text( + before = ((before ?: "") + leadingWhitespace).takeUnless { it.isBlank() }, + highlight = text.substring(leadingWhitespace.length, text.length - trailingWhitespace.length), + after = trailingWhitespace.takeUnless { it.isBlank() } ) +} private val Node.language: String? get() = attr("xml:lang").takeUnless { it.isBlank() } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt index 6127040281..5eed04f3f5 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt @@ -15,14 +15,21 @@ import org.readium.r2.shared.publication.indexOfFirstWithHref import org.readium.r2.shared.publication.services.content.Content import org.readium.r2.shared.util.Either -/** - * Creates a [Content.Iterator] instance for the [Resource], starting from the given [Locator]. - * - * Returns null if the resource media type is not supported. - */ @ExperimentalReadiumApi -typealias ResourceContentIteratorFactory = - suspend (resource: Resource, locator: Locator) -> Content.Iterator? +fun interface ResourceContentIteratorFactory { + + /** + * Creates a [Content.Iterator] instance for the [resource], starting from the given [locator]. + * + * Returns null if the resource media type is not supported. + */ + suspend fun create( + publication: Publication, + readingOrderIndex: Int, + resource: Resource, + locator: Locator + ): Content.Iterator? +} /** * A composite [Content.Iterator] which iterates through a whole [publication] and delegates the @@ -146,7 +153,7 @@ class PublicationContentIterator( return resourceContentIteratorFactories .firstNotNullOfOrNull { factory -> - factory(resource, locator) + factory.create(publication, index, resource, locator) } ?.let { IndexedIterator(index, it) } } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt index 0912130f79..50e3ca6469 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt @@ -51,6 +51,7 @@ class HtmlResourceContentIteratorTest { private val elements: List = listOf( TextElement( locator = locator( + progression = 0.0, selector = "#pgepubid00498 > div.center", before = null, highlight = "171" @@ -59,6 +60,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.0, selector = "#pgepubid00498 > div.center", before = null, highlight = "171" @@ -70,6 +72,7 @@ class HtmlResourceContentIteratorTest { ), TextElement( locator = locator( + progression = 0.2, selector = "#pgepubid00498 > h3", before = "171", highlight = "INTRODUCTORY" @@ -78,6 +81,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.2, selector = "#pgepubid00498 > h3", before = "171", highlight = "INTRODUCTORY" @@ -89,6 +93,7 @@ class HtmlResourceContentIteratorTest { ), TextElement( locator = locator( + progression = 0.4, selector = "#pgepubid00498 > p:nth-child(3)", before = "171INTRODUCTORY", highlight = "The difficulties of classification are very apparent here, and once more it must be noted that illustrative and practical purposes rather than logical ones are served by the arrangement adopted. The modern fanciful story is here placed next to the real folk story instead of after all the groups of folk products. The Hebrew stories at the beginning belong quite as well, perhaps even better, in Section V, while the stories at the end of Section VI shade off into the more modern types of short tales." @@ -97,6 +102,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.4, selector = "#pgepubid00498 > p:nth-child(3)", before = "171INTRODUCTORY", highlight = "The difficulties of classification are very apparent here, and once more it must be noted that illustrative and practical purposes rather than logical ones are served by the arrangement adopted. The modern fanciful story is here placed next to the real folk story instead of after all the groups of folk products. The Hebrew stories at the beginning belong quite as well, perhaps even better, in Section V, while the stories at the end of Section VI shade off into the more modern types of short tales." @@ -108,6 +114,7 @@ class HtmlResourceContentIteratorTest { ), TextElement( locator = locator( + progression = 0.6, selector = "#pgepubid00498 > p:nth-child(4)", before = "ade off into the more modern types of short tales.", highlight = "The child's natural literature. The world has lost certain secrets as the price of an advancing civilization." @@ -116,6 +123,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.6, selector = "#pgepubid00498 > p:nth-child(4)", before = "ade off into the more modern types of short tales.", highlight = "The child's natural literature. The world has lost certain secrets as the price of an advancing civilization." @@ -127,6 +135,7 @@ class HtmlResourceContentIteratorTest { ), TextElement( locator = locator( + progression = 0.8, selector = "#pgepubid00498 > p:nth-child(5)", before = "secrets as the price of an advancing civilization.", highlight = "Without discussing the limits of the culture-epoch theory of human development as a complete guide in education, it is clear that the young child passes through a period when his mind looks out upon the world in a manner analogous to that of the folk as expressed in their literature." @@ -135,6 +144,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.8, selector = "#pgepubid00498 > p:nth-child(5)", before = "secrets as the price of an advancing civilization.", highlight = "Without discussing the limits of the culture-epoch theory of human development as a complete guide in education, it is clear that the young child passes through a period when his mind looks out upon the world in a manner analogous to that of the folk as expressed in their literature." @@ -147,6 +157,7 @@ class HtmlResourceContentIteratorTest { ) private fun locator( + progression: Double? = null, selector: String? = null, before: String? = null, highlight: String? = null, @@ -154,6 +165,7 @@ class HtmlResourceContentIteratorTest { ): Locator = locator.copy( locations = Locator.Locations( + progression = progression, otherLocations = buildMap { selector?.let { put("cssSelector", it) } } @@ -161,8 +173,12 @@ class HtmlResourceContentIteratorTest { text = Locator.Text(before = before, highlight = highlight, after = after) ) - private fun iterator(html: String, startLocator: Locator = locator): HtmlResourceContentIterator = - HtmlResourceContentIterator(StringResource(link, html), startLocator) + private fun iterator( + html: String, + startLocator: Locator = locator, + totalProgressionRange: ClosedRange? = null + ): HtmlResourceContentIterator = + HtmlResourceContentIterator(StringResource(link, html), totalProgressionRange = totalProgressionRange, startLocator) private suspend fun HtmlResourceContentIterator.elements(): List = buildList { @@ -277,6 +293,7 @@ class HtmlResourceContentIteratorTest { assertEquals( TextElement( locator = locator( + progression = 0.5, selector = "html > body > p:nth-child(2)", before = "oin sur la chaussée, aussi loin qu’on pouvait voir", highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée." @@ -285,6 +302,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.5, selector = "html > body > p:nth-child(2)", before = "oin sur la chaussée, aussi loin qu’on pouvait voir", highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée.", @@ -316,6 +334,7 @@ class HtmlResourceContentIteratorTest { assertEquals( TextElement( locator = locator( + progression = 0.5, selector = "html > body > p:nth-child(2)", before = "oin sur la chaussée, aussi loin qu’on pouvait voir", highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée." @@ -324,6 +343,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.5, selector = "html > body > p:nth-child(2)", before = "oin sur la chaussée, aussi loin qu’on pouvait voir", highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée.", @@ -353,6 +373,7 @@ class HtmlResourceContentIteratorTest { listOf( Content.ImageElement( locator = locator( + progression = 0.0, selector = "html > body > img:nth-child(1)" ), embeddedLink = Link(href = "/dir/image.png"), @@ -361,6 +382,7 @@ class HtmlResourceContentIteratorTest { ), Content.ImageElement( locator = locator( + progression = 0.5, selector = "html > body > img:nth-child(2)" ), embeddedLink = Link(href = "/cover.jpg"), @@ -391,6 +413,7 @@ class HtmlResourceContentIteratorTest { listOf( Content.AudioElement( locator = locator( + progression = 0.0, selector = "html > body > audio:nth-child(1)" ), embeddedLink = Link(href = "/dir/audio.mp3"), @@ -398,6 +421,7 @@ class HtmlResourceContentIteratorTest { ), Content.AudioElement( locator = locator( + progression = 0.5, selector = "html > body > audio:nth-child(2)" ), embeddedLink = Link( @@ -433,6 +457,7 @@ class HtmlResourceContentIteratorTest { listOf( Content.VideoElement( locator = locator( + progression = 0.0, selector = "html > body > video:nth-child(1)" ), embeddedLink = Link(href = "/dir/video.mp4"), @@ -440,6 +465,7 @@ class HtmlResourceContentIteratorTest { ), Content.VideoElement( locator = locator( + progression = 0.5, selector = "html > body > video:nth-child(2)" ), embeddedLink = Link( @@ -479,6 +505,7 @@ class HtmlResourceContentIteratorTest { listOf( TextElement( locator = locator( + progression = 0.0, selector = "#c06-li-0001", highlight = "Let's start at the top—the source of ideas." ), @@ -486,6 +513,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 0.0, selector = "#c06-li-0001", highlight = "Let's start at the top—the source of ideas." ), @@ -497,6 +525,7 @@ class HtmlResourceContentIteratorTest { ), TextElement( locator = locator( + progression = 1 / 3.0, selector = "#c06-para-0019", before = " top—the source of ideas.\n ", highlight = "While almost everyone today claims to be Agile, what I've just described is very much a waterfall process." @@ -505,6 +534,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 1 / 3.0, selector = "#c06-para-0019", before = " top—the source of ideas.\n ", highlight = "While almost everyone today claims to be Agile, what I've just described is very much a waterfall process." @@ -517,6 +547,7 @@ class HtmlResourceContentIteratorTest { ), TextElement( locator = locator( + progression = 2 / 3.0, selector = "#c06-para-0019", before = "e just described is very much a waterfall process.\n \n ", highlight = "Trailing text" @@ -525,6 +556,7 @@ class HtmlResourceContentIteratorTest { segments = listOf( Segment( locator = locator( + progression = 2 / 3.0, selector = "#c06-para-0019", before = "e just described is very much a waterfall process.\n ", highlight = "Trailing text" diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt index f7c2d799ac..ff89f822a0 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt @@ -112,7 +112,7 @@ class EpubParser( search = StringSearchService.createDefaultFactory(), content = DefaultContentService.createFactory( listOf( - HtmlResourceContentIterator.createFactory() + HtmlResourceContentIterator.Factory() ) ), ) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaServiceFacade.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaServiceFacade.kt index 53438c135d..2a4e6db5f3 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaServiceFacade.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaServiceFacade.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import org.readium.r2.navigator.media3.api.Media3Adapter import org.readium.r2.shared.ExperimentalReadiumApi /** @@ -38,10 +39,10 @@ class MediaServiceFacade( val session: StateFlow = sessionMutable.asStateFlow() - suspend fun openSession( + suspend fun openSession( bookId: Long, - navigator: AnyMediaNavigator - ) = mutex.withLock { + navigator: N + ) where N : AnyMediaNavigator, N : Media3Adapter = mutex.withLock { if (session.value != null) { throw CancellationException("A session is already running.") } From 5f3c071cb26dd53902b232d6abdcf1839c918724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 14 Jun 2023 15:17:04 +0200 Subject: [PATCH 08/65] Fix regression parsing RWPM (#357) --- .../r2/streamer/parser/readium/ReadiumWebPubParser.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt index e97725c407..c8f851d5f5 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt @@ -29,7 +29,7 @@ class ReadiumWebPubParser( override suspend fun parse(asset: PublicationAsset, warnings: WarningLogger?): Publication.Builder? { val mediaType = asset.mediaType - if (!mediaType.isReadiumWebPublication) + if (!mediaType.isReadiumWebPubProfile) return null val manifestJson = @@ -68,7 +68,8 @@ class ReadiumWebPubParser( } /** Returns whether this media type is of a Readium Web Publication profile. */ -private val MediaType.isReadiumWebPublication: Boolean get() = matchesAny( - MediaType.READIUM_WEBPUB, MediaType.DIVINA, MediaType.LCP_PROTECTED_PDF, - MediaType.READIUM_AUDIOBOOK, MediaType.LCP_PROTECTED_AUDIOBOOK, +private val MediaType.isReadiumWebPubProfile: Boolean get() = matchesAny( + MediaType.READIUM_WEBPUB, MediaType.READIUM_WEBPUB_MANIFEST, + MediaType.READIUM_AUDIOBOOK, MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.LCP_PROTECTED_AUDIOBOOK, + MediaType.DIVINA, MediaType.DIVINA_MANIFEST, MediaType.LCP_PROTECTED_PDF ) From f17ba634900a3b6f9c9a2bbae8a2d74575d4a2fc Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Wed, 5 Jul 2023 11:05:39 +0200 Subject: [PATCH 09/65] Fix regression in `LcpDecryptor` (#362) --- .../src/main/java/org/readium/r2/lcp/LcpDecryptor.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt index bb7a5e7b77..fdcfb8e9d1 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt @@ -175,14 +175,16 @@ internal class LcpDecryptor(val license: LcpLicense?) { val cacheStartIndex = _cache.startIndex ?.takeIf { cacheStart -> val cacheEnd = cacheStart + _cache.data.size - cacheStart <= range.first && cacheEnd <= range.last + 1 + range.first in cacheStart until cacheEnd && cacheEnd <= range.last + 1 } ?: return resource.read(range) - return resource.read(range.first + _cache.data.size..range.last).map { - val bytes = ByteArray(range.last.toInt() - range.first.toInt() + 1) - val offsetInCache = (range.first - cacheStartIndex).toInt() + val bytes = ByteArray(range.last.toInt() - range.first.toInt() + 1) + val offsetInCache = (range.first - cacheStartIndex).toInt() + val fromCacheLength = _cache.data.size - offsetInCache + + return resource.read(range.first + fromCacheLength..range.last).map { _cache.data.copyInto(bytes, 0, offsetInCache) - it.copyInto(bytes, _cache.data.size) + it.copyInto(bytes, fromCacheLength) bytes } } From c55d2860dff2cc43bf166628380bd956284f24e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 5 Jul 2023 13:01:04 +0200 Subject: [PATCH 10/65] Add user guides for TTS and Media Navigators (#358) --- docs/guides/index.md | 8 + docs/guides/media-navigator.md | 212 +++++++++++++++ docs/guides/tts.md | 252 ++++++++---------- .../media3/api/TextAwareMediaNavigator.kt | 4 +- .../media3/syncmedia/GuidedAudioNavigator.kt | 4 +- .../r2/navigator/media3/tts/TtsNavigator.kt | 4 +- .../media3/tts/TtsNavigatorFactory.kt | 11 +- .../media3/tts/android/AndroidTtsEngine.kt | 114 ++++---- .../tts/android/AndroidTtsEngineProvider.kt | 26 +- .../iterators/HtmlResourceContentIterator.kt | 8 +- .../r2/testapp/reader/ReaderRepository.kt | 5 +- .../r2/testapp/reader/VisualReaderFragment.kt | 19 +- .../r2/testapp/reader/tts/TtsViewModel.kt | 25 +- test-app/src/main/res/values/strings.xml | 1 - 14 files changed, 444 insertions(+), 249 deletions(-) create mode 100644 docs/guides/index.md create mode 100644 docs/guides/media-navigator.md diff --git a/docs/guides/index.md b/docs/guides/index.md new file mode 100644 index 0000000000..7b9c1a2526 --- /dev/null +++ b/docs/guides/index.md @@ -0,0 +1,8 @@ +# User guides + +* [Extracting the content of a publication](content.md) +* [Supporting PDF documents](pdf.md) +* [Configuring the Navigator](navigator-preferences.md) +* [Font families in the EPUB navigator](epub-fonts.md) +* [Media Navigator](media-navigator.md) +* [Text-to-speech](tts.md) \ No newline at end of file diff --git a/docs/guides/media-navigator.md b/docs/guides/media-navigator.md new file mode 100644 index 0000000000..e259b5dddd --- /dev/null +++ b/docs/guides/media-navigator.md @@ -0,0 +1,212 @@ +# Media Navigator + +A `MediaNavigator` implementation can play media-based reading orders, such as audiobooks, text-to-speech rendition, and Media overlays. It enables you to reuse your UI, media controls, and logic related to media playback. + +## Controlling the playback + +A media navigator provides the API you need to pause or resume playback. + +```kotlin +navigator.pause() +check(!navigator.playback.value.playWhenReady) + +navigator.play() +check(navigator.playback.value.playWhenReady) +``` + +## Observing the playback changes + +You can observe the changes in the playback with the `navigator.playback` flow property. + +`playWhenReady` indicates whether the media is playing or will start playing once the required conditions are met (e.g. buffering). You will typically use this to change the icon of a play/pause button. + +The `state` property gives more information about the status of the playback: + +* `Ready` when the media is ready to be played if `playWhenReady` is true. +* `Ended` after reaching the end of the reading order items. +* `Buffering` if the navigator cannot play because the buffer is starved. +* `Error` occurs when an error preventing the playback happened. + +By combining the two, you can determine if the media is really playing: `playWhenReady && state == Ready`. + +Finally, you can use the `index` property to know which `navigator.readingOrder` item is set to be played. + +```kotlin +navigator.playback + .onEach { playback -> + playPauseButton.toggle(playback.playWhenReady) + + val playingItem = navigator.readingOrder.items[playback.index] + + if (playback.state is MediaNavigator.State.Error) { + // Alert + } + } + .launchIn(scope) +``` + +`MediaNavigator` implementations may provide additional playback properties. + +## Specializations of `MediaNavigator` + +### Audio Navigator + +The `AudioNavigator` interface is a specialized version of `MediaNavigator` for publications based on pre-recorded audio resources, such as audiobooks. It provides additional time-based APIs and properties. + +```kotlin +audioNavigator.playback + .onEach { playback -> + print("At duration ${playback.offset} in the resource, buffered ${playback.buffered}") + } + .launchIn(scope) + +// Jump to a particular duration offset in the resource item at index 4. +audioNavigator.seek(index = 4, offset = 5.seconds) +``` + +### Text-aware Media Navigator + +`TextAwareMediaNavigator` specializes `MediaNavigator` for media-based resources that are synchronized with text utterances, such as sentences. It offers additional APIs and properties to determine which utterances are playing. This interface is helpful for a text-to-speech or a Media overlays navigator. + +```kotlin +textAwareNavigator.playback + .onEach { playback -> + print("Playing the range ${playback.range} in text ${playback.utterance}") + } + .launchIn(scope) + +// Get additional context by observing the location instead of the playback. +textAwareNavigator.location + .onEach { location -> + // Highlight the portion of text being played. + visualNavigator.applyDecorations( + listOf(Decoration( + locator = location.utteranceLocator, + style = Decoration.Style.Highlight(tint = Color.RED) + )), + "highlight" + ) + } + .launchIn(scope) + +// Skip the current utterance. +if (textAwareNavigator.hasNextUtterance()) { + textAwareNavigator.goToNextUtterance() +} +``` + +## Background playback and media notification + +The Readium Kotlin toolkit provides implementations of `MediaNavigator` powered by Jetpack media3. This allows for continuous playback in the background and displaying Media-style notifications with playback controls. + +To accomplish this, you must create your own `MediaSessionService`. Get acquainted with [the concept behind media3](https://developer.android.com/guide/topics/media/media3) first. + +### Configuration + +Add the following [Jetpack media3](https://developer.android.com/jetpack/androidx/releases/media3) dependencies to your `build.gradle`, after checking for the latest version. + +```groovy +dependencies { + implementation "androidx.media3:media3-common:1.0.2" + implementation "androidx.media3:media3-session:1.0.2" + implementation "androidx.media3:media3-exoplayer:1.0.2" +} +``` + +### Add the `MediaSessionService` + +Create a new implementation of `MediaSessionService` in your application. For an example, take a look at `MediaService` in the Test App. You can access the media3 `Player` from the navigator with `navigator.asMedia3Player()`. + +Don't forget to declare this new service in your `AndroidManifest.xml`. + +```xml + + + + + + ... + + + + + + + + + + + + +``` + +### Customizing the notification metadata + +By default, the navigators will use the publication's metadata to display playback information in the Media-style notification. If you want to customize this, for example by retrieving metadata from your database, you can provide a custom `MediaMetadataFactory` implementation when creating the navigator. + +Here's an example for the `AndroidTtsNavigator`. + +```kotlin +val navigatorFactory = AndroidTtsNavigatorFactory( + application, publication, + metadataProvider = { pub -> + DatabaseMediaMetadataFactory( + context = application, + scope = application, + bookId = bookId, + trackCount = pub.readingOrder.size + ) + } +) + +/** + * Factory of media3 metadata for the local publication with given [bookId]. + */ +class DatabaseMediaMetadataFactory( + private val context: Context, + scope: CoroutineScope, + private val bookId: Int, + private val trackCount: Int +) : MediaMetadataFactory { + + private class Metadata( + val title: String, + val author: String, + val cover: ByteArray + ) + + private val metadata: Deferred = scope.async { + Database.getInstance(context).bookDao().get(bookId)?.let { book -> + Metadata( + title = book.title, + author = book.author, + // Byte arrays will go cross processes and should be kept small + cover = book.cover.scaleToFit(400, 400).toPng() + ) + } + } + + override suspend fun publicationMetadata(): MediaMetadata = + builder()?.build() ?: MediaMetadata.EMPTY + + override suspend fun resourceMetadata(index: Int): MediaMetadata = + builder()?.setTrackNumber(index)?.build() ?: MediaMetadata.EMPTY + + private suspend fun builder(): MediaMetadata.Builder? { + val metadata = metadata.await() ?: return null + + return MediaMetadata.Builder() + .setTitle(metadata.title) + .setTotalTrackCount(trackCount) + .setArtist(metadata.artist) + // We can't yet directly use a `content://` or `file://` URI with `setArtworkUri`. + // See https://github.com/androidx/media/issues/271 + .setArtworkData(metadata.cover, PICTURE_TYPE_FRONT_COVER) } + } +} +``` diff --git a/docs/guides/tts.md b/docs/guides/tts.md index 3b7b80b471..31b7a81928 100644 --- a/docs/guides/tts.md +++ b/docs/guides/tts.md @@ -1,182 +1,161 @@ # Text-to-speech -:warning: The API described in this guide will be changed in the next version of the Kotlin toolkit to support background TTS playback and media notifications. It is recommended that you wait before integrating it in your app. - -Text-to-speech can be used to read aloud a publication using a synthetic voice. The Readium toolkit ships with a TTS implementation based on the native [Android TTS engine](https://developer.android.com/reference/android/speech/tts/TextToSpeech), but it is opened for extension if you want to use a different TTS engine. +Text-to-speech can read aloud a publication using a synthetic voice. The Readium toolkit includes an implementation based on the [Android TTS engine](https://developer.android.com/reference/android/speech/tts/TextToSpeech), but it can be extended to use a different TTS engine. ## Glossary -* **engine** – a TTS engine takes an utterance and transforms it into audio using a synthetic voice -* **rate** - speech speed of a synthetic voice -* **tokenizer** - algorithm splitting the publication text content into individual utterances, usually by sentences * **utterance** - a single piece of text played by a TTS engine, such as a sentence -* **voice** – a synthetic voice is used by a TTS engine to speak a text using rules pertaining to the voice's language and region - -## Reading a publication aloud - -Apps targeting Android 11 that use text-to-speech should declare INTENT_ACTION_TTS_SERVICE in the queries elements of their manifest. - -To read a publication, you need to create an instance of `PublicationSpeechSynthesizer`. It orchestrates the rendition of a publication by iterating through its content, splitting it into individual utterances using a `ContentTokenizer`, then using a `TtsEngine` to read them aloud. Not all publications can be read using TTS, therefore the constructor returns a nullable object. You can also check whether a publication can be played beforehand using `PublicationSpeechSynthesizer.canSpeak(publication)`. +* **tokenizer** - algorithm splitting the publication text content into individual utterances, usually by sentences +* **engine** – a TTS engine takes an utterance and transforms it into audio using a synthetic voice +* **voice** – a synthetic voice is used by a TTS engine to speak a text in a way suitable for the language and region -```kotlin -val synthesizer = PublicationSpeechSynthesizer( - publication = publication, - config = PublicationSpeechSynthesizer.Configuration( - rateMultiplier = 1.25 - ), - listener = object : PublicationSpeechSynthesizer.Listener { ... } -) -``` +## Getting started -Then, begin the playback from a given starting `Locator`. When missing, the playback will start from the beginning of the publication. +:warning: Apps targeting Android 11 that use the native text-to-speech must declare `INTENT_ACTION_TTS_SERVICE` in the queries elements of their manifest. -```kotlin -synthesizer.start() +```xml + + + + + ``` -You should now hear the TTS engine speak the utterances from the beginning. `PublicationSpeechSynthesizer` provides the APIs necessary to control the playback from the app: - -* `stop()` - stops the playback ; requires start to be called again -* `pause()` - interrupts the playback temporarily -* `resume()` - resumes the playback where it was paused -* `pauseOrResume()` - toggles the pause -* `previous()` - skips to the previous utterance -* `next()` - skips to the next utterance - -Look at `TtsControls` in the Test App for an example of a view calling these APIs. - -:warning: Once you are done with the synthesizer, you should call `close()` to release held resources. +The text-to-speech feature is implemented as a standalone `Navigator`, which can render any publication with a [Content Service](content.md), such as an EPUB. This means you don't need an `EpubNavigatorFragment` open to read the publication; you can use the TTS navigator in the background. -## Observing the playback state +To get a new instance of `TtsNavigator`, first create an `AndroidTtsNavigatorFactory` to use the default Android TTS engine. -The `PublicationSpeechSynthesizer` should be the single source of truth to represent the playback state in your user interface. You can observe the `synthesizer.state` property to keep your user interface synchronized with the playback. The possible states are: - -* `Stopped` when idle and waiting for a call to `start()`. -* `Paused(utterance: Utterance)` when interrupted while playing `utterance`. -* `Playing(utterance: Utterance, range: Locator?)` when speaking `utterance`. This state is updated repeatedly while the utterance is spoken, updating the `range` property with the portion of utterance being played (usually the current word). +```kotlin +val factory = AndroidTtsNavigatorFactory(application, publication) + ?: throw Exception("This publication cannot be played with the TTS navigator") -When pairing the `PublicationSpeechSynthesizer` with a `Navigator`, you can use the `utterance.locator` and `range` properties to highlight spoken utterances and turn pages automatically. +val navigator = factory.createNavigator() +navigator.play() +``` -## Configuring the TTS +`TtsNavigator` implements `MediaNavigator`, so you can use all the APIs available for media-based playback. Check out the [dedicated user guide](media-navigator.md) to learn how to control `TtsNavigator` and observe playback notifications. -The `PublicationSpeechSynthesizer` offers some options to configure the TTS engine. Note that the support of each configuration option depends on the TTS engine used. +## Configuring the Android TTS navigator -Update the configuration by setting it directly. The configuration is not applied right away but for the next utterance. +The `AndroidTtsNavigator` implements [`Configurable`](navigator-preferences.md) and provides various settings to customize the text-to-speech experience. ```kotlin -synthesizer.setConfig(synthesizer.config.copy( - defaultLanguage = Language(Locale.FRENCH) +navigator.submitPreferences(AndroidTtsPreferences( + language = Language("fr"), + pitch = 0.8f, + speed = 1.5f )) ``` -To keep your settings user interface up to date when the configuration changes, observe the `PublicationSpeechSynthesizer.config` property. Look at `TtsControls` in the Test App for an example of a TTS settings screen. +A `PreferencesEditor` is available to help you construct your user interface and modify the preferences. -### Default language +```kotlin +val factory = AndroidTtsNavigatorFactory(application, publication) + ?: throw Exception("This publication cannot be played with the TTS navigator") -The language used by the synthesizer is important, as it determines which TTS voices are used and the rules to tokenize the publication text content. +val navigator = factory.createNavigator() -By default, `PublicationSpeechSynthesizer` will use any language explicitly set on a text element (e.g. with `lang="fr"` in HTML) and fall back on the global language declared in the publication manifest. You can override the fallback language with `Configuration.defaultLanguage` which is useful when the publication language is incorrect or missing. +val editor = factory.createPreferencesEditor(preferences) +editor.pitch.increment() +navigator.submitPreferences(editor.preferences) +``` -### Speech rate +### Language preference -The `rateMultiplier` configuration sets the speech speed as a multiplier, 1.0 being the normal speed. The available range depends on the TTS engine and can be queried with `synthesizer.rateMultiplierRange`. +The language set in the preferences determines the default voice used and how the publication text content is tokenized – i.e. split in utterances. -```kotlin -PublicationSpeechSynthesizer.Configuration( - rateMultiplier = multiplier.coerceIn(synthesizer.rateMultiplierRange) -) -``` +By default, the TTS navigator uses any language explicitly set on a text element (e.g. `lang="fr"` in HTML) and, if none is set, it falls back on the language declared in the publication manifest. Providing an explicit language preference is useful when the publication language is incorrect or missing. -### Voice +### Voices preference -The `voice` setting can be used to change the synthetic voice used by the engine. To get the available list, use `synthesizer.availableVoices`. Note that the available voices can change during runtime, observe `availableVoices` to keep your interface up to date. +The Android TTS engine supports multiple voices. To allow users to choose their preferred voice for each language, they are stored as a dictionary `Map` in `AndroidTtsPreferences`. -To restore a user-selected voice, persist the unique voice identifier returned by `voice.id`. +Use the `voices` property of the `AndroidTtsNavigator` instance to get the full list of available voices. -Users do not expect to see all available voices at all time, as they depend on the selected language. You can group the voices by their language and filter them by the selected language using the following snippet. +Users don't expect to see all available voices at once, as they depend on the selected language. To get an `EnumPreference` based on the current `language` preference, you can use the following snippet. ```kotlin -// Supported voices grouped by their language. -val voicesByLanguage: Flow>> = - synthesizer.availableVoices - .map { voices -> voices.groupBy { it.language } } - -// Supported voices for the language selected in the configuration. -val voicesForSelectedLanguage: Flow> = - combine( - synthesizer.config.map { it.defaultLanguage }, - voicesByLanguage, - ) { language, voices -> - language - ?.let { voices[it] } - ?.sortedBy { it.name ?: it.id } - ?: emptyList() +// We remove the region to show all the voices for a given language, no matter the region (e.g. Canada, France). +val currentLanguage = editor.language.effectiveValue?.removeRegion() + +val voice: EnumPreference = editor.voices + .map( + from = { voices -> + currentLanguage?.let { voices[it] } + }, + to = { voice -> + currentLanguage + ?.let { editor.voices.value.orEmpty().update(it, voice) } + ?: editor.voices.value.orEmpty() + } + ) + .withSupportedValues( + navigator.voices + .filter { it.language.removeRegion() == currentLanguage } + .map { it.id } + ) + +fun Map.update(key: K, value: V?): Map = + buildMap { + putAll(this@update) + if (value == null) { + remove(key) + } else { + put(key, value) + } } ``` -## Installing missing voice data +#### Installing missing voice data :point_up: This only applies if you use the default `AndroidTtsEngine`. -Sometimes the device does not have access to all the data required by a selected voice, in which case the user needs to download it manually. You can catch the `TtsEngine.Exception.LanguageSupportIncomplete` error and call `synthesizer.engine.requestInstallMissingVoice()` to start the system voice download activity. +If the device lacks the data necessary for the chosen voice, the user needs to manually download it. To do so, call the `AndroidTtsEngine.requestInstallVoice()` helper when the `AndroidTtsEngine.Error.LanguageMissingData` error occurs. This will launch the system voice download activity. ```kotlin -val synthesizer = PublicationSpeechSynthesizer(context, publication) - -synthesizer.listener = object : PublicationSpeechSynthesizer.Listener { - override fun onUtteranceError( utterance: PublicationSpeechSynthesizer.Utterance, error: PublicationSpeechSynthesizer.Exception) { - handle(error) - } - - override fun onError(error: PublicationSpeechSynthesizer.Exception) { - handle(error) - } - - private fun handle(error: PublicationSpeechSynthesizer.Exception) { - when (error) { - is PublicationSpeechSynthesizer.Exception.Engine -> - when (val err = error.error) { - is TtsEngine.Exception.LanguageSupportIncomplete -> { - synthesizer.engine.requestInstallMissingVoice(context) - } - - else -> { - ... - } - } +navigator.playback + .onEach { playback -> + (playback?.state as? TtsNavigator.State.Error.EngineError<*>) + ?.let { it.error as? AndroidTtsEngine.Error.LanguageMissingData } + ?.let { error -> + Timber.e("Missing data for language ${error.language}") + AndroidTtsEngine.requestInstallVoice(context) } - } } + .launchIn(viewModelScope) ``` -## Synchronizing the TTS with a Navigator +## Synchronizing the TTS navigator with a visual navigator + +`TtsNavigator` is a standalone navigator that can be used to play a publication in the background. However, most apps prefer to display the publication while it is being read aloud. To do this, you can open the publication with a visual navigator (e.g. `EpubNavigatorFragment`) alongside the `TtsNavigator`. Then, synchronize the progression between the two navigators and use the Decorator API to highlight the spoken utterances. -While `PublicationSpeechSynthesizer` is completely independent from `Navigator` and can be used to play a publication in the background, most apps prefer to render the publication while it is being read aloud. The `Locator` core model is used as a means to synchronize the synthesizer with the navigator. +For concrete examples, take a look at `TtsViewModel` in the Test App. ### Starting the TTS from the visible page -`PublicationSpeechSynthesizer.start()` takes a starting `Locator` for parameter. You can use it to begin the playback from the currently visible page in a `VisualNavigator` using `firstVisibleElementLocator()`. +To start the TTS from the currently visible page, you can use the `VisualNavigator.firstVisibleElementLocator()` API to feed the initial locator of the `TtsNavigator`. ```kotlin -val start = (navigator as? VisualNavigator)?.firstVisibleElementLocator() -synthesizer.start(fromLocator = start) +val ttsNavigator = ttsNavigatorFactory.createNavigator( + initialLocator = (navigator as? VisualNavigator)?.firstVisibleElementLocator() +) ``` ### Highlighting the currently spoken utterance -If you want to highlight or underline the current utterance on the page, you can apply a `Decoration` on the utterance locator with a `DecorableNavigator`. +To highlight the current utterance on the page, you can apply a `Decoration` on the utterance locator if the visual navigator implements `DecorableNavigator`. ```kotlin -val navigator: DecorableNavigator +val visualNavigator: DecorableNavigator -synthesizer.state - .map { (it as? State.Playing)?.utterance } +ttsNavigator.location + .map { it.utteranceLocator } .distinctUntilChanged() - .onEach { utterance -> + .onEach { locator -> navigator.applyDecorations(listOf( Decoration( id = "tts-utterance", - locator = utterance.locator, + locator = locator, style = Decoration.Style.Highlight(tint = Color.RED) ) ), group = "tts") @@ -186,47 +165,48 @@ synthesizer.state ### Turning pages automatically -You can use the same technique as described above to automatically synchronize the `Navigator` with the played utterance, using `navigator.go(utterance.locator)`. +To keep the visual navigator in sync with the utterance being played, observe the navigator's current `location` as described above and use `navigator.go(location.utteranceLocator)`. + +However, this won't turn pages in the middle of an utterance, which can be irritating when speaking a lengthy sentence that spans two pages. To tackle this issue, you can use `location.tokenLocator` when available. It is updated constantly while you speak each word of an utterance. + +Jumping to the token locator for every word can significantly reduce performance. To address this, it is recommended to use [`throttleLatest`](https://github.com/Kotlin/kotlinx.coroutines/issues/1107#issuecomment-1083076517). -However, this will not turn pages mid-utterance, which can be annoying when speaking a long sentence spanning two pages. To address this, you can go to the `State.Playing.range` locator instead, which is updated regularly while speaking each word of an utterance. Note that jumping to the `range` locator for every word can severely impact performances. To alleviate this, you can throttle the flow using [`throttleLatest`](https://github.com/Kotlin/kotlinx.coroutines/issues/1107#issuecomment-1083076517). ```kotlin -synthesizer.state - .filterIsInstance() - .map { it.range ?: it.utterance.locator } +ttsNavigator.location .throttleLatest(1.seconds) + .map { it.tokenLocator ?: it.utteranceLocator } + .distinctUntilChanged() .onEach { locator -> navigator.go(locator, animated = false) } .launchIn(scope) ``` -## Using a custom utterance tokenizer +## Advanced customizations + +### Utterance tokenizer -By default, the `PublicationSpeechSynthesizer` will split the publication text into sentences to create the utterances. You can customize this for finer or coarser utterances using a different tokenizer. +By default, the `TtsNavigator` splits the publication text into sentences, but you can supply your own tokenizer to customize how the text is divided. -For example, this will speak the content word-by-word: +For example, this will speak the content word by word: ```kotlin -val synthesizer = PublicationSpeechSynthesizer(context, publication, +val navigatorFactory = TtsNavigatorFactory( + application, publication, tokenizerFactory = { language -> - TextContentTokenizer( - defaultLanguage = language, - unit = TextUnit.Word - ) + DefaultTextContentTokenizer(unit = TextUnit.Word, language = language) } ) ``` -For completely custom tokenizing or to improve the existing tokenizers, you can implement your own `ContentTokenizer`. +### Custom TTS engine -## Using a custom TTS engine - -`PublicationSpeechSynthesizer` can be used with any TTS engine, provided they implement the `TtsEngine` interface. Take a look at `AndroidTtsEngine` for an example implementation. +`TtsNavigator` is compatible with any TTS engine if you provide an adapter implementing the `TtsEngine` interface. For an example, take a look at `AndroidTtsEngine`. ```kotlin -val synthesizer = PublicationSpeechSynthesizer(publication, - engineFactory = { listener -> MyCustomEngine(listener) } +val navigatorFactory = TtsNavigatorFactory( + application, publication, + engineProvider = MyEngineProvider() ) ``` - diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt index d76d3b5d31..b095743d7c 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TextAwareMediaNavigator.kt @@ -108,14 +108,14 @@ interface TextAwareMediaNavigator< * * Does nothing if the current utterance is the first one. */ - fun previousUtterance() + fun goToPreviousUtterance() /** * Jumps to the next utterance. * * Does nothing if the current utterance is the last one. */ - fun nextUtterance() + fun goToNextUtterance() /** * Whether the current utterance has a previous one or is the first one. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt index 9563d835d3..ea66c750f9 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt @@ -102,11 +102,11 @@ class GuidedAudioNavigator, player.go(locator) } - override fun previousUtterance() { + override fun goToPreviousUtterance() { player.previousUtterance() } - override fun nextUtterance() { + override fun goToNextUtterance() { player.nextUtterance() } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt index 48201ee251..8cc477d0b8 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt @@ -40,15 +40,13 @@ class TtsNavigatorFactory, tokenizerFactory: (language: Language?) -> TextTokenizer = defaultTokenizerFactory, metadataProvider: MediaMetadataProvider = defaultMediaMetadataProvider, defaults: AndroidTtsDefaults = AndroidTtsDefaults(), - voiceSelector: (Language?, Set) -> AndroidTtsEngine.Voice? = defaultVoiceSelector, - listener: AndroidTtsEngine.Listener? = null + voiceSelector: (Language?, Set) -> AndroidTtsEngine.Voice? = defaultVoiceSelector ): AndroidTtsNavigatorFactory? { val engineProvider = AndroidTtsEngineProvider( context = application, defaults = defaults, - voiceSelector = voiceSelector, - listener = listener + voiceSelector = voiceSelector ) return createNavigatorFactory( @@ -132,7 +130,6 @@ class TtsNavigatorFactory, ) } - fun createTtsPreferencesEditor( - currentPreferences: P, - ): E = ttsEngineProvider.createPreferencesEditor(publication, currentPreferences) + fun createPreferencesEditor(preferences: P): E = + ttsEngineProvider.createPreferencesEditor(publication, preferences) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt index 244a7e8c08..26747f1500 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt @@ -41,7 +41,6 @@ class AndroidTtsEngine private constructor( engine: TextToSpeech, private val settingsResolver: SettingsResolver, private val voiceSelector: VoiceSelector, - private val listener: Listener?, override val voices: Set, initialPreferences: AndroidTtsPreferences ) : TtsEngine): Voice? } - class Error(code: Int) : TtsEngine.Error { + sealed class Error : TtsEngine.Error { - val kind: Kind = - Kind.getOrDefault(code) + /** Denotes a generic operation failure. */ + object Unknown : Error() + + /** Denotes a failure caused by an invalid request. */ + object InvalidRequest : Error() + + /** Denotes a failure caused by a network connectivity problems. */ + object Network : Error() + + /** Denotes a failure caused by network timeout. */ + object NetworkTimeout : Error() + + /** Denotes a failure caused by an unfinished download of the voice data. */ + object NotInstalledYet : Error() + + /** Denotes a failure related to the output (audio device or a file). */ + object Output : Error() + + /** Denotes a failure of a TTS service. */ + object Service : Error() + + /** Denotes a failure of a TTS engine to synthesize the given input. */ + object Synthesis : Error() + + /** + * Denotes the language data is missing. + * + * You can open the Android settings to install the missing data with: + * AndroidTtsEngine.requestInstallVoice(context) + */ + data class LanguageMissingData(val language: Language) : Error() /** * Android's TTS error code. * See https://developer.android.com/reference/android/speech/tts/TextToSpeech#ERROR */ - enum class Kind(val code: Int) { - /** Denotes a generic operation failure. */ - Unknown(-1), - /** Denotes a failure caused by an invalid request. */ - InvalidRequest(-8), - /** Denotes a failure caused by a network connectivity problems. */ - Network(-6), - /** Denotes a failure caused by network timeout. */ - NetworkTimeout(-7), - /** Denotes a failure caused by an unfinished download of the voice data. */ - NotInstalledYet(-9), - /** Denotes a failure related to the output (audio device or a file). */ - Output(-5), - /** Denotes a failure of a TTS service. */ - Service(-4), - /** Denotes a failure of a TTS engine to synthesize the given input. */ - Synthesis(-3); - - companion object { - - fun getOrDefault(key: Int): Kind = - values() - .firstOrNull { it.code == key } - ?: Unknown - } + companion object { + internal fun fromNativeError(code: Int): Error = + when (code) { + ERROR_INVALID_REQUEST -> InvalidRequest + ERROR_NETWORK -> Network + ERROR_NETWORK_TIMEOUT -> NetworkTimeout + ERROR_NOT_INSTALLED_YET -> NotInstalledYet + ERROR_OUTPUT -> Output + ERROR_SERVICE -> Service + ERROR_SYNTHESIS -> Synthesis + else -> Unknown + } } } @@ -205,13 +218,6 @@ class AndroidTtsEngine private constructor( } } - interface Listener { - - fun onMissingData(language: Language) - - fun onLanguageNotSupported(language: Language) - } - private data class Request( val id: TtsEngine.RequestId, val text: String, @@ -283,8 +289,7 @@ class AndroidTtsEngine private constructor( tryReconnect(request) } is State.EngineAvailable -> { - val result = doSpeak(stateNow.engine, request) - if (result == ERROR) { + if (!doSpeak(stateNow.engine, request)) { cleanEngine(stateNow.engine) tryReconnect(request) } @@ -333,9 +338,9 @@ class AndroidTtsEngine private constructor( private fun doSpeak( engine: TextToSpeech, request: Request - ): Int { - engine.setupVoice(settings.value, request.language, voices) - return engine.speak(request.text, QUEUE_ADD, null, request.id.value) + ): Boolean { + return engine.setupVoice(settings.value, request.id, request.language, voices) + && (engine.speak(request.text, QUEUE_ADD, null, request.id.value) == SUCCESS) } private fun setupListener(engine: TextToSpeech) { @@ -362,7 +367,7 @@ class AndroidTtsEngine private constructor( private fun onReconnectionFailed() { val previousState = state as State.WaitingForService - val error = Error(Error.Kind.Service.code) + val error = Error.Service state = State.Error(error) for (request in previousState.pendingRequests) { @@ -391,16 +396,23 @@ class AndroidTtsEngine private constructor( private fun TextToSpeech.setupVoice( settings: AndroidTtsSettings, + id: TtsEngine.RequestId, utteranceLanguage: Language?, voices: Set - ) { - val language = utteranceLanguage + ): Boolean { + var language = utteranceLanguage .takeUnless { settings.overrideContentLanguage } ?: settings.language + utteranceListener?.onError(id, Error.LanguageMissingData(language)) + return false + when (isLanguageAvailable(language.locale)) { - LANG_MISSING_DATA -> listener?.onMissingData(language) - LANG_NOT_SUPPORTED -> listener?.onLanguageNotSupported(language) + LANG_MISSING_DATA -> { + utteranceListener?.onError(id, Error.LanguageMissingData(language)) + return false + } + LANG_NOT_SUPPORTED -> language = Language(defaultVoice.locale) } val preferredVoiceWithRegion = @@ -422,12 +434,14 @@ class AndroidTtsEngine private constructor( voice ?.let { this.voice = it } ?: run { this.language = language.locale } + + return true } private fun TextToSpeech.voiceForName(name: String) = voices.firstOrNull { it.name == name } - class UtteranceListener( + private class UtteranceListener( private val listener: TtsEngine.Listener? ) : UtteranceProgressListener() { override fun onStart(utteranceId: String) { @@ -457,7 +471,7 @@ class AndroidTtsEngine private constructor( override fun onError(utteranceId: String, errorCode: Int) { listener?.onError( TtsEngine.RequestId(utteranceId), - Error(errorCode) + Error.fromNativeError(errorCode) ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngineProvider.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngineProvider.kt index 6b27277e1a..cc01c650e6 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngineProvider.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngineProvider.kt @@ -20,7 +20,6 @@ import org.readium.r2.shared.publication.Publication class AndroidTtsEngineProvider( private val context: Context, private val defaults: AndroidTtsDefaults = AndroidTtsDefaults(), - private val listener: AndroidTtsEngine.Listener? = null, private val voiceSelector: AndroidTtsEngine.VoiceSelector = AndroidTtsEngine.VoiceSelector { _, _ -> null } ) : TtsEngineProvider { @@ -36,7 +35,6 @@ class AndroidTtsEngineProvider( context, settingsResolver, voiceSelector, - listener, initialPreferences ) } @@ -73,26 +71,24 @@ class AndroidTtsEngineProvider( } override fun mapEngineError(error: AndroidTtsEngine.Error): PlaybackException { - val errorCode = when (error.kind) { - AndroidTtsEngine.Error.Kind.Unknown -> + val errorCode = when (error) { + AndroidTtsEngine.Error.Unknown -> ERROR_CODE_UNSPECIFIED - AndroidTtsEngine.Error.Kind.InvalidRequest -> + AndroidTtsEngine.Error.InvalidRequest -> ERROR_CODE_IO_BAD_HTTP_STATUS - AndroidTtsEngine.Error.Kind.Network -> + AndroidTtsEngine.Error.Network -> ERROR_CODE_IO_NETWORK_CONNECTION_FAILED - AndroidTtsEngine.Error.Kind.NetworkTimeout -> + AndroidTtsEngine.Error.NetworkTimeout -> ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT - AndroidTtsEngine.Error.Kind.NotInstalledYet -> - ERROR_CODE_UNSPECIFIED - AndroidTtsEngine.Error.Kind.Output -> - ERROR_CODE_UNSPECIFIED - AndroidTtsEngine.Error.Kind.Service -> - ERROR_CODE_UNSPECIFIED - AndroidTtsEngine.Error.Kind.Synthesis -> + AndroidTtsEngine.Error.Output, + AndroidTtsEngine.Error.Service, + AndroidTtsEngine.Error.Synthesis, + is AndroidTtsEngine.Error.LanguageMissingData, + AndroidTtsEngine.Error.NotInstalledYet -> ERROR_CODE_UNSPECIFIED } - val message = "Android TTS engine error: ${error.kind.code}" + val message = "Android TTS engine error: ${error.javaClass.simpleName}" return PlaybackException(message, null, errorCode) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index 7590eadb7c..3dd2a118bc 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -319,8 +319,9 @@ class HtmlResourceContentIterator internal constructor( currentLanguage = language } - rawTextAcc += Parser.unescapeEntities(node.wholeText, false) - appendNormalisedText(node) + val text = Parser.unescapeEntities(node.wholeText, false) + rawTextAcc += text + appendNormalisedText(text) } else if (node is Element) { if (node.isBlock) { assert(breadcrumbs.last() == node) @@ -330,8 +331,7 @@ class HtmlResourceContentIterator internal constructor( } } - private fun appendNormalisedText(textNode: TextNode) { - val text = Parser.unescapeEntities(textNode.wholeText, false) + private fun appendNormalisedText(text: String) { StringUtil.appendNormalisedWhitespace(textAcc, text, lastCharIsWhitespace()) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt index fc77b39293..8216a5b201 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt @@ -183,7 +183,10 @@ class ReaderRepository( ): TtsInitData? { val preferencesManager = AndroidTtsPreferencesManagerFactory(preferencesDataStore) .createPreferenceManager(bookId) - val navigatorFactory = TtsNavigatorFactory(application, publication) ?: return null + val navigatorFactory = TtsNavigatorFactory( + application, + publication + ) ?: return null return TtsInitData(mediaServiceFacade, navigatorFactory, preferencesManager) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt index b88905de3c..ab47c3da90 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt @@ -83,13 +83,6 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List */ private var disableTouches by mutableStateOf(false) - /** - * When true, the fragment won't save progression. - * This is useful in the case where the TTS is on and a service is saving progression - * in background. - */ - private var preventProgressionSaving: Boolean = false - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -148,11 +141,7 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { navigator.currentLocator - .onEach { - if (!preventProgressionSaving) { - model.saveProgression(it) - } - } + .onEach { model.saveProgression(it) } .launchIn(this) setupHighlights(this) @@ -231,12 +220,6 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List } .launchIn(scope) } - - showControls - .onEach { showControls -> - preventProgressionSaving = showControls - } - .launchIn(scope) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt index 5d130ab097..34d3db97c7 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt @@ -105,7 +105,7 @@ class TtsViewModel private constructor( bookId = bookId, preferencesManager = preferencesManager ) { preferences -> - val baseEditor = ttsNavigatorFactory.createTtsPreferencesEditor(preferences) + val baseEditor = ttsNavigatorFactory.createPreferencesEditor(preferences) val voices = navigatorNow?.voices.orEmpty() TtsPreferencesEditor(baseEditor, voices) } @@ -148,7 +148,8 @@ class TtsViewModel private constructor( is MediaNavigator.State.Ready -> {} is MediaNavigator.State.Buffering -> {} } - }.launchIn(viewModelScope) + } + .launchIn(viewModelScope) preferencesManager.preferences .onEach { navigatorNow?.submitPreferences(it) } @@ -213,24 +214,26 @@ class TtsViewModel private constructor( } private fun onPlaybackError(error: TtsNavigator.State.Error) { - val exception = when (error) { + val event = when (error) { is TtsNavigator.State.Error.ContentError -> { Timber.e(error.exception) - UserException(R.string.tts_error_other, cause = error.exception) + Event.OnError(UserException(R.string.tts_error_other, cause = error.exception)) } is TtsNavigator.State.Error.EngineError<*> -> { - val kind = (error.error as AndroidTtsEngine.Error).kind - when (kind) { - AndroidTtsEngine.Error.Kind.Network -> - UserException(R.string.tts_error_network) + val engineError = (error.error as AndroidTtsEngine.Error) + when (engineError) { + is AndroidTtsEngine.Error.LanguageMissingData -> + Event.OnMissingVoiceData(engineError.language) + AndroidTtsEngine.Error.Network -> + Event.OnError(UserException(R.string.tts_error_network)) else -> - UserException(R.string.tts_error_other) - }.also { Timber.e(it, "Error type: ${kind.name}") } + Event.OnError(UserException(R.string.tts_error_other)) + }.also { Timber.e("Error type: $error") } } } viewModelScope.launch { - _events.send(Event.OnError(exception)) + _events.send(event) } } } diff --git a/test-app/src/main/res/values/strings.xml b/test-app/src/main/res/values/strings.xml index db8d60656a..692f8e8f39 100644 --- a/test-app/src/main/res/values/strings.xml +++ b/test-app/src/main/res/values/strings.xml @@ -200,7 +200,6 @@ Language Failed to initialize the TTS engine - The language %s is not supported The language %s requires additional data. Do you want to download it? A networking error occurred A TTS error occurred From c8681662d8cc85831cb8806e2729c14f5c487c04 Mon Sep 17 00:00:00 2001 From: riveram Date: Sat, 8 Jul 2023 16:07:16 +0800 Subject: [PATCH 11/65] Support for keyboard events (#351) --- CHANGELOG.md | 3 + docs/migration-guide.md | 30 ++ .../src/main/assets/_scripts/src/dom.js | 39 ++ .../src/main/assets/_scripts/src/gestures.js | 37 +- .../src/main/assets/_scripts/src/index.js | 1 + .../src/main/assets/_scripts/src/keyboard.js | 55 +++ .../assets/readium/scripts/readium-fixed.js | 2 +- .../readium/scripts/readium-reflowable.js | 2 +- .../org/readium/r2/navigator/Navigator.kt | 71 ++-- .../readium/r2/navigator/R2BasicWebView.kt | 37 ++ .../org/readium/r2/navigator/R2WebView.kt | 9 +- .../audiobook/R2AudiobookActivity.kt | 18 +- .../readium/r2/navigator/cbz/R2CbzActivity.kt | 14 + .../navigator/epub/EpubNavigatorFragment.kt | 70 +++- .../r2/navigator/epub/R2EpubActivity.kt | 20 +- .../navigator/image/ImageNavigatorFragment.kt | 55 ++- .../readium/r2/navigator/input/DragEvent.kt | 16 + .../r2/navigator/input/InputListener.kt | 45 +++ .../r2/navigator/input/InputModifier.kt | 8 + .../readium/r2/navigator/input/KeyEvent.kt | 366 ++++++++++++++++++ .../r2/navigator/input/KeyInterceptorView.kt | 43 ++ .../readium/r2/navigator/input/TapEvent.kt | 12 + .../media3/tts/android/AndroidTtsEngine.kt | 4 +- .../r2/navigator/pdf/PdfNavigatorFragment.kt | 66 ++-- .../util/DirectionalNavigationAdapter.kt | 105 +++++ .../r2/navigator/util/EdgeTapNavigation.kt | 85 +--- .../res/layout/fragment_fxllayout_double.xml | 7 +- .../res/layout/fragment_fxllayout_single.xml | 4 + .../res/layout/viewpager_fragment_epub.xml | 1 + .../r2/testapp/reader/VisualReaderFragment.kt | 143 +++---- 30 files changed, 1059 insertions(+), 309 deletions(-) create mode 100644 readium/navigator/src/main/assets/_scripts/src/keyboard.js create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/input/DragEvent.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/input/InputListener.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/input/InputModifier.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyEvent.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyInterceptorView.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/input/TapEvent.kt create mode 100644 readium/navigator/src/main/java/org/readium/r2/navigator/util/DirectionalNavigationAdapter.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a6e2cfba..749b15ebd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file. Take a look * `WebSettings.textZoom` will work with more publications than `--USER__fontSize`, even the ones poorly authored. However the page width is not adjusted when changing the font size to keep the optimal line length. * Scroll mode: jumping between two EPUB resources with a horizontal swipe triggers the `Navigator.Listener.onJumpToLocator()` callback. * This can be used to allow the user to go back to their previous location if they swiped across chapters by mistake. +* Support for keyboard events in the EPUB, PDF and image navigators. See `VisualNavigator.addInputListener()`. #### Streamer @@ -27,6 +28,8 @@ All notable changes to this project will be documented in this file. Take a look * `EpubNavigatorFragment.firstVisibleElementLocator()` now returns the first *block* element that is visible on the screen, even if it starts on previous pages. * This is used to make sure the user will not miss any context when restoring a TTS session in the middle of a resource. +* The `VisualNavigator`'s drag and tap listener events are moved to a new `addInputListener()` API. +* The new `DirectionalNavigationAdapter` component replaces `EdgeTapNavigation`, helping you turn pages with the arrow and space keyboard keys, or taps on the edge of the screen. ### Fixed diff --git a/docs/migration-guide.md b/docs/migration-guide.md index 843716eb76..504a339703 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -38,6 +38,36 @@ the streamer. You can use the overloaded open method taking a `Url` as argument streamer.open(file.toUrl(), ...) ``` +### Tap and drag events + +The `VisualNavigator.Listener`'s `onTap` and `onDrag` events are deprecated. You can now provide multiple implementations of `InputListener`, and the order matters if events are consumed. + +```kotlin +navigator.addInputListener(DirectionalNavigationAdapter()) + +navigator.addInputListener(object : InputListener { + override fun onTap(navigator: VisualNavigator, event: TapEvent): Boolean { + toggleUi() + return true + } +}) +``` + +### Edge tap and keyboard navigation + +Version 3.0.0 ships with a new `DirectionalNavigationAdapter` component replacing `EdgeTapNavigation`. This helper allows users to turn pages with arrow and space keys on their keyboard or by tapping the edge of the screen. + +It's easy to set it up with an implementation of `VisualNavigator`, as it implements `InputListener`. + +```kotlin +navigator.addInputListener(DirectionalNavigationAdapter( + animatedTransition = true +)) +``` + +`DirectionalNavigationAdapter` offers a lot of customization options. Take a look at its API. + + ## 2.3.0 ### `Decoration.extras` diff --git a/readium/navigator/src/main/assets/_scripts/src/dom.js b/readium/navigator/src/main/assets/_scripts/src/dom.js index befcaceda9..89ad87e50e 100644 --- a/readium/navigator/src/main/assets/_scripts/src/dom.js +++ b/readium/navigator/src/main/assets/_scripts/src/dom.js @@ -7,6 +7,45 @@ import { isScrollModeEnabled } from "./utils"; import { getCssSelector } from "css-selector-generator"; +// See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling +export function nearestInteractiveElement(element) { + if (element == null) { + return null; + } + var interactiveTags = [ + "a", + "audio", + "button", + "canvas", + "details", + "input", + "label", + "option", + "select", + "submit", + "textarea", + "video", + ]; + if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) { + return element.outerHTML; + } + + // Checks whether the element is editable by the user. + if ( + element.hasAttribute("contenteditable") && + element.getAttribute("contenteditable").toLowerCase() != "false" + ) { + return element.outerHTML; + } + + // Checks parents recursively because the touch might be for example on an inside a . + if (element.parentElement) { + return nearestInteractiveElement(element.parentElement); + } + + return null; +} + export function findFirstVisibleLocator() { const element = findElement(document.body); return { diff --git a/readium/navigator/src/main/assets/_scripts/src/gestures.js b/readium/navigator/src/main/assets/_scripts/src/gestures.js index a49f837057..9bee231b02 100644 --- a/readium/navigator/src/main/assets/_scripts/src/gestures.js +++ b/readium/navigator/src/main/assets/_scripts/src/gestures.js @@ -5,6 +5,7 @@ */ import { handleDecorationClickEvent } from "./decorator"; +import { nearestInteractiveElement } from "./dom"; window.addEventListener("DOMContentLoaded", function () { document.addEventListener("click", onClick, false); @@ -103,39 +104,3 @@ function bindDragGesture(element) { state = undefined; } } - -// See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling -function nearestInteractiveElement(element) { - var interactiveTags = [ - "a", - "audio", - "button", - "canvas", - "details", - "input", - "label", - "option", - "select", - "submit", - "textarea", - "video", - ]; - if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) { - return element.outerHTML; - } - - // Checks whether the element is editable by the user. - if ( - element.hasAttribute("contenteditable") && - element.getAttribute("contenteditable").toLowerCase() != "false" - ) { - return element.outerHTML; - } - - // Checks parents recursively because the touch might be for example on an inside a . - if (element.parentElement) { - return nearestInteractiveElement(element.parentElement); - } - - return null; -} diff --git a/readium/navigator/src/main/assets/_scripts/src/index.js b/readium/navigator/src/main/assets/_scripts/src/index.js index f39a59214e..630e10229f 100644 --- a/readium/navigator/src/main/assets/_scripts/src/index.js +++ b/readium/navigator/src/main/assets/_scripts/src/index.js @@ -7,6 +7,7 @@ // Base script used by both reflowable and fixed layout resources. import "./gestures"; +import "./keyboard"; import { removeProperty, scrollLeft, diff --git a/readium/navigator/src/main/assets/_scripts/src/keyboard.js b/readium/navigator/src/main/assets/_scripts/src/keyboard.js new file mode 100644 index 0000000000..d021314698 --- /dev/null +++ b/readium/navigator/src/main/assets/_scripts/src/keyboard.js @@ -0,0 +1,55 @@ +// +// Copyright 2023 Readium Foundation. All rights reserved. +// Use of this source code is governed by the BSD-style license +// available in the top-level LICENSE file of the project. +// + +import { nearestInteractiveElement } from "./dom"; + +window.addEventListener("keydown", (event) => { + if (shouldIgnoreEvent(event)) { + return; + } + + preventDefault(event); + sendPressKeyMessage(event, "down"); +}); + +window.addEventListener("keyup", (event) => { + if (shouldIgnoreEvent(event)) { + return; + } + + preventDefault(event); + sendPressKeyMessage(event, "up"); +}); + +function shouldIgnoreEvent(event) { + return ( + event.defaultPrevented || + nearestInteractiveElement(document.activeElement) != null + ); +} + +// We prevent the default behavior for keyboard events, otherwise the web view +// might scroll. +function preventDefault(event) { + event.stopPropagation(); + event.preventDefault(); +} + +function sendPressKeyMessage(event, type) { + if (event.repeat) return; + + let keyEvent = { + type: type, + code: event.code, + characters: String.fromCharCode(event.keyCode), + alt: event.altKey, + control: event.ctrlKey, + shift: event.shiftKey, + meta: event.metaKey, + }; + + Android.onKey(JSON.stringify(keyEvent)); +} diff --git a/readium/navigator/src/main/assets/readium/scripts/readium-fixed.js b/readium/navigator/src/main/assets/readium/scripts/readium-fixed.js index 94bc0e8cc7..33c89e77fa 100644 --- a/readium/navigator/src/main/assets/readium/scripts/readium-fixed.js +++ b/readium/navigator/src/main/assets/readium/scripts/readium-fixed.js @@ -1 +1 @@ -(function(){var __webpack_modules__={3089:function(__unused_webpack_module,exports){"use strict";eval('var __webpack_unused_export__;\n\n/**\n * Implementation of Myers\' online approximate string matching algorithm [1],\n * with additional optimizations suggested by [2].\n *\n * This has O((k/w) * n) complexity where `n` is the length of the text, `k` is\n * the maximum number of errors allowed (always <= the pattern length) and `w`\n * is the word size. Because JS only supports bitwise operations on 32 bit\n * integers, `w` is 32.\n *\n * As far as I am aware, there aren\'t any online algorithms which are\n * significantly better for a wide range of input parameters. The problem can be\n * solved faster using "filter then verify" approaches which first filter out\n * regions of the text that cannot match using a "cheap" check and then verify\n * the remaining potential matches. The verify step requires an algorithm such\n * as this one however.\n *\n * The algorithm\'s approach is essentially to optimize the classic dynamic\n * programming solution to the problem by computing columns of the matrix in\n * word-sized chunks (ie. dealing with 32 chars of the pattern at a time) and\n * avoiding calculating regions of the matrix where the minimum error count is\n * guaranteed to exceed the input threshold.\n *\n * The paper consists of two parts, the first describes the core algorithm for\n * matching patterns <= the size of a word (implemented by `advanceBlock` here).\n * The second uses the core algorithm as part of a larger block-based algorithm\n * to handle longer patterns.\n *\n * [1] G. Myers, “A Fast Bit-Vector Algorithm for Approximate String Matching\n * Based on Dynamic Programming,” vol. 46, no. 3, pp. 395–415, 1999.\n *\n * [2] Šošić, M. (2014). An simd dynamic programming c/c++ library (Doctoral\n * dissertation, Fakultet Elektrotehnike i računarstva, Sveučilište u Zagrebu).\n */\n__webpack_unused_export__ = ({ value: true });\nfunction reverse(s) {\n return s\n .split("")\n .reverse()\n .join("");\n}\n/**\n * Given the ends of approximate matches for `pattern` in `text`, find\n * the start of the matches.\n *\n * @param findEndFn - Function for finding the end of matches in\n * text.\n * @return Matches with the `start` property set.\n */\nfunction findMatchStarts(text, pattern, matches) {\n var patRev = reverse(pattern);\n return matches.map(function (m) {\n // Find start of each match by reversing the pattern and matching segment\n // of text and searching for an approx match with the same number of\n // errors.\n var minStart = Math.max(0, m.end - pattern.length - m.errors);\n var textRev = reverse(text.slice(minStart, m.end));\n // If there are multiple possible start points, choose the one that\n // maximizes the length of the match.\n var start = findMatchEnds(textRev, patRev, m.errors).reduce(function (min, rm) {\n if (m.end - rm.end < min) {\n return m.end - rm.end;\n }\n return min;\n }, m.end);\n return {\n start: start,\n end: m.end,\n errors: m.errors\n };\n });\n}\n/**\n * Return 1 if a number is non-zero or zero otherwise, without using\n * conditional operators.\n *\n * This should get inlined into `advanceBlock` below by the JIT.\n *\n * Adapted from https://stackoverflow.com/a/3912218/434243\n */\nfunction oneIfNotZero(n) {\n return ((n | -n) >> 31) & 1;\n}\n/**\n * Block calculation step of the algorithm.\n *\n * From Fig 8. on p. 408 of [1], additionally optimized to replace conditional\n * checks with bitwise operations as per Section 4.2.3 of [2].\n *\n * @param ctx - The pattern context object\n * @param peq - The `peq` array for the current character (`ctx.peq.get(ch)`)\n * @param b - The block level\n * @param hIn - Horizontal input delta ∈ {1,0,-1}\n * @return Horizontal output delta ∈ {1,0,-1}\n */\nfunction advanceBlock(ctx, peq, b, hIn) {\n var pV = ctx.P[b];\n var mV = ctx.M[b];\n var hInIsNegative = hIn >>> 31; // 1 if hIn < 0 or 0 otherwise.\n var eq = peq[b] | hInIsNegative;\n // Step 1: Compute horizontal deltas.\n var xV = eq | mV;\n var xH = (((eq & pV) + pV) ^ pV) | eq;\n var pH = mV | ~(xH | pV);\n var mH = pV & xH;\n // Step 2: Update score (value of last row of this block).\n var hOut = oneIfNotZero(pH & ctx.lastRowMask[b]) -\n oneIfNotZero(mH & ctx.lastRowMask[b]);\n // Step 3: Update vertical deltas for use when processing next char.\n pH <<= 1;\n mH <<= 1;\n mH |= hInIsNegative;\n pH |= oneIfNotZero(hIn) - hInIsNegative; // set pH[0] if hIn > 0\n pV = mH | ~(xV | pH);\n mV = pH & xV;\n ctx.P[b] = pV;\n ctx.M[b] = mV;\n return hOut;\n}\n/**\n * Find the ends and error counts for matches of `pattern` in `text`.\n *\n * Only the matches with the lowest error count are reported. Other matches\n * with error counts <= maxErrors are discarded.\n *\n * This is the block-based search algorithm from Fig. 9 on p.410 of [1].\n */\nfunction findMatchEnds(text, pattern, maxErrors) {\n if (pattern.length === 0) {\n return [];\n }\n // Clamp error count so we can rely on the `maxErrors` and `pattern.length`\n // rows being in the same block below.\n maxErrors = Math.min(maxErrors, pattern.length);\n var matches = [];\n // Word size.\n var w = 32;\n // Index of maximum block level.\n var bMax = Math.ceil(pattern.length / w) - 1;\n // Context used across block calculations.\n var ctx = {\n P: new Uint32Array(bMax + 1),\n M: new Uint32Array(bMax + 1),\n lastRowMask: new Uint32Array(bMax + 1)\n };\n ctx.lastRowMask.fill(1 << 31);\n ctx.lastRowMask[bMax] = 1 << (pattern.length - 1) % w;\n // Dummy "peq" array for chars in the text which do not occur in the pattern.\n var emptyPeq = new Uint32Array(bMax + 1);\n // Map of UTF-16 character code to bit vector indicating positions in the\n // pattern that equal that character.\n var peq = new Map();\n // Version of `peq` that only stores mappings for small characters. This\n // allows faster lookups when iterating through the text because a simple\n // array lookup can be done instead of a hash table lookup.\n var asciiPeq = [];\n for (var i = 0; i < 256; i++) {\n asciiPeq.push(emptyPeq);\n }\n // Calculate `ctx.peq` - a map of character values to bitmasks indicating\n // positions of that character within the pattern, where each bit represents\n // a position in the pattern.\n for (var c = 0; c < pattern.length; c += 1) {\n var val = pattern.charCodeAt(c);\n if (peq.has(val)) {\n // Duplicate char in pattern.\n continue;\n }\n var charPeq = new Uint32Array(bMax + 1);\n peq.set(val, charPeq);\n if (val < asciiPeq.length) {\n asciiPeq[val] = charPeq;\n }\n for (var b = 0; b <= bMax; b += 1) {\n charPeq[b] = 0;\n // Set all the bits where the pattern matches the current char (ch).\n // For indexes beyond the end of the pattern, always set the bit as if the\n // pattern contained a wildcard char in that position.\n for (var r = 0; r < w; r += 1) {\n var idx = b * w + r;\n if (idx >= pattern.length) {\n continue;\n }\n var match = pattern.charCodeAt(idx) === val;\n if (match) {\n charPeq[b] |= 1 << r;\n }\n }\n }\n }\n // Index of last-active block level in the column.\n var y = Math.max(0, Math.ceil(maxErrors / w) - 1);\n // Initialize maximum error count at bottom of each block.\n var score = new Uint32Array(bMax + 1);\n for (var b = 0; b <= y; b += 1) {\n score[b] = (b + 1) * w;\n }\n score[bMax] = pattern.length;\n // Initialize vertical deltas for each block.\n for (var b = 0; b <= y; b += 1) {\n ctx.P[b] = ~0;\n ctx.M[b] = 0;\n }\n // Process each char of the text, computing the error count for `w` chars of\n // the pattern at a time.\n for (var j = 0; j < text.length; j += 1) {\n // Lookup the bitmask representing the positions of the current char from\n // the text within the pattern.\n var charCode = text.charCodeAt(j);\n var charPeq = void 0;\n if (charCode < asciiPeq.length) {\n // Fast array lookup.\n charPeq = asciiPeq[charCode];\n }\n else {\n // Slower hash table lookup.\n charPeq = peq.get(charCode);\n if (typeof charPeq === "undefined") {\n charPeq = emptyPeq;\n }\n }\n // Calculate error count for blocks that we definitely have to process for\n // this column.\n var carry = 0;\n for (var b = 0; b <= y; b += 1) {\n carry = advanceBlock(ctx, charPeq, b, carry);\n score[b] += carry;\n }\n // Check if we also need to compute an additional block, or if we can reduce\n // the number of blocks processed for the next column.\n if (score[y] - carry <= maxErrors &&\n y < bMax &&\n (charPeq[y + 1] & 1 || carry < 0)) {\n // Error count for bottom block is under threshold, increase the number of\n // blocks processed for this column & next by 1.\n y += 1;\n ctx.P[y] = ~0;\n ctx.M[y] = 0;\n var maxBlockScore = y === bMax ? pattern.length % w : w;\n score[y] =\n score[y - 1] +\n maxBlockScore -\n carry +\n advanceBlock(ctx, charPeq, y, carry);\n }\n else {\n // Error count for bottom block exceeds threshold, reduce the number of\n // blocks processed for the next column.\n while (y > 0 && score[y] >= maxErrors + w) {\n y -= 1;\n }\n }\n // If error count is under threshold, report a match.\n if (y === bMax && score[y] <= maxErrors) {\n if (score[y] < maxErrors) {\n // Discard any earlier, worse matches.\n matches.splice(0, matches.length);\n }\n matches.push({\n start: -1,\n end: j + 1,\n errors: score[y]\n });\n // Because `search` only reports the matches with the lowest error count,\n // we can "ratchet down" the max error threshold whenever a match is\n // encountered and thereby save a small amount of work for the remainder\n // of the text.\n maxErrors = score[y];\n }\n }\n return matches;\n}\n/**\n * Search for matches for `pattern` in `text` allowing up to `maxErrors` errors.\n *\n * Returns the start, and end positions and error counts for each lowest-cost\n * match. Only the "best" matches are returned.\n */\nfunction search(text, pattern, maxErrors) {\n var matches = findMatchEnds(text, pattern, maxErrors);\n return findMatchStarts(text, pattern, matches);\n}\nexports.Z = search;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA4OS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkMsRUFBRSxhQUFhLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLE9BQU87QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2FwcHJveC1zdHJpbmctbWF0Y2gvZGlzdC9pbmRleC5qcz83MjMwIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBNeWVycycgb25saW5lIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBhbGdvcml0aG0gWzFdLFxuICogd2l0aCBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgc3VnZ2VzdGVkIGJ5IFsyXS5cbiAqXG4gKiBUaGlzIGhhcyBPKChrL3cpICogbikgY29tcGxleGl0eSB3aGVyZSBgbmAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCwgYGtgIGlzXG4gKiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIGFsbG93ZWQgKGFsd2F5cyA8PSB0aGUgcGF0dGVybiBsZW5ndGgpIGFuZCBgd2BcbiAqIGlzIHRoZSB3b3JkIHNpemUuIEJlY2F1c2UgSlMgb25seSBzdXBwb3J0cyBiaXR3aXNlIG9wZXJhdGlvbnMgb24gMzIgYml0XG4gKiBpbnRlZ2VycywgYHdgIGlzIDMyLlxuICpcbiAqIEFzIGZhciBhcyBJIGFtIGF3YXJlLCB0aGVyZSBhcmVuJ3QgYW55IG9ubGluZSBhbGdvcml0aG1zIHdoaWNoIGFyZVxuICogc2lnbmlmaWNhbnRseSBiZXR0ZXIgZm9yIGEgd2lkZSByYW5nZSBvZiBpbnB1dCBwYXJhbWV0ZXJzLiBUaGUgcHJvYmxlbSBjYW4gYmVcbiAqIHNvbHZlZCBmYXN0ZXIgdXNpbmcgXCJmaWx0ZXIgdGhlbiB2ZXJpZnlcIiBhcHByb2FjaGVzIHdoaWNoIGZpcnN0IGZpbHRlciBvdXRcbiAqIHJlZ2lvbnMgb2YgdGhlIHRleHQgdGhhdCBjYW5ub3QgbWF0Y2ggdXNpbmcgYSBcImNoZWFwXCIgY2hlY2sgYW5kIHRoZW4gdmVyaWZ5XG4gKiB0aGUgcmVtYWluaW5nIHBvdGVudGlhbCBtYXRjaGVzLiBUaGUgdmVyaWZ5IHN0ZXAgcmVxdWlyZXMgYW4gYWxnb3JpdGhtIHN1Y2hcbiAqIGFzIHRoaXMgb25lIGhvd2V2ZXIuXG4gKlxuICogVGhlIGFsZ29yaXRobSdzIGFwcHJvYWNoIGlzIGVzc2VudGlhbGx5IHRvIG9wdGltaXplIHRoZSBjbGFzc2ljIGR5bmFtaWNcbiAqIHByb2dyYW1taW5nIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGJ5IGNvbXB1dGluZyBjb2x1bW5zIG9mIHRoZSBtYXRyaXggaW5cbiAqIHdvcmQtc2l6ZWQgY2h1bmtzIChpZS4gZGVhbGluZyB3aXRoIDMyIGNoYXJzIG9mIHRoZSBwYXR0ZXJuIGF0IGEgdGltZSkgYW5kXG4gKiBhdm9pZGluZyBjYWxjdWxhdGluZyByZWdpb25zIG9mIHRoZSBtYXRyaXggd2hlcmUgdGhlIG1pbmltdW0gZXJyb3IgY291bnQgaXNcbiAqIGd1YXJhbnRlZWQgdG8gZXhjZWVkIHRoZSBpbnB1dCB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHBhcGVyIGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgdGhlIGZpcnN0IGRlc2NyaWJlcyB0aGUgY29yZSBhbGdvcml0aG0gZm9yXG4gKiBtYXRjaGluZyBwYXR0ZXJucyA8PSB0aGUgc2l6ZSBvZiBhIHdvcmQgKGltcGxlbWVudGVkIGJ5IGBhZHZhbmNlQmxvY2tgIGhlcmUpLlxuICogVGhlIHNlY29uZCB1c2VzIHRoZSBjb3JlIGFsZ29yaXRobSBhcyBwYXJ0IG9mIGEgbGFyZ2VyIGJsb2NrLWJhc2VkIGFsZ29yaXRobVxuICogdG8gaGFuZGxlIGxvbmdlciBwYXR0ZXJucy5cbiAqXG4gKiBbMV0gRy4gTXllcnMsIOKAnEEgRmFzdCBCaXQtVmVjdG9yIEFsZ29yaXRobSBmb3IgQXBwcm94aW1hdGUgU3RyaW5nIE1hdGNoaW5nXG4gKiBCYXNlZCBvbiBEeW5hbWljIFByb2dyYW1taW5nLOKAnSB2b2wuIDQ2LCBuby4gMywgcHAuIDM5NeKAkzQxNSwgMTk5OS5cbiAqXG4gKiBbMl0gxaBvxaFpxIcsIE0uICgyMDE0KS4gQW4gc2ltZCBkeW5hbWljIHByb2dyYW1taW5nIGMvYysrIGxpYnJhcnkgKERvY3RvcmFsXG4gKiBkaXNzZXJ0YXRpb24sIEZha3VsdGV0IEVsZWt0cm90ZWhuaWtlIGkgcmHEjXVuYXJzdHZhLCBTdmV1xI1pbGnFoXRlIHUgWmFncmVidSkuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJldmVyc2Uocykge1xuICAgIHJldHVybiBzXG4gICAgICAgIC5zcGxpdChcIlwiKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5qb2luKFwiXCIpO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgZW5kcyBvZiBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHRleHRgLCBmaW5kXG4gKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMuXG4gKlxuICogQHBhcmFtIGZpbmRFbmRGbiAtIEZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBlbmQgb2YgbWF0Y2hlcyBpblxuICogdGV4dC5cbiAqIEByZXR1cm4gTWF0Y2hlcyB3aXRoIHRoZSBgc3RhcnRgIHByb3BlcnR5IHNldC5cbiAqL1xuZnVuY3Rpb24gZmluZE1hdGNoU3RhcnRzKHRleHQsIHBhdHRlcm4sIG1hdGNoZXMpIHtcbiAgICB2YXIgcGF0UmV2ID0gcmV2ZXJzZShwYXR0ZXJuKTtcbiAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgLy8gRmluZCBzdGFydCBvZiBlYWNoIG1hdGNoIGJ5IHJldmVyc2luZyB0aGUgcGF0dGVybiBhbmQgbWF0Y2hpbmcgc2VnbWVudFxuICAgICAgICAvLyBvZiB0ZXh0IGFuZCBzZWFyY2hpbmcgZm9yIGFuIGFwcHJveCBtYXRjaCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZlxuICAgICAgICAvLyBlcnJvcnMuXG4gICAgICAgIHZhciBtaW5TdGFydCA9IE1hdGgubWF4KDAsIG0uZW5kIC0gcGF0dGVybi5sZW5ndGggLSBtLmVycm9ycyk7XG4gICAgICAgIHZhciB0ZXh0UmV2ID0gcmV2ZXJzZSh0ZXh0LnNsaWNlKG1pblN0YXJ0LCBtLmVuZCkpO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgc3RhcnQgcG9pbnRzLCBjaG9vc2UgdGhlIG9uZSB0aGF0XG4gICAgICAgIC8vIG1heGltaXplcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaC5cbiAgICAgICAgdmFyIHN0YXJ0ID0gZmluZE1hdGNoRW5kcyh0ZXh0UmV2LCBwYXRSZXYsIG0uZXJyb3JzKS5yZWR1Y2UoZnVuY3Rpb24gKG1pbiwgcm0pIHtcbiAgICAgICAgICAgIGlmIChtLmVuZCAtIHJtLmVuZCA8IG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmVuZCAtIHJtLmVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtaW47XG4gICAgICAgIH0sIG0uZW5kKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogbS5lbmQsXG4gICAgICAgICAgICBlcnJvcnM6IG0uZXJyb3JzXG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybiAxIGlmIGEgbnVtYmVyIGlzIG5vbi16ZXJvIG9yIHplcm8gb3RoZXJ3aXNlLCB3aXRob3V0IHVzaW5nXG4gKiBjb25kaXRpb25hbCBvcGVyYXRvcnMuXG4gKlxuICogVGhpcyBzaG91bGQgZ2V0IGlubGluZWQgaW50byBgYWR2YW5jZUJsb2NrYCBiZWxvdyBieSB0aGUgSklULlxuICpcbiAqIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzkxMjIxOC80MzQyNDNcbiAqL1xuZnVuY3Rpb24gb25lSWZOb3RaZXJvKG4pIHtcbiAgICByZXR1cm4gKChuIHwgLW4pID4+IDMxKSAmIDE7XG59XG4vKipcbiAqIEJsb2NrIGNhbGN1bGF0aW9uIHN0ZXAgb2YgdGhlIGFsZ29yaXRobS5cbiAqXG4gKiBGcm9tIEZpZyA4LiBvbiBwLiA0MDggb2YgWzFdLCBhZGRpdGlvbmFsbHkgb3B0aW1pemVkIHRvIHJlcGxhY2UgY29uZGl0aW9uYWxcbiAqIGNoZWNrcyB3aXRoIGJpdHdpc2Ugb3BlcmF0aW9ucyBhcyBwZXIgU2VjdGlvbiA0LjIuMyBvZiBbMl0uXG4gKlxuICogQHBhcmFtIGN0eCAtIFRoZSBwYXR0ZXJuIGNvbnRleHQgb2JqZWN0XG4gKiBAcGFyYW0gcGVxIC0gVGhlIGBwZXFgIGFycmF5IGZvciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgKGBjdHgucGVxLmdldChjaClgKVxuICogQHBhcmFtIGIgLSBUaGUgYmxvY2sgbGV2ZWxcbiAqIEBwYXJhbSBoSW4gLSBIb3Jpem9udGFsIGlucHV0IGRlbHRhIOKIiCB7MSwwLC0xfVxuICogQHJldHVybiBIb3Jpem9udGFsIG91dHB1dCBkZWx0YSDiiIggezEsMCwtMX1cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUJsb2NrKGN0eCwgcGVxLCBiLCBoSW4pIHtcbiAgICB2YXIgcFYgPSBjdHguUFtiXTtcbiAgICB2YXIgbVYgPSBjdHguTVtiXTtcbiAgICB2YXIgaEluSXNOZWdhdGl2ZSA9IGhJbiA+Pj4gMzE7IC8vIDEgaWYgaEluIDwgMCBvciAwIG90aGVyd2lzZS5cbiAgICB2YXIgZXEgPSBwZXFbYl0gfCBoSW5Jc05lZ2F0aXZlO1xuICAgIC8vIFN0ZXAgMTogQ29tcHV0ZSBob3Jpem9udGFsIGRlbHRhcy5cbiAgICB2YXIgeFYgPSBlcSB8IG1WO1xuICAgIHZhciB4SCA9ICgoKGVxICYgcFYpICsgcFYpIF4gcFYpIHwgZXE7XG4gICAgdmFyIHBIID0gbVYgfCB+KHhIIHwgcFYpO1xuICAgIHZhciBtSCA9IHBWICYgeEg7XG4gICAgLy8gU3RlcCAyOiBVcGRhdGUgc2NvcmUgKHZhbHVlIG9mIGxhc3Qgcm93IG9mIHRoaXMgYmxvY2spLlxuICAgIHZhciBoT3V0ID0gb25lSWZOb3RaZXJvKHBIICYgY3R4Lmxhc3RSb3dNYXNrW2JdKSAtXG4gICAgICAgIG9uZUlmTm90WmVybyhtSCAmIGN0eC5sYXN0Um93TWFza1tiXSk7XG4gICAgLy8gU3RlcCAzOiBVcGRhdGUgdmVydGljYWwgZGVsdGFzIGZvciB1c2Ugd2hlbiBwcm9jZXNzaW5nIG5leHQgY2hhci5cbiAgICBwSCA8PD0gMTtcbiAgICBtSCA8PD0gMTtcbiAgICBtSCB8PSBoSW5Jc05lZ2F0aXZlO1xuICAgIHBIIHw9IG9uZUlmTm90WmVybyhoSW4pIC0gaEluSXNOZWdhdGl2ZTsgLy8gc2V0IHBIWzBdIGlmIGhJbiA+IDBcbiAgICBwViA9IG1IIHwgfih4ViB8IHBIKTtcbiAgICBtViA9IHBIICYgeFY7XG4gICAgY3R4LlBbYl0gPSBwVjtcbiAgICBjdHguTVtiXSA9IG1WO1xuICAgIHJldHVybiBoT3V0O1xufVxuLyoqXG4gKiBGaW5kIHRoZSBlbmRzIGFuZCBlcnJvciBjb3VudHMgZm9yIG1hdGNoZXMgb2YgYHBhdHRlcm5gIGluIGB0ZXh0YC5cbiAqXG4gKiBPbmx5IHRoZSBtYXRjaGVzIHdpdGggdGhlIGxvd2VzdCBlcnJvciBjb3VudCBhcmUgcmVwb3J0ZWQuIE90aGVyIG1hdGNoZXNcbiAqIHdpdGggZXJyb3IgY291bnRzIDw9IG1heEVycm9ycyBhcmUgZGlzY2FyZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGJsb2NrLWJhc2VkIHNlYXJjaCBhbGdvcml0aG0gZnJvbSBGaWcuIDkgb24gcC40MTAgb2YgWzFdLlxuICovXG5mdW5jdGlvbiBmaW5kTWF0Y2hFbmRzKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIENsYW1wIGVycm9yIGNvdW50IHNvIHdlIGNhbiByZWx5IG9uIHRoZSBgbWF4RXJyb3JzYCBhbmQgYHBhdHRlcm4ubGVuZ3RoYFxuICAgIC8vIHJvd3MgYmVpbmcgaW4gdGhlIHNhbWUgYmxvY2sgYmVsb3cuXG4gICAgbWF4RXJyb3JzID0gTWF0aC5taW4obWF4RXJyb3JzLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgICAvLyBXb3JkIHNpemUuXG4gICAgdmFyIHcgPSAzMjtcbiAgICAvLyBJbmRleCBvZiBtYXhpbXVtIGJsb2NrIGxldmVsLlxuICAgIHZhciBiTWF4ID0gTWF0aC5jZWlsKHBhdHRlcm4ubGVuZ3RoIC8gdykgLSAxO1xuICAgIC8vIENvbnRleHQgdXNlZCBhY3Jvc3MgYmxvY2sgY2FsY3VsYXRpb25zLlxuICAgIHZhciBjdHggPSB7XG4gICAgICAgIFA6IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIE06IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIGxhc3RSb3dNYXNrOiBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpXG4gICAgfTtcbiAgICBjdHgubGFzdFJvd01hc2suZmlsbCgxIDw8IDMxKTtcbiAgICBjdHgubGFzdFJvd01hc2tbYk1heF0gPSAxIDw8IChwYXR0ZXJuLmxlbmd0aCAtIDEpICUgdztcbiAgICAvLyBEdW1teSBcInBlcVwiIGFycmF5IGZvciBjaGFycyBpbiB0aGUgdGV4dCB3aGljaCBkbyBub3Qgb2NjdXIgaW4gdGhlIHBhdHRlcm4uXG4gICAgdmFyIGVtcHR5UGVxID0gbmV3IFVpbnQzMkFycmF5KGJNYXggKyAxKTtcbiAgICAvLyBNYXAgb2YgVVRGLTE2IGNoYXJhY3RlciBjb2RlIHRvIGJpdCB2ZWN0b3IgaW5kaWNhdGluZyBwb3NpdGlvbnMgaW4gdGhlXG4gICAgLy8gcGF0dGVybiB0aGF0IGVxdWFsIHRoYXQgY2hhcmFjdGVyLlxuICAgIHZhciBwZXEgPSBuZXcgTWFwKCk7XG4gICAgLy8gVmVyc2lvbiBvZiBgcGVxYCB0aGF0IG9ubHkgc3RvcmVzIG1hcHBpbmdzIGZvciBzbWFsbCBjaGFyYWN0ZXJzLiBUaGlzXG4gICAgLy8gYWxsb3dzIGZhc3RlciBsb29rdXBzIHdoZW4gaXRlcmF0aW5nIHRocm91Z2ggdGhlIHRleHQgYmVjYXVzZSBhIHNpbXBsZVxuICAgIC8vIGFycmF5IGxvb2t1cCBjYW4gYmUgZG9uZSBpbnN0ZWFkIG9mIGEgaGFzaCB0YWJsZSBsb29rdXAuXG4gICAgdmFyIGFzY2lpUGVxID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgICBhc2NpaVBlcS5wdXNoKGVtcHR5UGVxKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlIGBjdHgucGVxYCAtIGEgbWFwIG9mIGNoYXJhY3RlciB2YWx1ZXMgdG8gYml0bWFza3MgaW5kaWNhdGluZ1xuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGF0IGNoYXJhY3RlciB3aXRoaW4gdGhlIHBhdHRlcm4sIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHNcbiAgICAvLyBhIHBvc2l0aW9uIGluIHRoZSBwYXR0ZXJuLlxuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgcGF0dGVybi5sZW5ndGg7IGMgKz0gMSkge1xuICAgICAgICB2YXIgdmFsID0gcGF0dGVybi5jaGFyQ29kZUF0KGMpO1xuICAgICAgICBpZiAocGVxLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgY2hhciBpbiBwYXR0ZXJuLlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoYXJQZXEgPSBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpO1xuICAgICAgICBwZXEuc2V0KHZhbCwgY2hhclBlcSk7XG4gICAgICAgIGlmICh2YWwgPCBhc2NpaVBlcS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFzY2lpUGVxW3ZhbF0gPSBjaGFyUGVxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGIgPSAwOyBiIDw9IGJNYXg7IGIgKz0gMSkge1xuICAgICAgICAgICAgY2hhclBlcVtiXSA9IDA7XG4gICAgICAgICAgICAvLyBTZXQgYWxsIHRoZSBiaXRzIHdoZXJlIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGN1cnJlbnQgY2hhciAoY2gpLlxuICAgICAgICAgICAgLy8gRm9yIGluZGV4ZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIGFsd2F5cyBzZXQgdGhlIGJpdCBhcyBpZiB0aGVcbiAgICAgICAgICAgIC8vIHBhdHRlcm4gY29udGFpbmVkIGEgd2lsZGNhcmQgY2hhciBpbiB0aGF0IHBvc2l0aW9uLlxuICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCB3OyByICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gYiAqIHcgKyByO1xuICAgICAgICAgICAgICAgIGlmIChpZHggPj0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IHBhdHRlcm4uY2hhckNvZGVBdChpZHgpID09PSB2YWw7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJQZXFbYl0gfD0gMSA8PCByO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJbmRleCBvZiBsYXN0LWFjdGl2ZSBibG9jayBsZXZlbCBpbiB0aGUgY29sdW1uLlxuICAgIHZhciB5ID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKG1heEVycm9ycyAvIHcpIC0gMSk7XG4gICAgLy8gSW5pdGlhbGl6ZSBtYXhpbXVtIGVycm9yIGNvdW50IGF0IGJvdHRvbSBvZiBlYWNoIGJsb2NrLlxuICAgIHZhciBzY29yZSA9IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSk7XG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIHNjb3JlW2JdID0gKGIgKyAxKSAqIHc7XG4gICAgfVxuICAgIHNjb3JlW2JNYXhdID0gcGF0dGVybi5sZW5ndGg7XG4gICAgLy8gSW5pdGlhbGl6ZSB2ZXJ0aWNhbCBkZWx0YXMgZm9yIGVhY2ggYmxvY2suXG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIGN0eC5QW2JdID0gfjA7XG4gICAgICAgIGN0eC5NW2JdID0gMDtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBlYWNoIGNoYXIgb2YgdGhlIHRleHQsIGNvbXB1dGluZyB0aGUgZXJyb3IgY291bnQgZm9yIGB3YCBjaGFycyBvZlxuICAgIC8vIHRoZSBwYXR0ZXJuIGF0IGEgdGltZS5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRleHQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBiaXRtYXNrIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb25zIG9mIHRoZSBjdXJyZW50IGNoYXIgZnJvbVxuICAgICAgICAvLyB0aGUgdGV4dCB3aXRoaW4gdGhlIHBhdHRlcm4uXG4gICAgICAgIHZhciBjaGFyQ29kZSA9IHRleHQuY2hhckNvZGVBdChqKTtcbiAgICAgICAgdmFyIGNoYXJQZXEgPSB2b2lkIDA7XG4gICAgICAgIGlmIChjaGFyQ29kZSA8IGFzY2lpUGVxLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gRmFzdCBhcnJheSBsb29rdXAuXG4gICAgICAgICAgICBjaGFyUGVxID0gYXNjaWlQZXFbY2hhckNvZGVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU2xvd2VyIGhhc2ggdGFibGUgbG9va3VwLlxuICAgICAgICAgICAgY2hhclBlcSA9IHBlcS5nZXQoY2hhckNvZGUpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyUGVxID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgY2hhclBlcSA9IGVtcHR5UGVxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3VudCBmb3IgYmxvY2tzIHRoYXQgd2UgZGVmaW5pdGVseSBoYXZlIHRvIHByb2Nlc3MgZm9yXG4gICAgICAgIC8vIHRoaXMgY29sdW1uLlxuICAgICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBiID0gMDsgYiA8PSB5OyBiICs9IDEpIHtcbiAgICAgICAgICAgIGNhcnJ5ID0gYWR2YW5jZUJsb2NrKGN0eCwgY2hhclBlcSwgYiwgY2FycnkpO1xuICAgICAgICAgICAgc2NvcmVbYl0gKz0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgYWxzbyBuZWVkIHRvIGNvbXB1dGUgYW4gYWRkaXRpb25hbCBibG9jaywgb3IgaWYgd2UgY2FuIHJlZHVjZVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGJsb2NrcyBwcm9jZXNzZWQgZm9yIHRoZSBuZXh0IGNvbHVtbi5cbiAgICAgICAgaWYgKHNjb3JlW3ldIC0gY2FycnkgPD0gbWF4RXJyb3JzICYmXG4gICAgICAgICAgICB5IDwgYk1heCAmJlxuICAgICAgICAgICAgKGNoYXJQZXFbeSArIDFdICYgMSB8fCBjYXJyeSA8IDApKSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGlzIHVuZGVyIHRocmVzaG9sZCwgaW5jcmVhc2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhpcyBjb2x1bW4gJiBuZXh0IGJ5IDEuXG4gICAgICAgICAgICB5ICs9IDE7XG4gICAgICAgICAgICBjdHguUFt5XSA9IH4wO1xuICAgICAgICAgICAgY3R4Lk1beV0gPSAwO1xuICAgICAgICAgICAgdmFyIG1heEJsb2NrU2NvcmUgPSB5ID09PSBiTWF4ID8gcGF0dGVybi5sZW5ndGggJSB3IDogdztcbiAgICAgICAgICAgIHNjb3JlW3ldID1cbiAgICAgICAgICAgICAgICBzY29yZVt5IC0gMV0gK1xuICAgICAgICAgICAgICAgICAgICBtYXhCbG9ja1Njb3JlIC1cbiAgICAgICAgICAgICAgICAgICAgY2FycnkgK1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlQmxvY2soY3R4LCBjaGFyUGVxLCB5LCBjYXJyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGV4Y2VlZHMgdGhyZXNob2xkLCByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhlIG5leHQgY29sdW1uLlxuICAgICAgICAgICAgd2hpbGUgKHkgPiAwICYmIHNjb3JlW3ldID49IG1heEVycm9ycyArIHcpIHtcbiAgICAgICAgICAgICAgICB5IC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZXJyb3IgY291bnQgaXMgdW5kZXIgdGhyZXNob2xkLCByZXBvcnQgYSBtYXRjaC5cbiAgICAgICAgaWYgKHkgPT09IGJNYXggJiYgc2NvcmVbeV0gPD0gbWF4RXJyb3JzKSB7XG4gICAgICAgICAgICBpZiAoc2NvcmVbeV0gPCBtYXhFcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIGFueSBlYXJsaWVyLCB3b3JzZSBtYXRjaGVzLlxuICAgICAgICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKDAsIG1hdGNoZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICAgICAgICAgIGVuZDogaiArIDEsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBzY29yZVt5XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBCZWNhdXNlIGBzZWFyY2hgIG9ubHkgcmVwb3J0cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBsb3dlc3QgZXJyb3IgY291bnQsXG4gICAgICAgICAgICAvLyB3ZSBjYW4gXCJyYXRjaGV0IGRvd25cIiB0aGUgbWF4IGVycm9yIHRocmVzaG9sZCB3aGVuZXZlciBhIG1hdGNoIGlzXG4gICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbmQgdGhlcmVieSBzYXZlIGEgc21hbGwgYW1vdW50IG9mIHdvcmsgZm9yIHRoZSByZW1haW5kZXJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB0ZXh0LlxuICAgICAgICAgICAgbWF4RXJyb3JzID0gc2NvcmVbeV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59XG4vKipcbiAqIFNlYXJjaCBmb3IgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogUmV0dXJucyB0aGUgc3RhcnQsIGFuZCBlbmQgcG9zaXRpb25zIGFuZCBlcnJvciBjb3VudHMgZm9yIGVhY2ggbG93ZXN0LWNvc3RcbiAqIG1hdGNoLiBPbmx5IHRoZSBcImJlc3RcIiBtYXRjaGVzIGFyZSByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoRW5kcyh0ZXh0LCBwYXR0ZXJuLCBtYXhFcnJvcnMpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hTdGFydHModGV4dCwgcGF0dGVybiwgbWF0Y2hlcyk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzZWFyY2g7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3089\n')},6396:function(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__){"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/approx-string-match/dist/index.js\nvar dist = __webpack_require__(3089);\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/match-quote.js\n\n/**\n * @typedef {import(\'approx-string-match\').Match} StringMatch\n */\n\n/**\n * @typedef Match\n * @prop {number} start - Start offset of match in text\n * @prop {number} end - End offset of match in text\n * @prop {number} score -\n * Score for the match between 0 and 1.0, where 1.0 indicates a perfect match\n * for the quote and context.\n */\n\n/**\n * Find the best approximate matches for `str` in `text` allowing up to `maxErrors` errors.\n *\n * @param {string} text\n * @param {string} str\n * @param {number} maxErrors\n * @return {StringMatch[]}\n */\n\nfunction search(text, str, maxErrors) {\n // Do a fast search for exact matches. The `approx-string-match` library\n // doesn\'t currently incorporate this optimization itself.\n var matchPos = 0;\n var exactMatches = [];\n\n while (matchPos !== -1) {\n matchPos = text.indexOf(str, matchPos);\n\n if (matchPos !== -1) {\n exactMatches.push({\n start: matchPos,\n end: matchPos + str.length,\n errors: 0\n });\n matchPos += 1;\n }\n }\n\n if (exactMatches.length > 0) {\n return exactMatches;\n } // If there are no exact matches, do a more expensive search for matches\n // with errors.\n\n\n return (0,dist/* default */.Z)(text, str, maxErrors);\n}\n/**\n * Compute a score between 0 and 1.0 for the similarity between `text` and `str`.\n *\n * @param {string} text\n * @param {string} str\n */\n\n\nfunction textMatchScore(text, str) {\n /* istanbul ignore next - `scoreMatch` will never pass an empty string */\n if (str.length === 0 || text.length === 0) {\n return 0.0;\n }\n\n var matches = search(text, str, str.length); // prettier-ignore\n\n return 1 - matches[0].errors / str.length;\n}\n/**\n * Find the best approximate match for `quote` in `text`.\n *\n * Returns `null` if no match exceeding the minimum quality threshold was found.\n *\n * @param {string} text - Document text to search\n * @param {string} quote - String to find within `text`\n * @param {Object} context -\n * Context in which the quote originally appeared. This is used to choose the\n * best match.\n * @param {string} [context.prefix] - Expected text before the quote\n * @param {string} [context.suffix] - Expected text after the quote\n * @param {number} [context.hint] - Expected offset of match within text\n * @return {Match|null}\n */\n\n\nfunction matchQuote(text, quote) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (quote.length === 0) {\n return null;\n } // Choose the maximum number of errors to allow for the initial search.\n // This choice involves a tradeoff between:\n //\n // - Recall (proportion of "good" matches found)\n // - Precision (proportion of matches found which are "good")\n // - Cost of the initial search and of processing the candidate matches [1]\n //\n // [1] Specifically, the expected-time complexity of the initial search is\n // `O((maxErrors / 32) * text.length)`. See `approx-string-match` docs.\n\n\n var maxErrors = Math.min(256, quote.length / 2); // Find closest matches for `quote` in `text` based on edit distance.\n\n var matches = search(text, quote, maxErrors);\n\n if (matches.length === 0) {\n return null;\n }\n /**\n * Compute a score between 0 and 1.0 for a match candidate.\n *\n * @param {StringMatch} match\n */\n\n\n var scoreMatch = function scoreMatch(match) {\n var quoteWeight = 50; // Similarity of matched text to quote.\n\n var prefixWeight = 20; // Similarity of text before matched text to `context.prefix`.\n\n var suffixWeight = 20; // Similarity of text after matched text to `context.suffix`.\n\n var posWeight = 2; // Proximity to expected location. Used as a tie-breaker.\n\n var quoteScore = 1 - match.errors / quote.length;\n var prefixScore = context.prefix ? textMatchScore(text.slice(Math.max(0, match.start - context.prefix.length), match.start), context.prefix) : 1.0;\n var suffixScore = context.suffix ? textMatchScore(text.slice(match.end, match.end + context.suffix.length), context.suffix) : 1.0;\n var posScore = 1.0;\n\n if (typeof context.hint === \'number\') {\n var offset = Math.abs(match.start - context.hint);\n posScore = 1.0 - offset / text.length;\n }\n\n var rawScore = quoteWeight * quoteScore + prefixWeight * prefixScore + suffixWeight * suffixScore + posWeight * posScore;\n var maxScore = quoteWeight + prefixWeight + suffixWeight + posWeight;\n var normalizedScore = rawScore / maxScore;\n return normalizedScore;\n }; // Rank matches based on similarity of actual and expected surrounding text\n // and actual/expected offset in the document text.\n\n\n var scoredMatches = matches.map(function (m) {\n return {\n start: m.start,\n end: m.end,\n score: scoreMatch(m)\n };\n }); // Choose match with highest score.\n\n scoredMatches.sort(function (a, b) {\n return b.score - a.score;\n });\n return scoredMatches[0];\n}\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/text-range.js\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Return the combined length of text nodes contained in `node`.\n *\n * @param {Node} node\n */\nfunction nodeTextLength(node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.TEXT_NODE:\n // nb. `textContent` excludes text in comments and processing instructions\n // when called on a parent element, so we don\'t need to subtract that here.\n return (\n /** @type {string} */\n node.textContent.length\n );\n\n default:\n return 0;\n }\n}\n/**\n * Return the total length of the text of all previous siblings of `node`.\n *\n * @param {Node} node\n */\n\n\nfunction previousSiblingsTextLength(node) {\n var sibling = node.previousSibling;\n var length = 0;\n\n while (sibling) {\n length += nodeTextLength(sibling);\n sibling = sibling.previousSibling;\n }\n\n return length;\n}\n/**\n * Resolve one or more character offsets within an element to (text node, position)\n * pairs.\n *\n * @param {Element} element\n * @param {number[]} offsets - Offsets, which must be sorted in ascending order\n * @return {{ node: Text, offset: number }[]}\n */\n\n\nfunction resolveOffsets(element) {\n for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n offsets[_key - 1] = arguments[_key];\n }\n\n var nextOffset = offsets.shift();\n var nodeIter =\n /** @type {Document} */\n element.ownerDocument.createNodeIterator(element, NodeFilter.SHOW_TEXT);\n var results = [];\n var currentNode = nodeIter.nextNode();\n var textNode;\n var length = 0; // Find the text node containing the `nextOffset`th character from the start\n // of `element`.\n\n while (nextOffset !== undefined && currentNode) {\n textNode =\n /** @type {Text} */\n currentNode;\n\n if (length + textNode.data.length > nextOffset) {\n results.push({\n node: textNode,\n offset: nextOffset - length\n });\n nextOffset = offsets.shift();\n } else {\n currentNode = nodeIter.nextNode();\n length += textNode.data.length;\n }\n } // Boundary case.\n\n\n while (nextOffset !== undefined && textNode && length === nextOffset) {\n results.push({\n node: textNode,\n offset: textNode.data.length\n });\n nextOffset = offsets.shift();\n }\n\n if (nextOffset !== undefined) {\n throw new RangeError(\'Offset exceeds text length\');\n }\n\n return results;\n}\n\nvar RESOLVE_FORWARDS = 1;\nvar RESOLVE_BACKWARDS = 2;\n/**\n * Represents an offset within the text content of an element.\n *\n * This position can be resolved to a specific descendant node in the current\n * DOM subtree of the element using the `resolve` method.\n */\n\nvar text_range_TextPosition = /*#__PURE__*/function () {\n /**\n * Construct a `TextPosition` that refers to the text position `offset` within\n * the text content of `element`.\n *\n * @param {Element} element\n * @param {number} offset\n */\n function TextPosition(element, offset) {\n _classCallCheck(this, TextPosition);\n\n if (offset < 0) {\n throw new Error(\'Offset is invalid\');\n }\n /** Element that `offset` is relative to. */\n\n\n this.element = element;\n /** Character offset from the start of the element\'s `textContent`. */\n\n this.offset = offset;\n }\n /**\n * Return a copy of this position with offset relative to a given ancestor\n * element.\n *\n * @param {Element} parent - Ancestor of `this.element`\n * @return {TextPosition}\n */\n\n\n _createClass(TextPosition, [{\n key: "relativeTo",\n value: function relativeTo(parent) {\n if (!parent.contains(this.element)) {\n throw new Error(\'Parent is not an ancestor of current element\');\n }\n\n var el = this.element;\n var offset = this.offset;\n\n while (el !== parent) {\n offset += previousSiblingsTextLength(el);\n el =\n /** @type {Element} */\n el.parentElement;\n }\n\n return new TextPosition(el, offset);\n }\n /**\n * Resolve the position to a specific text node and offset within that node.\n *\n * Throws if `this.offset` exceeds the length of the element\'s text. In the\n * case where the element has no text and `this.offset` is 0, the `direction`\n * option determines what happens.\n *\n * Offsets at the boundary between two nodes are resolved to the start of the\n * node that begins at the boundary.\n *\n * @param {Object} [options]\n * @param {RESOLVE_FORWARDS|RESOLVE_BACKWARDS} [options.direction] -\n * Specifies in which direction to search for the nearest text node if\n * `this.offset` is `0` and `this.element` has no text. If not specified\n * an error is thrown.\n * @return {{ node: Text, offset: number }}\n * @throws {RangeError}\n */\n\n }, {\n key: "resolve",\n value: function resolve() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n try {\n return resolveOffsets(this.element, this.offset)[0];\n } catch (err) {\n if (this.offset === 0 && options.direction !== undefined) {\n var tw = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);\n tw.currentNode = this.element;\n var forwards = options.direction === RESOLVE_FORWARDS;\n var text =\n /** @type {Text|null} */\n forwards ? tw.nextNode() : tw.previousNode();\n\n if (!text) {\n throw err;\n }\n\n return {\n node: text,\n offset: forwards ? 0 : text.data.length\n };\n } else {\n throw err;\n }\n }\n }\n /**\n * Construct a `TextPosition` that refers to the `offset`th character within\n * `node`.\n *\n * @param {Node} node\n * @param {number} offset\n * @return {TextPosition}\n */\n\n }], [{\n key: "fromCharOffset",\n value: function fromCharOffset(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n return TextPosition.fromPoint(node, offset);\n\n case Node.ELEMENT_NODE:\n return new TextPosition(\n /** @type {Element} */\n node, offset);\n\n default:\n throw new Error(\'Node is not an element or text node\');\n }\n }\n /**\n * Construct a `TextPosition` representing the range start or end point (node, offset).\n *\n * @param {Node} node - Text or Element node\n * @param {number} offset - Offset within the node.\n * @return {TextPosition}\n */\n\n }, {\n key: "fromPoint",\n value: function fromPoint(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n {\n if (offset < 0 || offset >\n /** @type {Text} */\n node.data.length) {\n throw new Error(\'Text node offset is out of range\');\n }\n\n if (!node.parentElement) {\n throw new Error(\'Text node has no parent\');\n } // Get the offset from the start of the parent element.\n\n\n var textOffset = previousSiblingsTextLength(node) + offset;\n return new TextPosition(node.parentElement, textOffset);\n }\n\n case Node.ELEMENT_NODE:\n {\n if (offset < 0 || offset > node.childNodes.length) {\n throw new Error(\'Child node offset is out of range\');\n } // Get the text length before the `offset`th child of element.\n\n\n var _textOffset = 0;\n\n for (var i = 0; i < offset; i++) {\n _textOffset += nodeTextLength(node.childNodes[i]);\n }\n\n return new TextPosition(\n /** @type {Element} */\n node, _textOffset);\n }\n\n default:\n throw new Error(\'Point is not in an element or text node\');\n }\n }\n }]);\n\n return TextPosition;\n}();\n/**\n * Represents a region of a document as a (start, end) pair of `TextPosition` points.\n *\n * Representing a range in this way allows for changes in the DOM content of the\n * range which don\'t affect its text content, without affecting the text content\n * of the range itself.\n */\n\nvar text_range_TextRange = /*#__PURE__*/function () {\n /**\n * Construct an immutable `TextRange` from a `start` and `end` point.\n *\n * @param {TextPosition} start\n * @param {TextPosition} end\n */\n function TextRange(start, end) {\n _classCallCheck(this, TextRange);\n\n this.start = start;\n this.end = end;\n }\n /**\n * Return a copy of this range with start and end positions relative to a\n * given ancestor. See `TextPosition.relativeTo`.\n *\n * @param {Element} element\n */\n\n\n _createClass(TextRange, [{\n key: "relativeTo",\n value: function relativeTo(element) {\n return new TextRange(this.start.relativeTo(element), this.end.relativeTo(element));\n }\n /**\n * Resolve the `TextRange` to a DOM range.\n *\n * The resulting DOM Range will always start and end in a `Text` node.\n * Hence `TextRange.fromRange(range).toRange()` can be used to "shrink" a\n * range to the text it contains.\n *\n * May throw if the `start` or `end` positions cannot be resolved to a range.\n *\n * @return {Range}\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var start;\n var end;\n\n if (this.start.element === this.end.element && this.start.offset <= this.end.offset) {\n // Fast path for start and end points in same element.\n var _resolveOffsets = resolveOffsets(this.start.element, this.start.offset, this.end.offset);\n\n var _resolveOffsets2 = _slicedToArray(_resolveOffsets, 2);\n\n start = _resolveOffsets2[0];\n end = _resolveOffsets2[1];\n } else {\n start = this.start.resolve({\n direction: RESOLVE_FORWARDS\n });\n end = this.end.resolve({\n direction: RESOLVE_BACKWARDS\n });\n }\n\n var range = new Range();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range;\n }\n /**\n * Convert an existing DOM `Range` to a `TextRange`\n *\n * @param {Range} range\n * @return {TextRange}\n */\n\n }], [{\n key: "fromRange",\n value: function fromRange(range) {\n var start = text_range_TextPosition.fromPoint(range.startContainer, range.startOffset);\n var end = text_range_TextPosition.fromPoint(range.endContainer, range.endOffset);\n return new TextRange(start, end);\n }\n /**\n * Return a `TextRange` from the `start`th to `end`th characters in `root`.\n *\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n\n }, {\n key: "fromOffsets",\n value: function fromOffsets(root, start, end) {\n return new TextRange(new text_range_TextPosition(root, start), new text_range_TextPosition(root, end));\n }\n }]);\n\n return TextRange;\n}();\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/types.js\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction types_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction types_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction types_createClass(Constructor, protoProps, staticProps) { if (protoProps) types_defineProperties(Constructor.prototype, protoProps); if (staticProps) types_defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This module exports a set of classes for converting between DOM `Range`\n * objects and different types of selectors. It is mostly a thin wrapper around a\n * set of anchoring libraries. It serves two main purposes:\n *\n * 1. Providing a consistent interface across different types of anchors.\n * 2. Insulating the rest of the code from API changes in the underlying anchoring\n * libraries.\n */\n\n\n\n/**\n * @typedef {import(\'../../types/api\').RangeSelector} RangeSelector\n * @typedef {import(\'../../types/api\').TextPositionSelector} TextPositionSelector\n * @typedef {import(\'../../types/api\').TextQuoteSelector} TextQuoteSelector\n */\n\n/**\n * Converts between `RangeSelector` selectors and `Range` objects.\n */\n\nvar RangeAnchor = /*#__PURE__*/(/* unused pure expression or super */ null && (function () {\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n function RangeAnchor(root, range) {\n types_classCallCheck(this, RangeAnchor);\n\n this.root = root;\n this.range = range;\n }\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n\n\n types_createClass(RangeAnchor, [{\n key: "toRange",\n value: function toRange() {\n return this.range;\n }\n /**\n * @return {RangeSelector}\n */\n\n }, {\n key: "toSelector",\n value: function toSelector() {\n // "Shrink" the range so that it tightly wraps its text. This ensures more\n // predictable output for a given text selection.\n var normalizedRange = TextRange.fromRange(this.range).toRange();\n var textRange = TextRange.fromRange(normalizedRange);\n var startContainer = xpathFromNode(textRange.start.element, this.root);\n var endContainer = xpathFromNode(textRange.end.element, this.root);\n return {\n type: \'RangeSelector\',\n startContainer: startContainer,\n startOffset: textRange.start.offset,\n endContainer: endContainer,\n endOffset: textRange.end.offset\n };\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n return new RangeAnchor(root, range);\n }\n /**\n * Create an anchor from a serialized `RangeSelector` selector.\n *\n * @param {Element} root - A root element from which to anchor.\n * @param {RangeSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var startContainer = nodeFromXPath(selector.startContainer, root);\n\n if (!startContainer) {\n throw new Error(\'Failed to resolve startContainer XPath\');\n }\n\n var endContainer = nodeFromXPath(selector.endContainer, root);\n\n if (!endContainer) {\n throw new Error(\'Failed to resolve endContainer XPath\');\n }\n\n var startPos = TextPosition.fromCharOffset(startContainer, selector.startOffset);\n var endPos = TextPosition.fromCharOffset(endContainer, selector.endOffset);\n var range = new TextRange(startPos, endPos).toRange();\n return new RangeAnchor(root, range);\n }\n }]);\n\n return RangeAnchor;\n}()));\n/**\n * Converts between `TextPositionSelector` selectors and `Range` objects.\n */\n\nvar TextPositionAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n function TextPositionAnchor(root, start, end) {\n types_classCallCheck(this, TextPositionAnchor);\n\n this.root = root;\n this.start = start;\n this.end = end;\n }\n /**\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextPositionAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextPositionSelector}\n */\n function toSelector() {\n return {\n type: \'TextPositionSelector\',\n start: this.start,\n end: this.end\n };\n }\n }, {\n key: "toRange",\n value: function toRange() {\n return text_range_TextRange.fromOffsets(this.root, this.start, this.end).toRange();\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n return new TextPositionAnchor(root, textRange.start.offset, textRange.end.offset);\n }\n /**\n * @param {Element} root\n * @param {TextPositionSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n return new TextPositionAnchor(root, selector.start, selector.end);\n }\n }]);\n\n return TextPositionAnchor;\n}();\n/**\n * @typedef QuoteMatchOptions\n * @prop {number} [hint] - Expected position of match in text. See `matchQuote`.\n */\n\n/**\n * Converts between `TextQuoteSelector` selectors and `Range` objects.\n */\n\nvar TextQuoteAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root - A root element from which to anchor.\n * @param {string} exact\n * @param {Object} context\n * @param {string} [context.prefix]\n * @param {string} [context.suffix]\n */\n function TextQuoteAnchor(root, exact) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n types_classCallCheck(this, TextQuoteAnchor);\n\n this.root = root;\n this.exact = exact;\n this.context = context;\n }\n /**\n * Create a `TextQuoteAnchor` from a range.\n *\n * Will throw if `range` does not contain any text nodes.\n *\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextQuoteAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextQuoteSelector}\n */\n function toSelector() {\n return {\n type: \'TextQuoteSelector\',\n exact: this.exact,\n prefix: this.context.prefix,\n suffix: this.context.suffix\n };\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return this.toPositionAnchor(options).toRange();\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toPositionAnchor",\n value: function toPositionAnchor() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var text =\n /** @type {string} */\n this.root.textContent;\n var match = matchQuote(text, this.exact, _objectSpread(_objectSpread({}, this.context), {}, {\n hint: options.hint\n }));\n\n if (!match) {\n throw new Error(\'Quote not found\');\n }\n\n return new TextPositionAnchor(this.root, match.start, match.end);\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var text =\n /** @type {string} */\n root.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n var start = textRange.start.offset;\n var end = textRange.end.offset; // Number of characters around the quote to capture as context. We currently\n // always use a fixed amount, but it would be better if this code was aware\n // of logical boundaries in the document (paragraph, article etc.) to avoid\n // capturing text unrelated to the quote.\n //\n // In regular prose the ideal content would often be the surrounding sentence.\n // This is a natural unit of meaning which enables displaying quotes in\n // context even when the document is not available. We could use `Intl.Segmenter`\n // for this when available.\n\n var contextLen = 32;\n return new TextQuoteAnchor(root, text.slice(start, end), {\n prefix: text.slice(Math.max(0, start - contextLen), start),\n suffix: text.slice(end, Math.min(text.length, end + contextLen))\n });\n }\n /**\n * @param {Element} root\n * @param {TextQuoteSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var prefix = selector.prefix,\n suffix = selector.suffix;\n return new TextQuoteAnchor(root, selector.exact, {\n prefix: prefix,\n suffix: suffix\n });\n }\n }]);\n\n return TextQuoteAnchor;\n}();\n;// CONCATENATED MODULE: ./src/utils.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = utils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction utils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return utils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return utils_arrayLikeToArray(o, minLen); }\n\nfunction utils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n // Catch JS errors to log them in the app.\n\nwindow.addEventListener("error", function (event) {\n Android.logError(event.message, event.filename, event.lineno);\n}, false);\nwindow.addEventListener("load", function () {\n var observer = new ResizeObserver(function () {\n onViewportWidthChanged();\n snapCurrentOffset();\n });\n observer.observe(document.body);\n}, false);\n/**\n * Having an odd number of columns when displaying two columns per screen causes snapping and page\n * turning issues. To fix this, we insert a blank virtual column at the end of the resource.\n */\n\nfunction appendVirtualColumnIfNeeded() {\n var id = "readium-virtual-page";\n var virtualCol = document.getElementById(id);\n\n if (isScrollModeEnabled() || getColumnCountPerScreen() != 2) {\n if (virtualCol) {\n virtualCol.remove();\n }\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var colCount = documentWidth / pageWidth;\n var hasOddColCount = Math.round(colCount * 2) / 2 % 1 > 0.1;\n\n if (hasOddColCount) {\n if (virtualCol) {\n virtualCol.remove();\n } else {\n virtualCol = document.createElement("div");\n virtualCol.setAttribute("id", id);\n virtualCol.style.breakBefore = "column";\n virtualCol.innerHTML = "​"; // zero-width space\n\n document.body.appendChild(virtualCol);\n }\n }\n }\n}\n\nvar pageWidth = 1;\n\nfunction onViewportWidthChanged() {\n // We can\'t rely on window.innerWidth for the pageWidth on Android, because if the\n // device pixel ratio is not an integer, we get rounding issues offsetting the pages.\n //\n // See https://github.com/readium/readium-css/issues/97\n // and https://github.com/readium/r2-navigator-kotlin/issues/146\n var width = Android.getViewportWidth();\n pageWidth = width / window.devicePixelRatio;\n setProperty("--RS__viewportWidth", "calc(" + width + "px / " + window.devicePixelRatio + ")");\n appendVirtualColumnIfNeeded();\n}\n\nfunction getColumnCountPerScreen() {\n return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n}\nfunction isScrollModeEnabled() {\n var style = document.documentElement.style;\n return style.getPropertyValue("--USER__view").trim() == "readium-scroll-on" || // FIXME: Will need to be removed in Readium 3.0, --USER__scroll was incorrect.\n style.getPropertyValue("--USER__scroll").trim() == "readium-scroll-on";\n}\nfunction isRTL() {\n return document.body.dir.toLowerCase() == "rtl";\n} // Scroll to the given TagId in document and snap.\n\nfunction scrollToId(id) {\n var element = document.getElementById(id);\n\n if (!element) {\n return false;\n }\n\n return scrollToRect(element.getBoundingClientRect());\n} // Position must be in the range [0 - 1], 0-100%.\n\nfunction scrollToPosition(position) {\n // Android.log("scrollToPosition " + position);\n if (position < 0 || position > 1) {\n throw "scrollToPosition() must be given a position from 0.0 to 1.0";\n }\n\n var offset;\n\n if (isScrollModeEnabled()) {\n offset = document.scrollingElement.scrollHeight * position;\n document.scrollingElement.scrollTop = offset; // window.scrollTo(0, offset);\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var factor = isRTL() ? -1 : 1;\n offset = documentWidth * position * factor;\n document.scrollingElement.scrollLeft = snapOffset(offset);\n }\n} // Scrolls to the first occurrence of the given text snippet.\n//\n// The expected text argument is a Locator Text object, as defined here:\n// https://readium.org/architecture/models/locators/\n\nfunction scrollToText(text) {\n var range = rangeFromLocator({\n text: text\n });\n\n if (!range) {\n return false;\n }\n\n scrollToRange(range);\n return true;\n}\n\nfunction scrollToRange(range) {\n return scrollToRect(range.getBoundingClientRect());\n}\n\nfunction scrollToRect(rect) {\n if (isScrollModeEnabled()) {\n document.scrollingElement.scrollTop = rect.top + window.scrollY - window.innerHeight / 2;\n } else {\n document.scrollingElement.scrollLeft = snapOffset(rect.left + window.scrollX);\n }\n\n return true;\n}\n\nfunction scrollToStart() {\n // Android.log("scrollToStart");\n if (!isScrollModeEnabled()) {\n document.scrollingElement.scrollLeft = 0;\n } else {\n document.scrollingElement.scrollTop = 0;\n window.scrollTo(0, 0);\n }\n}\nfunction scrollToEnd() {\n // Android.log("scrollToEnd");\n if (!isScrollModeEnabled()) {\n var factor = isRTL() ? -1 : 1;\n document.scrollingElement.scrollLeft = snapOffset(document.scrollingElement.scrollWidth * factor);\n } else {\n document.scrollingElement.scrollTop = document.body.scrollHeight;\n window.scrollTo(0, document.body.scrollHeight);\n }\n} // Returns false if the page is already at the left-most scroll offset.\n\nfunction scrollLeft() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX - pageWidth;\n var minOffset = isRTL() ? -(documentWidth - pageWidth) : 0;\n return scrollToOffset(Math.max(offset, minOffset));\n} // Returns false if the page is already at the right-most scroll offset.\n\nfunction scrollRight() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX + pageWidth;\n var maxOffset = isRTL() ? 0 : documentWidth - pageWidth;\n return scrollToOffset(Math.min(offset, maxOffset));\n} // Scrolls to the given left offset.\n// Returns false if the page scroll position is already close enough to the given offset.\n\nfunction scrollToOffset(offset) {\n // Android.log("scrollToOffset " + offset);\n if (isScrollModeEnabled()) {\n throw "Called scrollToOffset() with scroll mode enabled. This can only be used in paginated mode.";\n }\n\n var currentOffset = window.scrollX;\n document.scrollingElement.scrollLeft = snapOffset(offset); // In some case the scrollX cannot reach the position respecting to innerWidth\n\n var diff = Math.abs(currentOffset - offset) / pageWidth;\n return diff > 0.01;\n} // Snap the offset to the screen width (page width).\n\n\nfunction snapOffset(offset) {\n var value = offset + (isRTL() ? -1 : 1);\n return value - value % pageWidth;\n} // Snaps the current offset to the page width.\n\n\nfunction snapCurrentOffset() {\n // Android.log("snapCurrentOffset");\n if (isScrollModeEnabled()) {\n return;\n }\n\n var currentOffset = window.scrollX; // Adds half a page to make sure we don\'t snap to the previous page.\n\n var factor = isRTL() ? -1 : 1;\n var delta = factor * (pageWidth / 2);\n document.scrollingElement.scrollLeft = snapOffset(currentOffset + delta);\n}\nfunction rangeFromLocator(locator) {\n try {\n var locations = locator.locations;\n var text = locator.text;\n\n if (text && text.highlight) {\n var root;\n\n if (locations && locations.cssSelector) {\n root = document.querySelector(locations.cssSelector);\n }\n\n if (!root) {\n root = document.body;\n }\n\n var anchor = new TextQuoteAnchor(root, text.highlight, {\n prefix: text.before,\n suffix: text.after\n });\n return anchor.toRange();\n }\n\n if (locations) {\n var element = null;\n\n if (!element && locations.cssSelector) {\n element = document.querySelector(locations.cssSelector);\n }\n\n if (!element && locations.fragments) {\n var _iterator = _createForOfIteratorHelper(locations.fragments),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var htmlId = _step.value;\n element = document.getElementById(htmlId);\n\n if (element) {\n break;\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n if (element) {\n var range = document.createRange();\n range.setStartBefore(element);\n range.setEndAfter(element);\n return range;\n }\n }\n } catch (e) {\n logError(e);\n }\n\n return null;\n} /// User Settings.\n\nfunction setCSSProperties(properties) {\n for (var name in properties) {\n setProperty(name, properties[name]);\n }\n} // For setting user setting.\n\nfunction setProperty(key, value) {\n if (value === null || value === "") {\n removeProperty(key);\n } else {\n var root = document.documentElement; // The `!important` annotation is added with `setProperty()` because if it\'s part of the\n // `value`, it will be ignored by the Web View.\n\n root.style.setProperty(key, value, "important");\n }\n} // For removing user setting.\n\nfunction removeProperty(key) {\n var root = document.documentElement;\n root.style.removeProperty(key);\n} /// Toolkit\n\nfunction log() {\n var message = Array.prototype.slice.call(arguments).join(" ");\n Android.log(message);\n}\nfunction logError(message) {\n Android.logError(message, "", 0);\n}\n;// CONCATENATED MODULE: ./src/rect.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction rect_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = rect_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction rect_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return rect_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return rect_arrayLikeToArray(o, minLen); }\n\nfunction rect_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nvar debug = false;\n/**\n * Converts a DOMRect into a JSON object understandable by the native side.\n */\n\nfunction toNativeRect(rect) {\n var pixelRatio = window.devicePixelRatio;\n var width = rect.width * pixelRatio;\n var height = rect.height * pixelRatio;\n var left = rect.left * pixelRatio;\n var top = rect.top * pixelRatio;\n var right = left + width;\n var bottom = top + height;\n return {\n width: width,\n height: height,\n left: left,\n top: top,\n right: right,\n bottom: bottom\n };\n}\nfunction getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var clientRects = range.getClientRects();\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator = rect_createForOfIteratorHelper(clientRects),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var rangeClientRect = _step.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n var mergedRects = mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = removeContainedRects(mergedRects, tolerance);\n var newRects = replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n rect_log("CLIENT RECT: remove small");\n newRects.splice(j, 1);\n } else {\n rect_log("CLIENT RECT: remove small, but keep otherwise empty!");\n break;\n }\n }\n }\n\n rect_log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n return newRects;\n}\n\nfunction mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("mergeTouchingRects rect1 === rect2 ??!");\n return "continue";\n }\n\n var rectsLineUpVertically = almostEqual(rect1.top, rect2.top, tolerance) && almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = almostEqual(rect1.left, rect2.left, tolerance) && almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n rect_log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret = _loop(j);\n\n if (_ret === "continue") continue;\n if (_typeof(_ret) === "object") return _ret.v;\n }\n }\n\n return rects;\n}\n\nfunction getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator2 = rect_createForOfIteratorHelper(rects),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var rect = _step2.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n rect_log("CLIENT RECT: remove tiny");\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator3 = rect_createForOfIteratorHelper(rects),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var possiblyContainingRect = _step3.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (rectContains(possiblyContainingRect, rect, tolerance)) {\n rect_log("CLIENT RECT: remove contained");\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction rectContains(rect1, rect2, tolerance) {\n return rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || almostEqual(rect.left, x, tolerance)) && (rect.right > x || almostEqual(rect.right, x, tolerance)) && (rect.top < y || almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("replaceOverlapingRects rect1 === rect2 ??!");\n continue;\n }\n\n if (rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret2 = function () {\n var toAdd = [];\n var toRemove = void 0;\n var subtractRects1 = rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n var subtractRects2 = rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n }\n }\n\n rect_log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: replaceOverlapingRects(newRects)\n };\n }();\n\n if (_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction rectSubtract(rect1, rect2) {\n var rectIntersected = rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n return {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n}\n\nfunction rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction rect_log() {\n if (debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/decorator.js\nfunction decorator_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = decorator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction decorator_slicedToArray(arr, i) { return decorator_arrayWithHoles(arr) || decorator_iterableToArrayLimit(arr, i) || decorator_unsupportedIterableToArray(arr, i) || decorator_nonIterableRest(); }\n\nfunction decorator_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction decorator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return decorator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return decorator_arrayLikeToArray(o, minLen); }\n\nfunction decorator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction decorator_iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction decorator_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nvar styles = new Map();\nvar groups = new Map();\nvar lastGroupId = 0;\n/**\n * Registers a list of additional supported Decoration Templates.\n *\n * Each template object is indexed by the style ID.\n */\n\nfunction registerTemplates(newStyles) {\n var stylesheet = "";\n\n for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = decorator_slicedToArray(_Object$entries[_i], 2),\n id = _Object$entries$_i[0],\n style = _Object$entries$_i[1];\n\n styles.set(id, style);\n\n if (style.stylesheet) {\n stylesheet += style.stylesheet + "\\n";\n }\n }\n\n if (stylesheet) {\n var styleElement = document.createElement("style");\n styleElement.innerHTML = stylesheet;\n document.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n}\n/**\n * Returns an instance of DecorationGroup for the given group name.\n */\n\nfunction getDecorations(groupName) {\n var group = groups.get(groupName);\n\n if (!group) {\n var id = "r2-decoration-" + lastGroupId++;\n group = DecorationGroup(id, groupName);\n groups.set(groupName, group);\n }\n\n return group;\n}\n/**\n * Handles click events on a Decoration.\n * Returns whether a decoration matched this event.\n */\n\nfunction handleDecorationClickEvent(event, clickEvent) {\n if (groups.size === 0) {\n return false;\n }\n\n function findTarget() {\n var _iterator = decorator_createForOfIteratorHelper(groups),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = decorator_slicedToArray(_step.value, 2),\n group = _step$value[0],\n groupContent = _step$value[1];\n\n var _iterator2 = decorator_createForOfIteratorHelper(groupContent.items.reverse()),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var item = _step2.value;\n\n if (!item.clickableElements) {\n continue;\n }\n\n var _iterator3 = decorator_createForOfIteratorHelper(item.clickableElements),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var element = _step3.value;\n var rect = element.getBoundingClientRect().toJSON();\n\n if (rectContainsPoint(rect, event.clientX, event.clientY, 1)) {\n return {\n group: group,\n item: item,\n element: element,\n rect: rect\n };\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var target = findTarget();\n\n if (!target) {\n return false;\n }\n\n return Android.onDecorationActivated(JSON.stringify({\n id: target.item.decoration.id,\n group: target.group,\n rect: toNativeRect(target.item.range.getBoundingClientRect()),\n click: clickEvent\n }));\n}\n/**\n * Creates a DecorationGroup object from a unique HTML ID and its name.\n */\n\nfunction DecorationGroup(groupId, groupName) {\n var items = [];\n var lastItemId = 0;\n var container = null;\n /**\n * Adds a new decoration to the group.\n */\n\n function add(decoration) {\n var id = groupId + "-" + lastItemId++;\n var range = rangeFromLocator(decoration.locator);\n\n if (!range) {\n log("Can\'t locate DOM range for decoration", decoration);\n return;\n }\n\n var item = {\n id: id,\n decoration: decoration,\n range: range\n };\n items.push(item);\n layout(item);\n }\n /**\n * Removes the decoration with given ID from the group.\n */\n\n\n function remove(decorationId) {\n var index = items.findIndex(function (i) {\n return i.decoration.id === decorationId;\n });\n\n if (index === -1) {\n return;\n }\n\n var item = items[index];\n items.splice(index, 1);\n item.clickableElements = null;\n\n if (item.container) {\n item.container.remove();\n item.container = null;\n }\n }\n /**\n * Notifies that the given decoration was modified and needs to be updated.\n */\n\n\n function update(decoration) {\n remove(decoration.id);\n add(decoration);\n }\n /**\n * Removes all decorations from this group.\n */\n\n\n function clear() {\n clearContainer();\n items.length = 0;\n }\n /**\n * Recreates the decoration elements.\n *\n * To be called after reflowing the resource, for example.\n */\n\n\n function requestLayout() {\n clearContainer();\n items.forEach(function (item) {\n return layout(item);\n });\n }\n /**\n * Layouts a single Decoration item.\n */\n\n\n function layout(item) {\n var groupContainer = requireContainer();\n var style = styles.get(item.decoration.style);\n\n if (!style) {\n logError("Unknown decoration style: ".concat(item.decoration.style));\n return;\n }\n\n var itemContainer = document.createElement("div");\n itemContainer.setAttribute("id", item.id);\n itemContainer.setAttribute("data-style", item.decoration.style);\n itemContainer.style.setProperty("pointer-events", "none");\n var viewportWidth = window.innerWidth;\n var columnCount = parseInt(getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n var pageWidth = viewportWidth / (columnCount || 1);\n var scrollingElement = document.scrollingElement;\n var xOffset = scrollingElement.scrollLeft;\n var yOffset = scrollingElement.scrollTop;\n\n function positionElement(element, rect, boundingRect) {\n element.style.position = "absolute";\n\n if (style.width === "wrap") {\n element.style.width = "".concat(rect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(rect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "viewport") {\n element.style.width = "".concat(viewportWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n var left = Math.floor(rect.left / viewportWidth) * viewportWidth;\n element.style.left = "".concat(left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "bounds") {\n element.style.width = "".concat(boundingRect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(boundingRect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "page") {\n element.style.width = "".concat(pageWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n\n var _left = Math.floor(rect.left / pageWidth) * pageWidth;\n\n element.style.left = "".concat(_left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n }\n }\n\n var boundingRect = item.range.getBoundingClientRect();\n var elementTemplate;\n\n try {\n var template = document.createElement("template");\n template.innerHTML = item.decoration.element.trim();\n elementTemplate = template.content.firstElementChild;\n } catch (error) {\n logError("Invalid decoration element \\"".concat(item.decoration.element, "\\": ").concat(error.message));\n return;\n }\n\n if (style.layout === "boxes") {\n var doNotMergeHorizontallyAlignedRects = true;\n var clientRects = getClientRectsNoOverlap(item.range, doNotMergeHorizontallyAlignedRects);\n clientRects = clientRects.sort(function (r1, r2) {\n if (r1.top < r2.top) {\n return -1;\n } else if (r1.top > r2.top) {\n return 1;\n } else {\n return 0;\n }\n });\n\n var _iterator4 = decorator_createForOfIteratorHelper(clientRects),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var clientRect = _step4.value;\n var line = elementTemplate.cloneNode(true);\n line.style.setProperty("pointer-events", "none");\n positionElement(line, clientRect, boundingRect);\n itemContainer.append(line);\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n } else if (style.layout === "bounds") {\n var bounds = elementTemplate.cloneNode(true);\n bounds.style.setProperty("pointer-events", "none");\n positionElement(bounds, boundingRect, boundingRect);\n itemContainer.append(bounds);\n }\n\n groupContainer.append(itemContainer);\n item.container = itemContainer;\n item.clickableElements = Array.from(itemContainer.querySelectorAll("[data-activable=\'1\']"));\n\n if (item.clickableElements.length === 0) {\n item.clickableElements = Array.from(itemContainer.children);\n }\n }\n /**\n * Returns the group container element, after making sure it exists.\n */\n\n\n function requireContainer() {\n if (!container) {\n container = document.createElement("div");\n container.setAttribute("id", groupId);\n container.setAttribute("data-group", groupName);\n container.style.setProperty("pointer-events", "none");\n document.body.append(container);\n }\n\n return container;\n }\n /**\n * Removes the group container.\n */\n\n\n function clearContainer() {\n if (container) {\n container.remove();\n container = null;\n }\n }\n\n return {\n add: add,\n remove: remove,\n update: update,\n clear: clear,\n items: items,\n requestLayout: requestLayout\n };\n}\nwindow.addEventListener("load", function () {\n // Will relayout all the decorations when the document body is resized.\n var body = document.body;\n var lastSize = {\n width: 0,\n height: 0\n };\n var observer = new ResizeObserver(function () {\n if (lastSize.width === body.clientWidth && lastSize.height === body.clientHeight) {\n return;\n }\n\n lastSize = {\n width: body.clientWidth,\n height: body.clientHeight\n };\n groups.forEach(function (group) {\n group.requestLayout();\n });\n });\n observer.observe(body);\n}, false);\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n} // See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling\n\n\nfunction nearestInteractiveElement(element) {\n var interactiveTags = ["a", "audio", "button", "canvas", "details", "input", "label", "option", "select", "submit", "textarea", "video"];\n\n if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) {\n return element.outerHTML;\n } // Checks whether the element is editable by the user.\n\n\n if (element.hasAttribute("contenteditable") && element.getAttribute("contenteditable").toLowerCase() != "false") {\n return element.outerHTML;\n } // Checks parents recursively because the touch might be for example on an inside a .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\n;// CONCATENATED MODULE: ./src/highlight.js\nfunction highlight_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { highlight_typeof = function _typeof(obj) { return typeof obj; }; } else { highlight_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return highlight_typeof(obj); }\n\nfunction highlight_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = highlight_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction highlight_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return highlight_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return highlight_arrayLikeToArray(o, minLen); }\n\nfunction highlight_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/* eslint-disable */\n//\n// highlight.js\n// r2-navigator-kotlin\n//\n// Organized by Taehyun Kim on 6/27/19 from r2-navigator-js.\n//\n// Copyright 2019 Readium Foundation. All rights reserved.\n// Use of this source code is governed by a BSD-style license which is detailed\n// in the LICENSE file present in the project repository where this source code is maintained.\n//\nvar ROOT_CLASS_REDUCE_MOTION = "r2-reduce-motion";\nvar ROOT_CLASS_NO_FOOTNOTES = "r2-no-popup-foonotes";\nvar POPUP_DIALOG_CLASS = "r2-popup-dialog";\nvar FOOTNOTES_CONTAINER_CLASS = "r2-footnote-container";\nvar FOOTNOTES_CLOSE_BUTTON_CLASS = "r2-footnote-close";\nvar FOOTNOTE_FORCE_SHOW = "r2-footnote-force-show";\nvar TTS_ID_PREVIOUS = "r2-tts-previous";\nvar TTS_ID_NEXT = "r2-tts-next";\nvar TTS_ID_SLIDER = "r2-tts-slider";\nvar TTS_ID_ACTIVE_WORD = "r2-tts-active-word";\nvar TTS_ID_CONTAINER = "r2-tts-txt";\nvar TTS_ID_INFO = "r2-tts-info";\nvar TTS_NAV_BUTTON_CLASS = "r2-tts-button";\nvar TTS_ID_SPEAKING_DOC_ELEMENT = "r2-tts-speaking-el";\nvar TTS_CLASS_INJECTED_SPAN = "r2-tts-speaking-txt";\nvar TTS_CLASS_INJECTED_SUBSPAN = "r2-tts-speaking-word";\nvar TTS_ID_INJECTED_PARENT = "r2-tts-speaking-txt-parent";\nvar ID_HIGHLIGHTS_CONTAINER = "R2_ID_HIGHLIGHTS_CONTAINER";\nvar ID_ANNOTATION_CONTAINER = "R2_ID_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_CONTAINER = "R2_CLASS_HIGHLIGHT_CONTAINER";\nvar CLASS_ANNOTATION_CONTAINER = "R2_CLASS_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_AREA = "R2_CLASS_HIGHLIGHT_AREA";\nvar CLASS_ANNOTATION_AREA = "R2_CLASS_ANNOTATION_AREA";\nvar CLASS_HIGHLIGHT_BOUNDING_AREA = "R2_CLASS_HIGHLIGHT_BOUNDING_AREA";\nvar CLASS_ANNOTATION_BOUNDING_AREA = "R2_CLASS_ANNOTATION_BOUNDING_AREA"; // tslint:disable-next-line:max-line-length\n\nvar _blacklistIdClassForCFI = [POPUP_DIALOG_CLASS, TTS_CLASS_INJECTED_SPAN, TTS_CLASS_INJECTED_SUBSPAN, ID_HIGHLIGHTS_CONTAINER, CLASS_HIGHLIGHT_CONTAINER, CLASS_HIGHLIGHT_AREA, CLASS_HIGHLIGHT_BOUNDING_AREA, "resize-sensor"];\nvar CLASS_PAGINATED = "r2-css-paginated"; //const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");\n\nvar IS_DEV = false;\nvar _highlights = [];\n\nvar _highlightsContainer;\n\nvar _annotationContainer;\n\nvar lastMouseDownX = -1;\nvar lastMouseDownY = -1;\nvar bodyEventListenersSet = false;\nvar USE_SVG = false;\nvar DEFAULT_BACKGROUND_COLOR_OPACITY = 0.3;\nvar ALT_BACKGROUND_COLOR_OPACITY = 0.45; //const DEBUG_VISUALS = false;\n\nvar DEBUG_VISUALS = false;\nvar DEFAULT_BACKGROUND_COLOR = {\n blue: 100,\n green: 50,\n red: 230\n};\nvar ANNOTATION_WIDTH = 15;\n\nfunction resetHighlightBoundingStyle(_win, highlightBounding) {\n if (highlightBounding.getAttribute("class") == CLASS_ANNOTATION_BOUNDING_AREA) {\n return;\n }\n\n highlightBounding.style.outline = "none";\n highlightBounding.style.setProperty("background-color", "transparent", "important");\n}\n\nfunction setHighlightAreaStyle(win, highlightAreas, highlight) {\n var useSVG = !DEBUG_VISUALS && USE_SVG;\n\n var _iterator = highlight_createForOfIteratorHelper(highlightAreas),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var highlightArea = _step.value;\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var opacity = ALT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n}\n\nfunction resetHighlightAreaStyle(win, highlightArea) {\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var id = isSVG ? highlightArea.parentNode && highlightArea.parentNode.parentNode && highlightArea.parentNode.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.parentNode.getAttribute ? highlightArea.parentNode.parentNode.getAttribute("id") : undefined : highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.getAttribute ? highlightArea.parentNode.getAttribute("id") : undefined;\n\n if (id) {\n var highlight = _highlights.find(function (h) {\n return h.id === id;\n });\n\n if (highlight) {\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n }\n}\n\nfunction processTouchEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.changedTouches[0].clientX;\n var y = ev.changedTouches[0].clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect; // _highlights.sort(function(a, b) {\n // console.log(JSON.stringify(a.selectionInfo))\n // return a.selectionInfo.cleanText.length < b.selectionInfo.cleanText.length\n // })\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator2 = highlight_createForOfIteratorHelper(highlightFragments),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var highlightFragment = _step2.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator3 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var highlightBounding = _step3.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i = 0, _allHighlightAreas = allHighlightAreas; _i < _allHighlightAreas.length; _i++) {\n var highlightArea = _allHighlightAreas[_i];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas2 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator4 = highlight_createForOfIteratorHelper(_allHighlightAreas2),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var _highlightArea = _step4.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea) < 0) {\n resetHighlightAreaStyle(win, _highlightArea);\n }\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator5 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step5;\n\n try {\n for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {\n var _highlightBounding = _step5.value;\n\n if (!foundElementHighlightBounding || _highlightBounding !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding);\n }\n }\n } catch (err) {\n _iterator5.e(err);\n } finally {\n _iterator5.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "touchstart" || ev.type === "touchend") {\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight.id,\n size: size\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n console.log(foundHighlight.id.includes("R2_ANNOTATION_"));\n\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n}\n\nfunction processMouseEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.clientX;\n var y = ev.clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect;\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator6 = highlight_createForOfIteratorHelper(highlightFragments),\n _step6;\n\n try {\n for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {\n var highlightFragment = _step6.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator6.e(err);\n } finally {\n _iterator6.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator7 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step7;\n\n try {\n for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {\n var highlightBounding = _step7.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator7.e(err);\n } finally {\n _iterator7.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i2 = 0, _allHighlightAreas3 = allHighlightAreas; _i2 < _allHighlightAreas3.length; _i2++) {\n var highlightArea = _allHighlightAreas3[_i2];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas4 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator8 = highlight_createForOfIteratorHelper(_allHighlightAreas4),\n _step8;\n\n try {\n for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {\n var _highlightArea2 = _step8.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea2) < 0) {\n resetHighlightAreaStyle(win, _highlightArea2);\n }\n }\n } catch (err) {\n _iterator8.e(err);\n } finally {\n _iterator8.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator9 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step9;\n\n try {\n for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {\n var _highlightBounding2 = _step9.value;\n\n if (!foundElementHighlightBounding || _highlightBounding2 !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding2);\n }\n }\n } catch (err) {\n _iterator9.e(err);\n } finally {\n _iterator9.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "mouseup" || ev.type === "touchend") {\n var touchedPosition = {\n screenWidth: window.outerWidth,\n screenHeight: window.innerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight,\n position: touchedPosition\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n }\n }\n}\n\nfunction highlight_rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && highlight_almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && highlight_almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && highlight_almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && highlight_almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction highlight_replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("replaceOverlapingRects rect1 === rect2 ??!");\n }\n\n continue;\n }\n\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret = function () {\n var toAdd = [];\n var toRemove = void 0;\n var toPreserve = void 0;\n var subtractRects1 = highlight_rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n var subtractRects2 = highlight_rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n toPreserve = rect1;\n }\n }\n\n if (IS_DEV) {\n var toCheck = [];\n toCheck.push(toPreserve);\n Array.prototype.push.apply(toCheck, toAdd);\n checkOverlaps(toCheck);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: highlight_replaceOverlapingRects(newRects)\n };\n }();\n\n if (highlight_typeof(_ret) === "object") return _ret.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction checkOverlaps(rects) {\n var stillOverlapingRects = [];\n\n var _iterator10 = highlight_createForOfIteratorHelper(rects),\n _step10;\n\n try {\n for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {\n var rect1 = _step10.value;\n\n var _iterator11 = highlight_createForOfIteratorHelper(rects),\n _step11;\n\n try {\n for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {\n var rect2 = _step11.value;\n\n if (rect1 === rect2) {\n continue;\n }\n\n var has1 = stillOverlapingRects.indexOf(rect1) >= 0;\n var has2 = stillOverlapingRects.indexOf(rect2) >= 0;\n\n if (!has1 || !has2) {\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n if (!has1) {\n stillOverlapingRects.push(rect1);\n }\n\n if (!has2) {\n stillOverlapingRects.push(rect2);\n }\n\n console.log("CLIENT RECT: overlap ---");\n console.log("#1 TOP:".concat(rect1.top, " BOTTOM:").concat(rect1.bottom, " LEFT:").concat(rect1.left, " RIGHT:").concat(rect1.right, " WIDTH:").concat(rect1.width, " HEIGHT:").concat(rect1.height));\n console.log("#2 TOP:".concat(rect2.top, " BOTTOM:").concat(rect2.bottom, " LEFT:").concat(rect2.left, " RIGHT:").concat(rect2.right, " WIDTH:").concat(rect2.width, " HEIGHT:").concat(rect2.height));\n var xOverlap = getRectOverlapX(rect1, rect2);\n console.log("xOverlap: ".concat(xOverlap));\n var yOverlap = getRectOverlapY(rect1, rect2);\n console.log("yOverlap: ".concat(yOverlap));\n }\n }\n }\n } catch (err) {\n _iterator11.e(err);\n } finally {\n _iterator11.f();\n }\n }\n } catch (err) {\n _iterator10.e(err);\n } finally {\n _iterator10.f();\n }\n\n if (stillOverlapingRects.length) {\n console.log("CLIENT RECT: overlaps ".concat(stillOverlapingRects.length));\n }\n}\n\nfunction highlight_removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator12 = highlight_createForOfIteratorHelper(rects),\n _step12;\n\n try {\n for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {\n var rect = _step12.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove tiny");\n }\n\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator13 = highlight_createForOfIteratorHelper(rects),\n _step13;\n\n try {\n for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {\n var possiblyContainingRect = _step13.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (highlight_rectContains(possiblyContainingRect, rect, tolerance)) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove contained");\n }\n\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator13.e(err);\n } finally {\n _iterator13.f();\n }\n }\n } catch (err) {\n _iterator12.e(err);\n } finally {\n _iterator12.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction highlight_almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction highlight_rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n var rect = {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n return rect;\n}\n\nfunction highlight_rectSubtract(rect1, rect2) {\n var rectIntersected = highlight_rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction highlight_rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || highlight_almostEqual(rect.left, x, tolerance)) && (rect.right > x || highlight_almostEqual(rect.right, x, tolerance)) && (rect.top < y || highlight_almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || highlight_almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction highlight_rectContains(rect1, rect2, tolerance) {\n return highlight_rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction highlight_getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction highlight_mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("mergeTouchingRects rect1 === rect2 ??!");\n }\n\n return "continue";\n }\n\n var rectsLineUpVertically = highlight_almostEqual(rect1.top, rect2.top, tolerance) && highlight_almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = highlight_almostEqual(rect1.left, rect2.left, tolerance) && highlight_almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && highlight_rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n if (IS_DEV) {\n console.log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = highlight_getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: highlight_mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret2 = _loop(j);\n\n if (_ret2 === "continue") continue;\n if (highlight_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n\n return rects;\n}\n\nfunction highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var rangeClientRects = range.getClientRects();\n return getClientRectsNoOverlap_(rangeClientRects, doNotMergeHorizontallyAlignedRects);\n}\n\nfunction getClientRectsNoOverlap_(clientRects, doNotMergeHorizontallyAlignedRects) {\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator14 = highlight_createForOfIteratorHelper(clientRects),\n _step14;\n\n try {\n for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {\n var rangeClientRect = _step14.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator14.e(err);\n } finally {\n _iterator14.f();\n }\n\n var mergedRects = highlight_mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = highlight_removeContainedRects(mergedRects, tolerance);\n var newRects = highlight_replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small");\n }\n\n newRects.splice(j, 1);\n } else {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small, but keep otherwise empty!");\n }\n\n break;\n }\n }\n }\n\n if (IS_DEV) {\n checkOverlaps(newRects);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n }\n\n return newRects;\n}\n\nfunction isPaginated(document) {\n return document && document.documentElement && document.documentElement.classList.contains(CLASS_PAGINATED);\n}\n\nfunction getScrollingElement(document) {\n if (document.scrollingElement) {\n return document.scrollingElement;\n }\n\n return document.body;\n}\n\nfunction ensureContainer(win, annotationFlag) {\n var document = win.document;\n\n if (!_highlightsContainer) {\n if (!bodyEventListenersSet) {\n bodyEventListenersSet = true;\n document.body.addEventListener("mousedown", function (ev) {\n lastMouseDownX = ev.clientX;\n lastMouseDownY = ev.clientY;\n }, false);\n document.body.addEventListener("mouseup", function (ev) {\n if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {\n processMouseEvent(win, ev);\n }\n }, false);\n document.body.addEventListener("mousemove", function (ev) {\n processMouseEvent(win, ev);\n }, false);\n document.body.addEventListener("touchend", function touchEnd(e) {\n processTouchEvent(win, e);\n }, false);\n }\n\n _highlightsContainer = document.createElement("div");\n\n _highlightsContainer.setAttribute("id", ID_HIGHLIGHTS_CONTAINER);\n\n _highlightsContainer.style.setProperty("pointer-events", "none");\n\n document.body.append(_highlightsContainer);\n }\n\n return _highlightsContainer;\n}\n\nfunction hideAllhighlights() {\n if (_highlightsContainer) {\n _highlightsContainer.remove();\n\n _highlightsContainer = null;\n }\n}\n\nfunction destroyAllhighlights() {\n hideAllhighlights();\n\n _highlights.splice(0, _highlights.length);\n}\n\nfunction destroyHighlight(id) {\n var i = -1;\n var _document = window.document;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (highlight && i >= 0 && i < _highlights.length) {\n _highlights.splice(i, 1);\n }\n\n var highlightContainer = _document.getElementById(id);\n\n if (highlightContainer) {\n highlightContainer.remove();\n }\n}\n\nfunction isCfiTextNode(node) {\n return node.nodeType !== Node.ELEMENT_NODE;\n}\n\nfunction getChildTextNodeCfiIndex(element, child) {\n var found = -1;\n var textNodeIndex = -1;\n var previousWasElement = false;\n\n for (var i = 0; i < element.childNodes.length; i++) {\n var childNode = element.childNodes[i];\n var isText = isCfiTextNode(childNode);\n\n if (isText || previousWasElement) {\n textNodeIndex += 2;\n }\n\n if (isText) {\n if (childNode === child) {\n found = textNodeIndex;\n break;\n }\n }\n\n previousWasElement = childNode.nodeType === Node.ELEMENT_NODE;\n }\n\n return found;\n}\n\nfunction getCommonAncestorElement(node1, node2) {\n if (node1.nodeType === Node.ELEMENT_NODE && node1 === node2) {\n return node1;\n }\n\n if (node1.nodeType === Node.ELEMENT_NODE && node1.contains(node2)) {\n return node1;\n }\n\n if (node2.nodeType === Node.ELEMENT_NODE && node2.contains(node1)) {\n return node2;\n }\n\n var node1ElementAncestorChain = [];\n var parent = node1.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node1ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var node2ElementAncestorChain = [];\n parent = node2.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node2ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var commonAncestor = node1ElementAncestorChain.find(function (node1ElementAncestor) {\n return node2ElementAncestorChain.indexOf(node1ElementAncestor) >= 0;\n });\n\n if (!commonAncestor) {\n commonAncestor = node2ElementAncestorChain.find(function (node2ElementAncestor) {\n return node1ElementAncestorChain.indexOf(node2ElementAncestor) >= 0;\n });\n }\n\n return commonAncestor;\n}\n\nfunction fullQualifiedSelector(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n return lowerCaseName;\n } //return cssPath(node, justSelector);\n\n\n return cssPath(node, true);\n}\n\nfunction getCurrentSelectionInfo() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n console.log("^^^ SELECTION COLLAPSED.");\n return undefined;\n }\n\n var rawText = selection.toString();\n var cleanText = rawText.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanText.length === 0) {\n console.log("^^^ SELECTION TEXT EMPTY.");\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n console.log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var rangeInfo = convertRange(range, fullQualifiedSelector, computeCFI);\n\n if (!rangeInfo) {\n console.log("^^^ SELECTION RANGE INFO FAIL?!");\n return undefined;\n }\n\n if (IS_DEV && DEBUG_VISUALS) {\n var restoredRange = convertRangeInfo(win.document, rangeInfo);\n\n if (restoredRange) {\n if (restoredRange.startOffset === range.startOffset && restoredRange.endOffset === range.endOffset && restoredRange.startContainer === range.startContainer && restoredRange.endContainer === range.endContainer) {\n console.log("SELECTION RANGE RESTORED OKAY (dev check).");\n } else {\n console.log("SELECTION RANGE RESTORE FAIL (dev check).");\n dumpDebug("SELECTION", selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset, getCssSelector);\n dumpDebug("ORDERED RANGE FROM SELECTION", range.startContainer, range.startOffset, range.endContainer, range.endOffset, getCssSelector);\n dumpDebug("RESTORED RANGE", restoredRange.startContainer, restoredRange.startOffset, restoredRange.endContainer, restoredRange.endOffset, getCssSelector);\n }\n } else {\n console.log("CANNOT RESTORE SELECTION RANGE ??!");\n }\n } else {}\n\n return {\n locations: rangeInfo2Location(rangeInfo),\n text: {\n highlight: rawText\n }\n };\n}\n\nfunction checkBlacklisted(el) {\n var blacklistedId;\n var id = el.getAttribute("id");\n\n if (id && _blacklistIdClassForCFI.indexOf(id) >= 0) {\n console.log("checkBlacklisted ID: " + id);\n blacklistedId = id;\n }\n\n var blacklistedClass;\n\n var _iterator15 = highlight_createForOfIteratorHelper(_blacklistIdClassForCFI),\n _step15;\n\n try {\n for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {\n var item = _step15.value;\n\n if (el.classList.contains(item)) {\n console.log("checkBlacklisted CLASS: " + item);\n blacklistedClass = item;\n break;\n }\n }\n } catch (err) {\n _iterator15.e(err);\n } finally {\n _iterator15.f();\n }\n\n if (blacklistedId || blacklistedClass) {\n return true;\n }\n\n return false;\n}\n\nfunction cssPath(node, optimized) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return "";\n }\n\n var steps = [];\n var contextNode = node;\n\n while (contextNode) {\n var step = _cssPathStep(contextNode, !!optimized, contextNode === node);\n\n if (!step) {\n break; // Error - bail out early.\n }\n\n steps.push(step.value);\n\n if (step.optimized) {\n break;\n }\n\n contextNode = contextNode.parentNode;\n }\n\n steps.reverse();\n return steps.join(" > ");\n} // tslint:disable-next-line:max-line-length\n// https://chromium.googlesource.com/chromium/blink/+/master/Source/devtools/front_end/components/DOMPresentationUtils.js#316\n\n\nfunction _cssPathStep(node, optimized, isTargetNode) {\n function prefixedElementClassNames(nd) {\n var classAttribute = nd.getAttribute("class");\n\n if (!classAttribute) {\n return [];\n }\n\n return classAttribute.split(/\\s+/g).filter(Boolean).map(function (nm) {\n // The prefix is required to store "__proto__" in a object-based map.\n return "$" + nm;\n });\n }\n\n function idSelector(idd) {\n return "#" + escapeIdentifierIfNeeded(idd);\n }\n\n function escapeIdentifierIfNeeded(ident) {\n if (isCSSIdentifier(ident)) {\n return ident;\n }\n\n var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);\n var lastIndex = ident.length - 1;\n return ident.replace(/./g, function (c, ii) {\n return shouldEscapeFirst && ii === 0 || !isCSSIdentChar(c) ? escapeAsciiChar(c, ii === lastIndex) : c;\n });\n }\n\n function escapeAsciiChar(c, isLast) {\n return "\\\\" + toHexByte(c) + (isLast ? "" : " ");\n }\n\n function toHexByte(c) {\n var hexByte = c.charCodeAt(0).toString(16);\n\n if (hexByte.length === 1) {\n hexByte = "0" + hexByte;\n }\n\n return hexByte;\n }\n\n function isCSSIdentChar(c) {\n if (/[a-zA-Z0-9_-]/.test(c)) {\n return true;\n }\n\n return c.charCodeAt(0) >= 0xa0;\n }\n\n function isCSSIdentifier(value) {\n return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n var element = node;\n var id = element.getAttribute("id");\n\n if (optimized) {\n if (id) {\n return {\n optimized: true,\n value: idSelector(id)\n };\n }\n\n if (lowerCaseName === "body" || lowerCaseName === "head" || lowerCaseName === "html") {\n return {\n optimized: true,\n value: lowerCaseName // node.nodeNameInCorrectCase(),\n\n };\n }\n }\n\n var nodeName = lowerCaseName; // node.nodeNameInCorrectCase();\n\n if (id) {\n return {\n optimized: true,\n value: nodeName + idSelector(id)\n };\n }\n\n var parent = node.parentNode;\n\n if (!parent || parent.nodeType === Node.DOCUMENT_NODE) {\n return {\n optimized: true,\n value: nodeName\n };\n }\n\n var prefixedOwnClassNamesArray_ = prefixedElementClassNames(element);\n var prefixedOwnClassNamesArray = []; // .keySet()\n\n prefixedOwnClassNamesArray_.forEach(function (arrItem) {\n if (prefixedOwnClassNamesArray.indexOf(arrItem) < 0) {\n prefixedOwnClassNamesArray.push(arrItem);\n }\n });\n var needsClassNames = false;\n var needsNthChild = false;\n var ownIndex = -1;\n var elementIndex = -1;\n var siblings = parent.children;\n\n var _loop2 = function _loop2(i) {\n var sibling = siblings[i];\n\n if (sibling.nodeType !== Node.ELEMENT_NODE) {\n return "continue";\n }\n\n elementIndex += 1;\n\n if (sibling === node) {\n ownIndex = elementIndex;\n return "continue";\n }\n\n if (needsNthChild) {\n return "continue";\n } // sibling.nodeNameInCorrectCase()\n\n\n var siblingName = sibling.localName && sibling.localName.toLowerCase() || sibling.nodeName.toLowerCase();\n\n if (siblingName !== nodeName) {\n return "continue";\n }\n\n needsClassNames = true;\n var ownClassNames = [];\n prefixedOwnClassNamesArray.forEach(function (arrItem) {\n ownClassNames.push(arrItem);\n });\n var ownClassNameCount = ownClassNames.length;\n\n if (ownClassNameCount === 0) {\n needsNthChild = true;\n return "continue";\n }\n\n var siblingClassNamesArray_ = prefixedElementClassNames(sibling);\n var siblingClassNamesArray = []; // .keySet()\n\n siblingClassNamesArray_.forEach(function (arrItem) {\n if (siblingClassNamesArray.indexOf(arrItem) < 0) {\n siblingClassNamesArray.push(arrItem);\n }\n });\n\n for (var _i3 = 0, _siblingClassNamesArr = siblingClassNamesArray; _i3 < _siblingClassNamesArr.length; _i3++) {\n var siblingClass = _siblingClassNamesArr[_i3];\n var ind = ownClassNames.indexOf(siblingClass);\n\n if (ind < 0) {\n continue;\n }\n\n ownClassNames.splice(ind, 1); // delete ownClassNames[siblingClass];\n\n if (! --ownClassNameCount) {\n needsNthChild = true;\n break;\n }\n }\n };\n\n for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {\n var _ret3 = _loop2(i);\n\n if (_ret3 === "continue") continue;\n }\n\n var result = nodeName;\n\n if (isTargetNode && nodeName === "input" && element.getAttribute("type") && !element.getAttribute("id") && !element.getAttribute("class")) {\n result += \'[type="\' + element.getAttribute("type") + \'"]\';\n }\n\n if (needsNthChild) {\n result += ":nth-child(" + (ownIndex + 1) + ")";\n } else if (needsClassNames) {\n var _iterator16 = highlight_createForOfIteratorHelper(prefixedOwnClassNamesArray),\n _step16;\n\n try {\n for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {\n var prefixedName = _step16.value;\n result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));\n }\n } catch (err) {\n _iterator16.e(err);\n } finally {\n _iterator16.f();\n }\n }\n\n return {\n optimized: false,\n value: result\n };\n}\n\nfunction computeCFI(node) {\n // TODO: handle character position inside text node\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var cfi = "";\n var currentElement = node;\n\n while (currentElement.parentNode && currentElement.parentNode.nodeType === Node.ELEMENT_NODE) {\n var blacklisted = checkBlacklisted(currentElement);\n\n if (!blacklisted) {\n var currentElementParentChildren = currentElement.parentNode.children;\n var currentElementIndex = -1;\n\n for (var i = 0; i < currentElementParentChildren.length; i++) {\n if (currentElement === currentElementParentChildren[i]) {\n currentElementIndex = i;\n break;\n }\n }\n\n if (currentElementIndex >= 0) {\n var cfiIndex = (currentElementIndex + 1) * 2;\n cfi = cfiIndex + (currentElement.id ? "[" + currentElement.id + "]" : "") + (cfi.length ? "/" + cfi : "");\n }\n }\n\n currentElement = currentElement.parentNode;\n }\n\n return "/" + cfi;\n}\n\nfunction _createHighlight(locations, color, pointerInteraction, type) {\n var rangeInfo = location2RangeInfo(locations);\n var uniqueStr = "".concat(rangeInfo.cfi).concat(rangeInfo.startContainerElementCssSelector).concat(rangeInfo.startContainerChildTextNodeIndex).concat(rangeInfo.startOffset).concat(rangeInfo.endContainerElementCssSelector).concat(rangeInfo.endContainerChildTextNodeIndex).concat(rangeInfo.endOffset);\n\n var hash = __webpack_require__(3715);\n\n var sha256Hex = hash.sha256().update(uniqueStr).digest("hex");\n var id;\n\n if (type == ID_HIGHLIGHTS_CONTAINER) {\n id = "R2_HIGHLIGHT_" + sha256Hex;\n } else {\n id = "R2_ANNOTATION_" + sha256Hex;\n }\n\n destroyHighlight(id);\n var highlight = {\n color: color ? color : DEFAULT_BACKGROUND_COLOR,\n id: id,\n pointerInteraction: pointerInteraction,\n rangeInfo: rangeInfo\n };\n\n _highlights.push(highlight);\n\n createHighlightDom(window, highlight, type == ID_ANNOTATION_CONTAINER ? true : false);\n return highlight;\n}\n\nfunction createHighlight(selectionInfo, color, pointerInteraction) {\n return _createHighlight(selectionInfo, color, pointerInteraction, ID_HIGHLIGHTS_CONTAINER);\n}\nfunction createAnnotation(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (i == _highlights.length) return;\n var locations = {\n locations: rangeInfo2Location(highlight.rangeInfo)\n };\n return _createHighlight(locations, highlight.color, true, ID_ANNOTATION_CONTAINER);\n}\n\nfunction createHighlightDom(win, highlight, annotationFlag) {\n var document = win.document;\n var scale = 1 / (win.READIUM2 && win.READIUM2.isFixedLayout ? win.READIUM2.fxlViewportScale : 1);\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var paginated = isPaginated(document);\n var highlightsContainer = ensureContainer(win, annotationFlag);\n var highlightParent = document.createElement("div");\n highlightParent.setAttribute("id", highlight.id);\n highlightParent.setAttribute("class", CLASS_HIGHLIGHT_CONTAINER);\n document.body.style.position = "relative";\n highlightParent.style.setProperty("pointer-events", "none");\n\n if (highlight.pointerInteraction) {\n highlightParent.setAttribute("data-click", "1");\n }\n\n var bodyRect = document.body.getBoundingClientRect();\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var highlightAreaSVGDocFrag;\n var roundedCorner = 3;\n var underlineThickness = 2;\n var strikeThroughLineThickness = 3;\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n var extra = "";\n var rangeAnnotationBoundingClientRect = frameForHighlightAnnotationMarkWithID(win, highlight.id);\n var xOffset;\n var yOffset;\n var annotationOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n annotationOffset = parseInt((rangeAnnotationBoundingClientRect.right - xOffset) / window.innerWidth) + 1;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n annotationOffset = parseInt(rangeAnnotationBoundingClientRect.right / window.innerWidth + 1);\n }\n\n var _iterator17 = highlight_createForOfIteratorHelper(clientRects),\n _step17;\n\n try {\n for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {\n var clientRect = _step17.value;\n\n if (useSVG) {\n var borderThickness = 0;\n\n if (!highlightAreaSVGDocFrag) {\n highlightAreaSVGDocFrag = document.createDocumentFragment();\n }\n\n var highlightAreaSVGRect = document.createElementNS(SVG_XML_NAMESPACE, "rect");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGRect.setAttribute("style", "fill: rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; fill-opacity: ").concat(opacity, " !important; stroke-width: 0;"));\n highlightAreaSVGRect.scale = scale;\n /*\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGRect.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaSVGRect.setAttribute("rx", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("ry", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("x", "".concat((highlightAreaSVGRect.rect.left - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("y", "".concat((highlightAreaSVGRect.rect.top - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("height", "".concat((highlightAreaSVGRect.rect.height + borderThickness * 2) * scale));\n highlightAreaSVGRect.setAttribute("width", "".concat((highlightAreaSVGRect.rect.width + borderThickness * 2) * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGRect);\n\n if (drawUnderline) {\n var highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGLine.setAttribute("style", "stroke-linecap: round; stroke-width: ".concat(underlineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n var lineOffset = highlightAreaSVGLine.rect.width > roundedCorner ? roundedCorner : 0;\n highlightAreaSVGLine.setAttribute("x1", "".concat((highlightAreaSVGLine.rect.left + lineOffset) * scale));\n highlightAreaSVGLine.setAttribute("x2", "".concat((highlightAreaSVGLine.rect.left + highlightAreaSVGLine.rect.width - lineOffset) * scale));\n var y = (highlightAreaSVGLine.rect.top + highlightAreaSVGLine.rect.height - underlineThickness / 2) * scale;\n highlightAreaSVGLine.setAttribute("y1", "".concat(y));\n highlightAreaSVGLine.setAttribute("y2", "".concat(y));\n highlightAreaSVGLine.setAttribute("height", "".concat(highlightAreaSVGLine.rect.height * scale));\n highlightAreaSVGLine.setAttribute("width", "".concat(highlightAreaSVGLine.rect.width * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGLine);\n }\n\n if (drawStrikeThrough) {\n var _highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n _highlightAreaSVGLine.setAttribute("style", "stroke-linecap: butt; stroke-width: ".concat(strikeThroughLineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n\n _highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n _highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n _highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n _highlightAreaSVGLine.setAttribute("x1", "".concat(_highlightAreaSVGLine.rect.left * scale));\n\n _highlightAreaSVGLine.setAttribute("x2", "".concat((_highlightAreaSVGLine.rect.left + _highlightAreaSVGLine.rect.width) * scale));\n\n var _lineOffset = _highlightAreaSVGLine.rect.height / 2;\n\n var _y = (_highlightAreaSVGLine.rect.top + _lineOffset) * scale;\n\n _highlightAreaSVGLine.setAttribute("y1", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("y2", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("height", "".concat(_highlightAreaSVGLine.rect.height * scale));\n\n _highlightAreaSVGLine.setAttribute("width", "".concat(_highlightAreaSVGLine.rect.width * scale));\n\n highlightAreaSVGDocFrag.appendChild(_highlightAreaSVGLine);\n }\n } else {\n var highlightArea = document.createElement("div");\n highlightArea.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n if (DEBUG_VISUALS) {\n var rgb = Math.round(0xffffff * Math.random());\n var r = rgb >> 16;\n var g = rgb >> 8 & 255;\n var b = rgb & 255;\n extra = "outline-color: rgb(".concat(r, ", ").concat(g, ", ").concat(b, "); outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n } else {\n if (drawUnderline) {\n extra += "border-bottom: ".concat(underlineThickness * scale, "px solid rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important");\n }\n }\n\n highlightArea.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n highlightArea.style.setProperty("pointer-events", "none");\n highlightArea.style.position = paginated ? "fixed" : "absolute";\n highlightArea.scale = scale;\n /*\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightArea.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightArea.style.width = "".concat(highlightArea.rect.width * scale, "px");\n highlightArea.style.height = "".concat(highlightArea.rect.height * scale, "px");\n highlightArea.style.left = "".concat(highlightArea.rect.left * scale, "px");\n highlightArea.style.top = "".concat(highlightArea.rect.top * scale, "px");\n highlightParent.append(highlightArea);\n\n if (!DEBUG_VISUALS && drawStrikeThrough) {\n //if (drawStrikeThrough) {\n var highlightAreaLine = document.createElement("div");\n highlightAreaLine.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaLine.setAttribute("style", "background-color: rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important;"));\n highlightAreaLine.style.setProperty("pointer-events", "none");\n highlightAreaLine.style.position = paginated ? "fixed" : "absolute";\n highlightAreaLine.scale = scale;\n /*\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaLine.style.width = "".concat(highlightAreaLine.rect.width * scale, "px");\n highlightAreaLine.style.height = "".concat(strikeThroughLineThickness * scale, "px");\n highlightAreaLine.style.left = "".concat(highlightAreaLine.rect.left * scale, "px");\n highlightAreaLine.style.top = "".concat((highlightAreaLine.rect.top + highlightAreaLine.rect.height / 2 - strikeThroughLineThickness / 2) * scale, "px");\n highlightParent.append(highlightAreaLine);\n }\n }\n\n if (annotationFlag) {\n break;\n }\n }\n } catch (err) {\n _iterator17.e(err);\n } finally {\n _iterator17.f();\n }\n\n if (useSVG && highlightAreaSVGDocFrag) {\n var highlightAreaSVG = document.createElementNS(SVG_XML_NAMESPACE, "svg");\n highlightAreaSVG.setAttribute("pointer-events", "none");\n highlightAreaSVG.style.position = paginated ? "fixed" : "absolute";\n highlightAreaSVG.style.overflow = "visible";\n highlightAreaSVG.style.left = "0";\n highlightAreaSVG.style.top = "0";\n highlightAreaSVG.append(highlightAreaSVGDocFrag);\n highlightParent.append(highlightAreaSVG);\n }\n\n var highlightBounding = document.createElement("div");\n\n if (annotationFlag) {\n highlightBounding.setAttribute("class", CLASS_ANNOTATION_BOUNDING_AREA);\n highlightBounding.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n } else {\n highlightBounding.setAttribute("class", CLASS_HIGHLIGHT_BOUNDING_AREA);\n }\n\n highlightBounding.style.setProperty("pointer-events", "none");\n highlightBounding.style.position = paginated ? "fixed" : "absolute";\n highlightBounding.scale = scale;\n\n if (DEBUG_VISUALS) {\n highlightBounding.setAttribute("style", "outline-color: magenta; outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n }\n\n if (annotationFlag) {\n highlightBounding.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n var rangeBoundingClientRect = range.getBoundingClientRect();\n highlightBounding.rect = {\n height: rangeBoundingClientRect.height,\n left: rangeBoundingClientRect.left - xOffset,\n top: rangeBoundingClientRect.top - yOffset,\n width: rangeBoundingClientRect.width\n };\n }\n\n highlightBounding.style.width = "".concat(highlightBounding.rect.width * scale, "px");\n highlightBounding.style.height = "".concat(highlightBounding.rect.height * scale, "px");\n highlightBounding.style.left = "".concat(highlightBounding.rect.left * scale, "px");\n highlightBounding.style.top = "".concat(highlightBounding.rect.top * scale, "px");\n highlightParent.append(highlightBounding);\n highlightsContainer.append(highlightParent);\n return highlightParent;\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n console.log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n console.log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n console.log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRange(range, getCssSelector, computeElementCFI) {\n var startIsElement = range.startContainer.nodeType === Node.ELEMENT_NODE;\n var startContainerElement = startIsElement ? range.startContainer : range.startContainer.parentNode && range.startContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.startContainer.parentNode : undefined;\n\n if (!startContainerElement) {\n return undefined;\n }\n\n var startContainerChildTextNodeIndex = startIsElement ? -1 : Array.from(startContainerElement.childNodes).indexOf(range.startContainer);\n\n if (startContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var startContainerElementCssSelector = getCssSelector(startContainerElement);\n var endIsElement = range.endContainer.nodeType === Node.ELEMENT_NODE;\n var endContainerElement = endIsElement ? range.endContainer : range.endContainer.parentNode && range.endContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.endContainer.parentNode : undefined;\n\n if (!endContainerElement) {\n return undefined;\n }\n\n var endContainerChildTextNodeIndex = endIsElement ? -1 : Array.from(endContainerElement.childNodes).indexOf(range.endContainer);\n\n if (endContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var endContainerElementCssSelector = getCssSelector(endContainerElement);\n var commonElementAncestor = getCommonAncestorElement(range.startContainer, range.endContainer);\n\n if (!commonElementAncestor) {\n console.log("^^^ NO RANGE COMMON ANCESTOR?!");\n return undefined;\n }\n\n if (range.commonAncestorContainer) {\n var rangeCommonAncestorElement = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? range.commonAncestorContainer : range.commonAncestorContainer.parentNode;\n\n if (rangeCommonAncestorElement && rangeCommonAncestorElement.nodeType === Node.ELEMENT_NODE) {\n if (commonElementAncestor !== rangeCommonAncestorElement) {\n console.log(">>>>>> COMMON ANCESTOR CONTAINER DIFF??!");\n console.log(getCssSelector(commonElementAncestor));\n console.log(getCssSelector(rangeCommonAncestorElement));\n }\n }\n }\n\n var rootElementCfi = computeElementCFI(commonElementAncestor);\n var startElementCfi = computeElementCFI(startContainerElement);\n var endElementCfi = computeElementCFI(endContainerElement);\n var cfi;\n\n if (rootElementCfi && startElementCfi && endElementCfi) {\n var startElementOrTextCfi = startElementCfi;\n\n if (!startIsElement) {\n var startContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(startContainerElement, range.startContainer);\n startElementOrTextCfi = startElementCfi + "/" + startContainerChildTextNodeIndexForCfi + ":" + range.startOffset;\n } else {\n if (range.startOffset >= 0 && range.startOffset < startContainerElement.childNodes.length) {\n var childNode = startContainerElement.childNodes[range.startOffset];\n\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (range.startOffset + 1) * 2;\n } else {\n var cfiTextNodeIndex = getChildTextNodeCfiIndex(startContainerElement, childNode);\n startElementOrTextCfi = startElementCfi + "/" + cfiTextNodeIndex;\n }\n } else {\n var cfiIndexOfLastElement = startContainerElement.childElementCount * 2;\n var lastChildNode = startContainerElement.childNodes[startContainerElement.childNodes.length - 1];\n\n if (lastChildNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 1);\n } else {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 2);\n }\n }\n }\n\n var endElementOrTextCfi = endElementCfi;\n\n if (!endIsElement) {\n var endContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(endContainerElement, range.endContainer);\n endElementOrTextCfi = endElementCfi + "/" + endContainerChildTextNodeIndexForCfi + ":" + range.endOffset;\n } else {\n if (range.endOffset >= 0 && range.endOffset < endContainerElement.childNodes.length) {\n var _childNode = endContainerElement.childNodes[range.endOffset];\n\n if (_childNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (range.endOffset + 1) * 2;\n } else {\n var _cfiTextNodeIndex = getChildTextNodeCfiIndex(endContainerElement, _childNode);\n\n endElementOrTextCfi = endElementCfi + "/" + _cfiTextNodeIndex;\n }\n } else {\n var _cfiIndexOfLastElement = endContainerElement.childElementCount * 2;\n\n var _lastChildNode = endContainerElement.childNodes[endContainerElement.childNodes.length - 1];\n\n if (_lastChildNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 1);\n } else {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 2);\n }\n }\n }\n\n cfi = rootElementCfi + "," + startElementOrTextCfi.replace(rootElementCfi, "") + "," + endElementOrTextCfi.replace(rootElementCfi, "");\n }\n\n return {\n cfi: cfi,\n endContainerChildTextNodeIndex: endContainerChildTextNodeIndex,\n endContainerElementCssSelector: endContainerElementCssSelector,\n endOffset: range.endOffset,\n startContainerChildTextNodeIndex: startContainerChildTextNodeIndex,\n startContainerElementCssSelector: startContainerElementCssSelector,\n startOffset: range.startOffset\n };\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n console.log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n console.log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\n\nfunction frameForHighlightAnnotationMarkWithID(win, id) {\n var clientRects = frameForHighlightWithID(id);\n if (!clientRects) return;\n var topClientRect = clientRects[0];\n var maxHeight = topClientRect.height;\n\n var _iterator18 = highlight_createForOfIteratorHelper(clientRects),\n _step18;\n\n try {\n for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {\n var clientRect = _step18.value;\n if (clientRect.top < topClientRect.top) topClientRect = clientRect;\n if (clientRect.height > maxHeight) maxHeight = clientRect.height;\n }\n } catch (err) {\n _iterator18.e(err);\n } finally {\n _iterator18.f();\n }\n\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var newTop = topClientRect.top;\n\n if (_highlightsContainer) {\n do {\n var boundingAreas = document.getElementsByClassName(CLASS_ANNOTATION_BOUNDING_AREA);\n var found = false; //for (let i = 0, length = boundingAreas.snapshotLength; i < length; ++i) {\n\n for (var i = 0, len = boundingAreas.length | 0; i < len; i = i + 1 | 0) {\n var boundingArea = boundingAreas[i];\n\n if (Math.abs(boundingArea.rect.top - (newTop - yOffset)) < 3) {\n newTop += boundingArea.rect.height;\n found = true;\n break;\n }\n }\n } while (found);\n }\n\n topClientRect.top = newTop;\n topClientRect.height = maxHeight;\n return topClientRect;\n}\n\nfunction highlightWithID(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n return highlight;\n}\n\nfunction frameForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n return clientRects;\n}\n\nfunction rangeInfo2Location(rangeInfo) {\n return {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n partialCfi: rangeInfo.cfi,\n domRange: {\n start: {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n textNodeIndex: rangeInfo.startContainerChildTextNodeIndex,\n offset: rangeInfo.startOffset\n },\n end: {\n cssSelector: rangeInfo.endContainerElementCssSelector,\n textNodeIndex: rangeInfo.endContainerChildTextNodeIndex,\n offset: rangeInfo.endOffset\n }\n }\n };\n}\n\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n cfi: location.partialCfi,\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction rectangleForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRects[0].left,\n width: clientRects[0].width,\n top: clientRects[0].top,\n height: clientRects[0].height\n };\n return size;\n}\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n var clientRect = range.getBoundingClientRect();\n var handleBounds = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRect.left,\n width: clientRect.width,\n top: clientRect.top,\n height: clientRect.height\n };\n return handleBounds;\n } catch (e) {\n return null;\n }\n}\nfunction setScrollMode(flag) {\n if (!flag) {\n document.documentElement.classList.add(CLASS_PAGINATED);\n } else {\n document.documentElement.classList.remove(CLASS_PAGINATED);\n }\n}\n/*\n if (document.addEventListener) { // IE >= 9; other browsers\n document.addEventListener(\'contextmenu\', function(e) {\n //alert("You\'ve tried to open context menu"); //here you draw your own menu\n //e.preventDefault();\n //let getCssSelector = fullQualifiedSelector;\n \n\t\t\tlet str = window.getSelection();\n\t\t\tlet selectionInfo = getCurrentSelectionInfo();\n\t\t\tlet pos = createHighlight(selectionInfo,{red:10,green:50,blue:230},true);\n\t\t\tlet ret2 = createAnnotation(pos.id);\n\t\t\t\n }, false);\n } else { // IE < 9\n document.attachEvent(\'oncontextmenu\', function() {\n alert("You\'ve tried to open context menu");\n window.event.returnValue = false;\n });\n }\n*/\n// EXTERNAL MODULE: ./node_modules/css-selector-generator/build/index.js\nvar build = __webpack_require__(4766);\n;// CONCATENATED MODULE: ./src/dom.js\n//\n// Copyright 2022 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = selection_getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction selection_getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : selection_createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction selection_createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction selection_convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return selection_createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction selection_location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n}; // Legacy highlights API.\n\nwindow.createAnnotation = createAnnotation;\nwindow.createHighlight = createHighlight;\nwindow.destroyHighlight = destroyHighlight;\nwindow.getCurrentSelectionInfo = getCurrentSelectionInfo;\nwindow.getSelectionRect = getSelectionRect;\nwindow.rectangleForHighlightWithID = rectangleForHighlightWithID;\nwindow.setScrollMode = setScrollMode;\n;// CONCATENATED MODULE: ./src/index-fixed.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for fixed layouts resources.\n\nwindow.readium.isFixedLayout = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q0FBQzRZLGdCQUFQLEdBQTBCQSxnQkFBMUI7QUFDQTVZLE1BQU0sQ0FBQ21hLHVCQUFQLEdBQWlDQSx1QkFBakM7QUFDQW5hLE1BQU0sQ0FBQ29rQixnQkFBUCxHQUEwQkEsZ0JBQTFCO0FBQ0Fwa0IsTUFBTSxDQUFDbWtCLDJCQUFQLEdBQXFDQSwyQkFBckM7QUFDQW5rQixNQUFNLENBQUN1a0IsYUFBUCxHQUF1QkEsYUFBdkIsQzs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQXZrQixNQUFNLENBQUMra0IsT0FBUCxDQUFlM0UsYUFBZixHQUErQixJQUEvQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL21hdGNoLXF1b3RlLmpzP2RkNmEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZS5qcz9mZGVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzLmpzPzQwMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy91dGlscy5qcz8wMjVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvcmVjdC5qcz80ZDVhIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZGVjb3JhdG9yLmpzPzFiMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9nZXN0dXJlcy5qcz8xNGMyIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaGlnaGxpZ2h0LmpzPzhkYTgiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kb20uanM/Y2JmMCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL3NlbGVjdGlvbi5qcz81OWFjIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaW5kZXguanM/YjYzNSIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LWZpeGVkLmpzP2Q5OWYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFwcHJveFNlYXJjaCBmcm9tICdhcHByb3gtc3RyaW5nLW1hdGNoJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHByb3gtc3RyaW5nLW1hdGNoJykuTWF0Y2h9IFN0cmluZ01hdGNoXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBNYXRjaFxuICogQHByb3Age251bWJlcn0gc3RhcnQgLSBTdGFydCBvZmZzZXQgb2YgbWF0Y2ggaW4gdGV4dFxuICogQHByb3Age251bWJlcn0gZW5kIC0gRW5kIG9mZnNldCBvZiBtYXRjaCBpbiB0ZXh0XG4gKiBAcHJvcCB7bnVtYmVyfSBzY29yZSAtXG4gKiAgIFNjb3JlIGZvciB0aGUgbWF0Y2ggYmV0d2VlbiAwIGFuZCAxLjAsIHdoZXJlIDEuMCBpbmRpY2F0ZXMgYSBwZXJmZWN0IG1hdGNoXG4gKiAgIGZvciB0aGUgcXVvdGUgYW5kIGNvbnRleHQuXG4gKi9cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoZXMgZm9yIGBzdHJgIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhFcnJvcnNcbiAqIEByZXR1cm4ge1N0cmluZ01hdGNoW119XG4gKi9cbmZ1bmN0aW9uIHNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycykge1xuICAvLyBEbyBhIGZhc3Qgc2VhcmNoIGZvciBleGFjdCBtYXRjaGVzLiBUaGUgYGFwcHJveC1zdHJpbmctbWF0Y2hgIGxpYnJhcnlcbiAgLy8gZG9lc24ndCBjdXJyZW50bHkgaW5jb3Jwb3JhdGUgdGhpcyBvcHRpbWl6YXRpb24gaXRzZWxmLlxuICBsZXQgbWF0Y2hQb3MgPSAwO1xuICBsZXQgZXhhY3RNYXRjaGVzID0gW107XG4gIHdoaWxlIChtYXRjaFBvcyAhPT0gLTEpIHtcbiAgICBtYXRjaFBvcyA9IHRleHQuaW5kZXhPZihzdHIsIG1hdGNoUG9zKTtcbiAgICBpZiAobWF0Y2hQb3MgIT09IC0xKSB7XG4gICAgICBleGFjdE1hdGNoZXMucHVzaCh7XG4gICAgICAgIHN0YXJ0OiBtYXRjaFBvcyxcbiAgICAgICAgZW5kOiBtYXRjaFBvcyArIHN0ci5sZW5ndGgsXG4gICAgICAgIGVycm9yczogMCxcbiAgICAgIH0pO1xuICAgICAgbWF0Y2hQb3MgKz0gMTtcbiAgICB9XG4gIH1cbiAgaWYgKGV4YWN0TWF0Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGV4YWN0TWF0Y2hlcztcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBubyBleGFjdCBtYXRjaGVzLCBkbyBhIG1vcmUgZXhwZW5zaXZlIHNlYXJjaCBmb3IgbWF0Y2hlc1xuICAvLyB3aXRoIGVycm9ycy5cbiAgcmV0dXJuIGFwcHJveFNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycyk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSBhIHNjb3JlIGJldHdlZW4gMCBhbmQgMS4wIGZvciB0aGUgc2ltaWxhcml0eSBiZXR3ZWVuIGB0ZXh0YCBhbmQgYHN0cmAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqL1xuZnVuY3Rpb24gdGV4dE1hdGNoU2NvcmUodGV4dCwgc3RyKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0IC0gYHNjb3JlTWF0Y2hgIHdpbGwgbmV2ZXIgcGFzcyBhbiBlbXB0eSBzdHJpbmcgKi9cbiAgaWYgKHN0ci5sZW5ndGggPT09IDAgfHwgdGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gMC4wO1xuICB9XG4gIGNvbnN0IG1hdGNoZXMgPSBzZWFyY2godGV4dCwgc3RyLCBzdHIubGVuZ3RoKTtcblxuICAvLyBwcmV0dGllci1pZ25vcmVcbiAgcmV0dXJuIDEgLSAobWF0Y2hlc1swXS5lcnJvcnMgLyBzdHIubGVuZ3RoKTtcbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoIGZvciBgcXVvdGVgIGluIGB0ZXh0YC5cbiAqXG4gKiBSZXR1cm5zIGBudWxsYCBpZiBubyBtYXRjaCBleGNlZWRpbmcgdGhlIG1pbmltdW0gcXVhbGl0eSB0aHJlc2hvbGQgd2FzIGZvdW5kLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gRG9jdW1lbnQgdGV4dCB0byBzZWFyY2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBxdW90ZSAtIFN0cmluZyB0byBmaW5kIHdpdGhpbiBgdGV4dGBcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC1cbiAqICAgQ29udGV4dCBpbiB3aGljaCB0aGUgcXVvdGUgb3JpZ2luYWxseSBhcHBlYXJlZC4gVGhpcyBpcyB1c2VkIHRvIGNob29zZSB0aGVcbiAqICAgYmVzdCBtYXRjaC5cbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnByZWZpeF0gLSBFeHBlY3RlZCB0ZXh0IGJlZm9yZSB0aGUgcXVvdGVcbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnN1ZmZpeF0gLSBFeHBlY3RlZCB0ZXh0IGFmdGVyIHRoZSBxdW90ZVxuICogICBAcGFyYW0ge251bWJlcn0gW2NvbnRleHQuaGludF0gLSBFeHBlY3RlZCBvZmZzZXQgb2YgbWF0Y2ggd2l0aGluIHRleHRcbiAqIEByZXR1cm4ge01hdGNofG51bGx9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaFF1b3RlKHRleHQsIHF1b3RlLCBjb250ZXh0ID0ge30pIHtcbiAgaWYgKHF1b3RlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQ2hvb3NlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBlcnJvcnMgdG8gYWxsb3cgZm9yIHRoZSBpbml0aWFsIHNlYXJjaC5cbiAgLy8gVGhpcyBjaG9pY2UgaW52b2x2ZXMgYSB0cmFkZW9mZiBiZXR3ZWVuOlxuICAvL1xuICAvLyAgLSBSZWNhbGwgKHByb3BvcnRpb24gb2YgXCJnb29kXCIgbWF0Y2hlcyBmb3VuZClcbiAgLy8gIC0gUHJlY2lzaW9uIChwcm9wb3J0aW9uIG9mIG1hdGNoZXMgZm91bmQgd2hpY2ggYXJlIFwiZ29vZFwiKVxuICAvLyAgLSBDb3N0IG9mIHRoZSBpbml0aWFsIHNlYXJjaCBhbmQgb2YgcHJvY2Vzc2luZyB0aGUgY2FuZGlkYXRlIG1hdGNoZXMgWzFdXG4gIC8vXG4gIC8vIFsxXSBTcGVjaWZpY2FsbHksIHRoZSBleHBlY3RlZC10aW1lIGNvbXBsZXhpdHkgb2YgdGhlIGluaXRpYWwgc2VhcmNoIGlzXG4gIC8vICAgICBgTygobWF4RXJyb3JzIC8gMzIpICogdGV4dC5sZW5ndGgpYC4gU2VlIGBhcHByb3gtc3RyaW5nLW1hdGNoYCBkb2NzLlxuICBjb25zdCBtYXhFcnJvcnMgPSBNYXRoLm1pbigyNTYsIHF1b3RlLmxlbmd0aCAvIDIpO1xuXG4gIC8vIEZpbmQgY2xvc2VzdCBtYXRjaGVzIGZvciBgcXVvdGVgIGluIGB0ZXh0YCBiYXNlZCBvbiBlZGl0IGRpc3RhbmNlLlxuICBjb25zdCBtYXRjaGVzID0gc2VhcmNoKHRleHQsIHF1b3RlLCBtYXhFcnJvcnMpO1xuXG4gIGlmIChtYXRjaGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEuMCBmb3IgYSBtYXRjaCBjYW5kaWRhdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nTWF0Y2h9IG1hdGNoXG4gICAqL1xuICBjb25zdCBzY29yZU1hdGNoID0gbWF0Y2ggPT4ge1xuICAgIGNvbnN0IHF1b3RlV2VpZ2h0ID0gNTA7IC8vIFNpbWlsYXJpdHkgb2YgbWF0Y2hlZCB0ZXh0IHRvIHF1b3RlLlxuICAgIGNvbnN0IHByZWZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYmVmb3JlIG1hdGNoZWQgdGV4dCB0byBgY29udGV4dC5wcmVmaXhgLlxuICAgIGNvbnN0IHN1ZmZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYWZ0ZXIgbWF0Y2hlZCB0ZXh0IHRvIGBjb250ZXh0LnN1ZmZpeGAuXG4gICAgY29uc3QgcG9zV2VpZ2h0ID0gMjsgLy8gUHJveGltaXR5IHRvIGV4cGVjdGVkIGxvY2F0aW9uLiBVc2VkIGFzIGEgdGllLWJyZWFrZXIuXG5cbiAgICBjb25zdCBxdW90ZVNjb3JlID0gMSAtIG1hdGNoLmVycm9ycyAvIHF1b3RlLmxlbmd0aDtcblxuICAgIGNvbnN0IHByZWZpeFNjb3JlID0gY29udGV4dC5wcmVmaXhcbiAgICAgID8gdGV4dE1hdGNoU2NvcmUoXG4gICAgICAgICAgdGV4dC5zbGljZShNYXRoLm1heCgwLCBtYXRjaC5zdGFydCAtIGNvbnRleHQucHJlZml4Lmxlbmd0aCksIG1hdGNoLnN0YXJ0KSxcbiAgICAgICAgICBjb250ZXh0LnByZWZpeFxuICAgICAgICApXG4gICAgICA6IDEuMDtcbiAgICBjb25zdCBzdWZmaXhTY29yZSA9IGNvbnRleHQuc3VmZml4XG4gICAgICA/IHRleHRNYXRjaFNjb3JlKFxuICAgICAgICAgIHRleHQuc2xpY2UobWF0Y2guZW5kLCBtYXRjaC5lbmQgKyBjb250ZXh0LnN1ZmZpeC5sZW5ndGgpLFxuICAgICAgICAgIGNvbnRleHQuc3VmZml4XG4gICAgICAgIClcbiAgICAgIDogMS4wO1xuXG4gICAgbGV0IHBvc1Njb3JlID0gMS4wO1xuICAgIGlmICh0eXBlb2YgY29udGV4dC5oaW50ID09PSAnbnVtYmVyJykge1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5hYnMobWF0Y2guc3RhcnQgLSBjb250ZXh0LmhpbnQpO1xuICAgICAgcG9zU2NvcmUgPSAxLjAgLSBvZmZzZXQgLyB0ZXh0Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBjb25zdCByYXdTY29yZSA9XG4gICAgICBxdW90ZVdlaWdodCAqIHF1b3RlU2NvcmUgK1xuICAgICAgcHJlZml4V2VpZ2h0ICogcHJlZml4U2NvcmUgK1xuICAgICAgc3VmZml4V2VpZ2h0ICogc3VmZml4U2NvcmUgK1xuICAgICAgcG9zV2VpZ2h0ICogcG9zU2NvcmU7XG4gICAgY29uc3QgbWF4U2NvcmUgPSBxdW90ZVdlaWdodCArIHByZWZpeFdlaWdodCArIHN1ZmZpeFdlaWdodCArIHBvc1dlaWdodDtcbiAgICBjb25zdCBub3JtYWxpemVkU2NvcmUgPSByYXdTY29yZSAvIG1heFNjb3JlO1xuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRTY29yZTtcbiAgfTtcblxuICAvLyBSYW5rIG1hdGNoZXMgYmFzZWQgb24gc2ltaWxhcml0eSBvZiBhY3R1YWwgYW5kIGV4cGVjdGVkIHN1cnJvdW5kaW5nIHRleHRcbiAgLy8gYW5kIGFjdHVhbC9leHBlY3RlZCBvZmZzZXQgaW4gdGhlIGRvY3VtZW50IHRleHQuXG4gIGNvbnN0IHNjb3JlZE1hdGNoZXMgPSBtYXRjaGVzLm1hcChtID0+ICh7XG4gICAgc3RhcnQ6IG0uc3RhcnQsXG4gICAgZW5kOiBtLmVuZCxcbiAgICBzY29yZTogc2NvcmVNYXRjaChtKSxcbiAgfSkpO1xuXG4gIC8vIENob29zZSBtYXRjaCB3aXRoIGhpZ2hlc3Qgc2NvcmUuXG4gIHNjb3JlZE1hdGNoZXMuc29ydCgoYSwgYikgPT4gYi5zY29yZSAtIGEuc2NvcmUpO1xuICByZXR1cm4gc2NvcmVkTWF0Y2hlc1swXTtcbn1cbiIsIi8qKlxuICogUmV0dXJuIHRoZSBjb21iaW5lZCBsZW5ndGggb2YgdGV4dCBub2RlcyBjb250YWluZWQgaW4gYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICovXG5mdW5jdGlvbiBub2RlVGV4dExlbmd0aChub2RlKSB7XG4gIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgIC8vIG5iLiBgdGV4dENvbnRlbnRgIGV4Y2x1ZGVzIHRleHQgaW4gY29tbWVudHMgYW5kIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zXG4gICAgICAvLyB3aGVuIGNhbGxlZCBvbiBhIHBhcmVudCBlbGVtZW50LCBzbyB3ZSBkb24ndCBuZWVkIHRvIHN1YnRyYWN0IHRoYXQgaGVyZS5cblxuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobm9kZS50ZXh0Q29udGVudCkubGVuZ3RoO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gMDtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgdG90YWwgbGVuZ3RoIG9mIHRoZSB0ZXh0IG9mIGFsbCBwcmV2aW91cyBzaWJsaW5ncyBvZiBgbm9kZWAuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKi9cbmZ1bmN0aW9uIHByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoKG5vZGUpIHtcbiAgbGV0IHNpYmxpbmcgPSBub2RlLnByZXZpb3VzU2libGluZztcbiAgbGV0IGxlbmd0aCA9IDA7XG4gIHdoaWxlIChzaWJsaW5nKSB7XG4gICAgbGVuZ3RoICs9IG5vZGVUZXh0TGVuZ3RoKHNpYmxpbmcpO1xuICAgIHNpYmxpbmcgPSBzaWJsaW5nLnByZXZpb3VzU2libGluZztcbiAgfVxuICByZXR1cm4gbGVuZ3RoO1xufVxuXG4vKipcbiAqIFJlc29sdmUgb25lIG9yIG1vcmUgY2hhcmFjdGVyIG9mZnNldHMgd2l0aGluIGFuIGVsZW1lbnQgdG8gKHRleHQgbm9kZSwgcG9zaXRpb24pXG4gKiBwYWlycy5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyW119IG9mZnNldHMgLSBPZmZzZXRzLCB3aGljaCBtdXN0IGJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXJcbiAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfVtdfVxuICovXG5mdW5jdGlvbiByZXNvbHZlT2Zmc2V0cyhlbGVtZW50LCAuLi5vZmZzZXRzKSB7XG4gIGxldCBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICBjb25zdCBub2RlSXRlciA9IC8qKiBAdHlwZSB7RG9jdW1lbnR9ICovIChcbiAgICBlbGVtZW50Lm93bmVyRG9jdW1lbnRcbiAgKS5jcmVhdGVOb2RlSXRlcmF0b3IoZWxlbWVudCwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuICBjb25zdCByZXN1bHRzID0gW107XG5cbiAgbGV0IGN1cnJlbnROb2RlID0gbm9kZUl0ZXIubmV4dE5vZGUoKTtcbiAgbGV0IHRleHROb2RlO1xuICBsZXQgbGVuZ3RoID0gMDtcblxuICAvLyBGaW5kIHRoZSB0ZXh0IG5vZGUgY29udGFpbmluZyB0aGUgYG5leHRPZmZzZXRgdGggY2hhcmFjdGVyIGZyb20gdGhlIHN0YXJ0XG4gIC8vIG9mIGBlbGVtZW50YC5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50Tm9kZSkge1xuICAgIHRleHROb2RlID0gLyoqIEB0eXBlIHtUZXh0fSAqLyAoY3VycmVudE5vZGUpO1xuICAgIGlmIChsZW5ndGggKyB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCA+IG5leHRPZmZzZXQpIHtcbiAgICAgIHJlc3VsdHMucHVzaCh7IG5vZGU6IHRleHROb2RlLCBvZmZzZXQ6IG5leHRPZmZzZXQgLSBsZW5ndGggfSk7XG4gICAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IG5vZGVJdGVyLm5leHROb2RlKCk7XG4gICAgICBsZW5ndGggKz0gdGV4dE5vZGUuZGF0YS5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgLy8gQm91bmRhcnkgY2FzZS5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiB0ZXh0Tm9kZSAmJiBsZW5ndGggPT09IG5leHRPZmZzZXQpIHtcbiAgICByZXN1bHRzLnB1c2goeyBub2RlOiB0ZXh0Tm9kZSwgb2Zmc2V0OiB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCB9KTtcbiAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICB9XG5cbiAgaWYgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPZmZzZXQgZXhjZWVkcyB0ZXh0IGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmV4cG9ydCBsZXQgUkVTT0xWRV9GT1JXQVJEUyA9IDE7XG5leHBvcnQgbGV0IFJFU09MVkVfQkFDS1dBUkRTID0gMjtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIG9mZnNldCB3aXRoaW4gdGhlIHRleHQgY29udGVudCBvZiBhbiBlbGVtZW50LlxuICpcbiAqIFRoaXMgcG9zaXRpb24gY2FuIGJlIHJlc29sdmVkIHRvIGEgc3BlY2lmaWMgZGVzY2VuZGFudCBub2RlIGluIHRoZSBjdXJyZW50XG4gKiBET00gc3VidHJlZSBvZiB0aGUgZWxlbWVudCB1c2luZyB0aGUgYHJlc29sdmVgIG1ldGhvZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbiB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgdGV4dCBwb3NpdGlvbiBgb2Zmc2V0YCB3aXRoaW5cbiAgICogdGhlIHRleHQgY29udGVudCBvZiBgZWxlbWVudGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvZmZzZXQpIHtcbiAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPZmZzZXQgaXMgaW52YWxpZCcpO1xuICAgIH1cblxuICAgIC8qKiBFbGVtZW50IHRoYXQgYG9mZnNldGAgaXMgcmVsYXRpdmUgdG8uICovXG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIC8qKiBDaGFyYWN0ZXIgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBlbGVtZW50J3MgYHRleHRDb250ZW50YC4gKi9cbiAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgcG9zaXRpb24gd2l0aCBvZmZzZXQgcmVsYXRpdmUgdG8gYSBnaXZlbiBhbmNlc3RvclxuICAgKiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHBhcmVudCAtIEFuY2VzdG9yIG9mIGB0aGlzLmVsZW1lbnRgXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHJlbGF0aXZlVG8ocGFyZW50KSB7XG4gICAgaWYgKCFwYXJlbnQuY29udGFpbnModGhpcy5lbGVtZW50KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJlbnQgaXMgbm90IGFuIGFuY2VzdG9yIG9mIGN1cnJlbnQgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIGxldCBlbCA9IHRoaXMuZWxlbWVudDtcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgd2hpbGUgKGVsICE9PSBwYXJlbnQpIHtcbiAgICAgIG9mZnNldCArPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChlbCk7XG4gICAgICBlbCA9IC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKGVsLnBhcmVudEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKGVsLCBvZmZzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIHBvc2l0aW9uIHRvIGEgc3BlY2lmaWMgdGV4dCBub2RlIGFuZCBvZmZzZXQgd2l0aGluIHRoYXQgbm9kZS5cbiAgICpcbiAgICogVGhyb3dzIGlmIGB0aGlzLm9mZnNldGAgZXhjZWVkcyB0aGUgbGVuZ3RoIG9mIHRoZSBlbGVtZW50J3MgdGV4dC4gSW4gdGhlXG4gICAqIGNhc2Ugd2hlcmUgdGhlIGVsZW1lbnQgaGFzIG5vIHRleHQgYW5kIGB0aGlzLm9mZnNldGAgaXMgMCwgdGhlIGBkaXJlY3Rpb25gXG4gICAqIG9wdGlvbiBkZXRlcm1pbmVzIHdoYXQgaGFwcGVucy5cbiAgICpcbiAgICogT2Zmc2V0cyBhdCB0aGUgYm91bmRhcnkgYmV0d2VlbiB0d28gbm9kZXMgYXJlIHJlc29sdmVkIHRvIHRoZSBzdGFydCBvZiB0aGVcbiAgICogbm9kZSB0aGF0IGJlZ2lucyBhdCB0aGUgYm91bmRhcnkuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBAcGFyYW0ge1JFU09MVkVfRk9SV0FSRFN8UkVTT0xWRV9CQUNLV0FSRFN9IFtvcHRpb25zLmRpcmVjdGlvbl0gLVxuICAgKiAgICAgU3BlY2lmaWVzIGluIHdoaWNoIGRpcmVjdGlvbiB0byBzZWFyY2ggZm9yIHRoZSBuZWFyZXN0IHRleHQgbm9kZSBpZlxuICAgKiAgICAgYHRoaXMub2Zmc2V0YCBpcyBgMGAgYW5kIGB0aGlzLmVsZW1lbnRgIGhhcyBubyB0ZXh0LiBJZiBub3Qgc3BlY2lmaWVkXG4gICAqICAgICBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfX1cbiAgICogQHRocm93cyB7UmFuZ2VFcnJvcn1cbiAgICovXG4gIHJlc29sdmUob3B0aW9ucyA9IHt9KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiByZXNvbHZlT2Zmc2V0cyh0aGlzLmVsZW1lbnQsIHRoaXMub2Zmc2V0KVswXTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmICh0aGlzLm9mZnNldCA9PT0gMCAmJiBvcHRpb25zLmRpcmVjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHR3ID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVFxuICAgICAgICApO1xuICAgICAgICB0dy5jdXJyZW50Tm9kZSA9IHRoaXMuZWxlbWVudDtcbiAgICAgICAgY29uc3QgZm9yd2FyZHMgPSBvcHRpb25zLmRpcmVjdGlvbiA9PT0gUkVTT0xWRV9GT1JXQVJEUztcbiAgICAgICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7VGV4dHxudWxsfSAqLyAoXG4gICAgICAgICAgZm9yd2FyZHMgPyB0dy5uZXh0Tm9kZSgpIDogdHcucHJldmlvdXNOb2RlKClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHRleHQsIG9mZnNldDogZm9yd2FyZHMgPyAwIDogdGV4dC5kYXRhLmxlbmd0aCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgYG9mZnNldGB0aCBjaGFyYWN0ZXIgd2l0aGluXG4gICAqIGBub2RlYC5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7VGV4dFBvc2l0aW9ufVxuICAgKi9cbiAgc3RhdGljIGZyb21DaGFyT2Zmc2V0KG5vZGUsIG9mZnNldCkge1xuICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgICAgcmV0dXJuIFRleHRQb3NpdGlvbi5mcm9tUG9pbnQobm9kZSwgb2Zmc2V0KTtcbiAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCBvZmZzZXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb2RlIGlzIG5vdCBhbiBlbGVtZW50IG9yIHRleHQgbm9kZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCByZXByZXNlbnRpbmcgdGhlIHJhbmdlIHN0YXJ0IG9yIGVuZCBwb2ludCAobm9kZSwgb2Zmc2V0KS5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlIC0gVGV4dCBvciBFbGVtZW50IG5vZGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCAtIE9mZnNldCB3aXRoaW4gdGhlIG5vZGUuXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tUG9pbnQobm9kZSwgb2Zmc2V0KSB7XG4gICAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7XG4gICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOiB7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IC8qKiBAdHlwZSB7VGV4dH0gKi8gKG5vZGUpLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IG5vZGUgb2Zmc2V0IGlzIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFub2RlLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RleHQgbm9kZSBoYXMgbm8gcGFyZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcGFyZW50IGVsZW1lbnQuXG4gICAgICAgIGNvbnN0IHRleHRPZmZzZXQgPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChub2RlKSArIG9mZnNldDtcblxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbihub2RlLnBhcmVudEVsZW1lbnQsIHRleHRPZmZzZXQpO1xuICAgICAgfVxuICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERToge1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBub2RlIG9mZnNldCBpcyBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgdGV4dCBsZW5ndGggYmVmb3JlIHRoZSBgb2Zmc2V0YHRoIGNoaWxkIG9mIGVsZW1lbnQuXG4gICAgICAgIGxldCB0ZXh0T2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvZmZzZXQ7IGkrKykge1xuICAgICAgICAgIHRleHRPZmZzZXQgKz0gbm9kZVRleHRMZW5ndGgobm9kZS5jaGlsZE5vZGVzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCB0ZXh0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUG9pbnQgaXMgbm90IGluIGFuIGVsZW1lbnQgb3IgdGV4dCBub2RlJyk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHJlZ2lvbiBvZiBhIGRvY3VtZW50IGFzIGEgKHN0YXJ0LCBlbmQpIHBhaXIgb2YgYFRleHRQb3NpdGlvbmAgcG9pbnRzLlxuICpcbiAqIFJlcHJlc2VudGluZyBhIHJhbmdlIGluIHRoaXMgd2F5IGFsbG93cyBmb3IgY2hhbmdlcyBpbiB0aGUgRE9NIGNvbnRlbnQgb2YgdGhlXG4gKiByYW5nZSB3aGljaCBkb24ndCBhZmZlY3QgaXRzIHRleHQgY29udGVudCwgd2l0aG91dCBhZmZlY3RpbmcgdGhlIHRleHQgY29udGVudFxuICogb2YgdGhlIHJhbmdlIGl0c2VsZi5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRSYW5nZSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYW4gaW1tdXRhYmxlIGBUZXh0UmFuZ2VgIGZyb20gYSBgc3RhcnRgIGFuZCBgZW5kYCBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb259IHN0YXJ0XG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9ufSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5lbmQgPSBlbmQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGlzIHJhbmdlIHdpdGggc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgcmVsYXRpdmUgdG8gYVxuICAgKiBnaXZlbiBhbmNlc3Rvci4gU2VlIGBUZXh0UG9zaXRpb24ucmVsYXRpdmVUb2AuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKi9cbiAgcmVsYXRpdmVUbyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2UoXG4gICAgICB0aGlzLnN0YXJ0LnJlbGF0aXZlVG8oZWxlbWVudCksXG4gICAgICB0aGlzLmVuZC5yZWxhdGl2ZVRvKGVsZW1lbnQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBgVGV4dFJhbmdlYCB0byBhIERPTSByYW5nZS5cbiAgICpcbiAgICogVGhlIHJlc3VsdGluZyBET00gUmFuZ2Ugd2lsbCBhbHdheXMgc3RhcnQgYW5kIGVuZCBpbiBhIGBUZXh0YCBub2RlLlxuICAgKiBIZW5jZSBgVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkudG9SYW5nZSgpYCBjYW4gYmUgdXNlZCB0byBcInNocmlua1wiIGFcbiAgICogcmFuZ2UgdG8gdGhlIHRleHQgaXQgY29udGFpbnMuXG4gICAqXG4gICAqIE1heSB0aHJvdyBpZiB0aGUgYHN0YXJ0YCBvciBgZW5kYCBwb3NpdGlvbnMgY2Fubm90IGJlIHJlc29sdmVkIHRvIGEgcmFuZ2UuXG4gICAqXG4gICAqIEByZXR1cm4ge1JhbmdlfVxuICAgKi9cbiAgdG9SYW5nZSgpIHtcbiAgICBsZXQgc3RhcnQ7XG4gICAgbGV0IGVuZDtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhcnQuZWxlbWVudCA9PT0gdGhpcy5lbmQuZWxlbWVudCAmJlxuICAgICAgdGhpcy5zdGFydC5vZmZzZXQgPD0gdGhpcy5lbmQub2Zmc2V0XG4gICAgKSB7XG4gICAgICAvLyBGYXN0IHBhdGggZm9yIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGluIHNhbWUgZWxlbWVudC5cbiAgICAgIFtzdGFydCwgZW5kXSA9IHJlc29sdmVPZmZzZXRzKFxuICAgICAgICB0aGlzLnN0YXJ0LmVsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhcnQub2Zmc2V0LFxuICAgICAgICB0aGlzLmVuZC5vZmZzZXRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0ID0gdGhpcy5zdGFydC5yZXNvbHZlKHsgZGlyZWN0aW9uOiBSRVNPTFZFX0ZPUldBUkRTIH0pO1xuICAgICAgZW5kID0gdGhpcy5lbmQucmVzb2x2ZSh7IGRpcmVjdGlvbjogUkVTT0xWRV9CQUNLV0FSRFMgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgUmFuZ2UoKTtcbiAgICByYW5nZS5zZXRTdGFydChzdGFydC5ub2RlLCBzdGFydC5vZmZzZXQpO1xuICAgIHJhbmdlLnNldEVuZChlbmQubm9kZSwgZW5kLm9mZnNldCk7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYW4gZXhpc3RpbmcgRE9NIGBSYW5nZWAgdG8gYSBgVGV4dFJhbmdlYFxuICAgKlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZVxuICAgKiBAcmV0dXJuIHtUZXh0UmFuZ2V9XG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJhbmdlKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBUZXh0UG9zaXRpb24uZnJvbVBvaW50KFxuICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgICByYW5nZS5zdGFydE9mZnNldFxuICAgICk7XG4gICAgY29uc3QgZW5kID0gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2Uoc3RhcnQsIGVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgYFRleHRSYW5nZWAgZnJvbSB0aGUgYHN0YXJ0YHRoIHRvIGBlbmRgdGggY2hhcmFjdGVycyBpbiBgcm9vdGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZFxuICAgKi9cbiAgc3RhdGljIGZyb21PZmZzZXRzKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gbmV3IFRleHRSYW5nZShcbiAgICAgIG5ldyBUZXh0UG9zaXRpb24ocm9vdCwgc3RhcnQpLFxuICAgICAgbmV3IFRleHRQb3NpdGlvbihyb290LCBlbmQpXG4gICAgKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBUaGlzIG1vZHVsZSBleHBvcnRzIGEgc2V0IG9mIGNsYXNzZXMgZm9yIGNvbnZlcnRpbmcgYmV0d2VlbiBET00gYFJhbmdlYFxuICogb2JqZWN0cyBhbmQgZGlmZmVyZW50IHR5cGVzIG9mIHNlbGVjdG9ycy4gSXQgaXMgbW9zdGx5IGEgdGhpbiB3cmFwcGVyIGFyb3VuZCBhXG4gKiBzZXQgb2YgYW5jaG9yaW5nIGxpYnJhcmllcy4gSXQgc2VydmVzIHR3byBtYWluIHB1cnBvc2VzOlxuICpcbiAqICAxLiBQcm92aWRpbmcgYSBjb25zaXN0ZW50IGludGVyZmFjZSBhY3Jvc3MgZGlmZmVyZW50IHR5cGVzIG9mIGFuY2hvcnMuXG4gKiAgMi4gSW5zdWxhdGluZyB0aGUgcmVzdCBvZiB0aGUgY29kZSBmcm9tIEFQSSBjaGFuZ2VzIGluIHRoZSB1bmRlcmx5aW5nIGFuY2hvcmluZ1xuICogICAgIGxpYnJhcmllcy5cbiAqL1xuXG5pbXBvcnQgeyBtYXRjaFF1b3RlIH0gZnJvbSAnLi9tYXRjaC1xdW90ZSc7XG5pbXBvcnQgeyBUZXh0UmFuZ2UsIFRleHRQb3NpdGlvbiB9IGZyb20gJy4vdGV4dC1yYW5nZSc7XG5pbXBvcnQgeyBub2RlRnJvbVhQYXRoLCB4cGF0aEZyb21Ob2RlIH0gZnJvbSAnLi94cGF0aCc7XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuUmFuZ2VTZWxlY3Rvcn0gUmFuZ2VTZWxlY3RvclxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuVGV4dFBvc2l0aW9uU2VsZWN0b3J9IFRleHRQb3NpdGlvblNlbGVjdG9yXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi8uLi90eXBlcy9hcGknKS5UZXh0UXVvdGVTZWxlY3Rvcn0gVGV4dFF1b3RlU2VsZWN0b3JcbiAqL1xuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgUmFuZ2VBbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtOb2RlfSByb290IC0gQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgcmFuZ2UpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMucmFuZ2UgPSByYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge05vZGV9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyb290LCByYW5nZSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2VBbmNob3Iocm9vdCwgcmFuZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBhbmNob3IgZnJvbSBhIHNlcmlhbGl6ZWQgYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9yLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2VTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IG5vZGVGcm9tWFBhdGgoc2VsZWN0b3Iuc3RhcnRDb250YWluZXIsIHJvb3QpO1xuICAgIGlmICghc3RhcnRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgc3RhcnRDb250YWluZXIgWFBhdGgnKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmRDb250YWluZXIgPSBub2RlRnJvbVhQYXRoKHNlbGVjdG9yLmVuZENvbnRhaW5lciwgcm9vdCk7XG4gICAgaWYgKCFlbmRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgZW5kQ29udGFpbmVyIFhQYXRoJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBzdGFydENvbnRhaW5lcixcbiAgICAgIHNlbGVjdG9yLnN0YXJ0T2Zmc2V0XG4gICAgKTtcbiAgICBjb25zdCBlbmRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBlbmRDb250YWluZXIsXG4gICAgICBzZWxlY3Rvci5lbmRPZmZzZXRcbiAgICApO1xuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgVGV4dFJhbmdlKHN0YXJ0UG9zLCBlbmRQb3MpLnRvUmFuZ2UoKTtcbiAgICByZXR1cm4gbmV3IFJhbmdlQW5jaG9yKHJvb3QsIHJhbmdlKTtcbiAgfVxuXG4gIHRvUmFuZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMucmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7UmFuZ2VTZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgLy8gXCJTaHJpbmtcIiB0aGUgcmFuZ2Ugc28gdGhhdCBpdCB0aWdodGx5IHdyYXBzIGl0cyB0ZXh0LiBUaGlzIGVuc3VyZXMgbW9yZVxuICAgIC8vIHByZWRpY3RhYmxlIG91dHB1dCBmb3IgYSBnaXZlbiB0ZXh0IHNlbGVjdGlvbi5cbiAgICBjb25zdCBub3JtYWxpemVkUmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHRoaXMucmFuZ2UpLnRvUmFuZ2UoKTtcblxuICAgIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2Uobm9ybWFsaXplZFJhbmdlKTtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IHhwYXRoRnJvbU5vZGUodGV4dFJhbmdlLnN0YXJ0LmVsZW1lbnQsIHRoaXMucm9vdCk7XG4gICAgY29uc3QgZW5kQ29udGFpbmVyID0geHBhdGhGcm9tTm9kZSh0ZXh0UmFuZ2UuZW5kLmVsZW1lbnQsIHRoaXMucm9vdCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1JhbmdlU2VsZWN0b3InLFxuICAgICAgc3RhcnRDb250YWluZXIsXG4gICAgICBzdGFydE9mZnNldDogdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldCxcbiAgICAgIGVuZENvbnRhaW5lcixcbiAgICAgIGVuZE9mZnNldDogdGV4dFJhbmdlLmVuZC5vZmZzZXQsXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFRleHRQb3NpdGlvblNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbkFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICB0aGlzLmVuZCA9IGVuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKFxuICAgICAgcm9vdCxcbiAgICAgIHRleHRSYW5nZS5zdGFydC5vZmZzZXQsXG4gICAgICB0ZXh0UmFuZ2UuZW5kLm9mZnNldFxuICAgICk7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvblNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKHJvb3QsIHNlbGVjdG9yLnN0YXJ0LCBzZWxlY3Rvci5lbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvblNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRQb3NpdGlvblNlbGVjdG9yJyxcbiAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0LFxuICAgICAgZW5kOiB0aGlzLmVuZCxcbiAgICB9O1xuICB9XG5cbiAgdG9SYW5nZSgpIHtcbiAgICByZXR1cm4gVGV4dFJhbmdlLmZyb21PZmZzZXRzKHRoaXMucm9vdCwgdGhpcy5zdGFydCwgdGhpcy5lbmQpLnRvUmFuZ2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIFF1b3RlTWF0Y2hPcHRpb25zXG4gKiBAcHJvcCB7bnVtYmVyfSBbaGludF0gLSBFeHBlY3RlZCBwb3NpdGlvbiBvZiBtYXRjaCBpbiB0ZXh0LiBTZWUgYG1hdGNoUXVvdGVgLlxuICovXG5cbi8qKlxuICogQ29udmVydHMgYmV0d2VlbiBgVGV4dFF1b3RlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgVGV4dFF1b3RlQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdCAtIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXhhY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQucHJlZml4XVxuICAgKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5zdWZmaXhdXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCBleGFjdCwgY29udGV4dCA9IHt9KSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLmV4YWN0ID0gZXhhY3Q7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBgVGV4dFF1b3RlQW5jaG9yYCBmcm9tIGEgcmFuZ2UuXG4gICAqXG4gICAqIFdpbGwgdGhyb3cgaWYgYHJhbmdlYCBkb2VzIG5vdCBjb250YWluIGFueSB0ZXh0IG5vZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyb290LnRleHRDb250ZW50KTtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuXG4gICAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICAgIGNvbnN0IGVuZCA9IHRleHRSYW5nZS5lbmQub2Zmc2V0O1xuXG4gICAgLy8gTnVtYmVyIG9mIGNoYXJhY3RlcnMgYXJvdW5kIHRoZSBxdW90ZSB0byBjYXB0dXJlIGFzIGNvbnRleHQuIFdlIGN1cnJlbnRseVxuICAgIC8vIGFsd2F5cyB1c2UgYSBmaXhlZCBhbW91bnQsIGJ1dCBpdCB3b3VsZCBiZSBiZXR0ZXIgaWYgdGhpcyBjb2RlIHdhcyBhd2FyZVxuICAgIC8vIG9mIGxvZ2ljYWwgYm91bmRhcmllcyBpbiB0aGUgZG9jdW1lbnQgKHBhcmFncmFwaCwgYXJ0aWNsZSBldGMuKSB0byBhdm9pZFxuICAgIC8vIGNhcHR1cmluZyB0ZXh0IHVucmVsYXRlZCB0byB0aGUgcXVvdGUuXG4gICAgLy9cbiAgICAvLyBJbiByZWd1bGFyIHByb3NlIHRoZSBpZGVhbCBjb250ZW50IHdvdWxkIG9mdGVuIGJlIHRoZSBzdXJyb3VuZGluZyBzZW50ZW5jZS5cbiAgICAvLyBUaGlzIGlzIGEgbmF0dXJhbCB1bml0IG9mIG1lYW5pbmcgd2hpY2ggZW5hYmxlcyBkaXNwbGF5aW5nIHF1b3RlcyBpblxuICAgIC8vIGNvbnRleHQgZXZlbiB3aGVuIHRoZSBkb2N1bWVudCBpcyBub3QgYXZhaWxhYmxlLiBXZSBjb3VsZCB1c2UgYEludGwuU2VnbWVudGVyYFxuICAgIC8vIGZvciB0aGlzIHdoZW4gYXZhaWxhYmxlLlxuICAgIGNvbnN0IGNvbnRleHRMZW4gPSAzMjtcblxuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHRleHQuc2xpY2Uoc3RhcnQsIGVuZCksIHtcbiAgICAgIHByZWZpeDogdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIGNvbnRleHRMZW4pLCBzdGFydCksXG4gICAgICBzdWZmaXg6IHRleHQuc2xpY2UoZW5kLCBNYXRoLm1pbih0ZXh0Lmxlbmd0aCwgZW5kICsgY29udGV4dExlbikpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRRdW90ZVNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIGNvbnN0IHsgcHJlZml4LCBzdWZmaXggfSA9IHNlbGVjdG9yO1xuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHNlbGVjdG9yLmV4YWN0LCB7IHByZWZpeCwgc3VmZml4IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRRdW90ZVNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRRdW90ZVNlbGVjdG9yJyxcbiAgICAgIGV4YWN0OiB0aGlzLmV4YWN0LFxuICAgICAgcHJlZml4OiB0aGlzLmNvbnRleHQucHJlZml4LFxuICAgICAgc3VmZml4OiB0aGlzLmNvbnRleHQuc3VmZml4LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtRdW90ZU1hdGNoT3B0aW9uc30gW29wdGlvbnNdXG4gICAqL1xuICB0b1JhbmdlKG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnRvUG9zaXRpb25BbmNob3Iob3B0aW9ucykudG9SYW5nZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVvdGVNYXRjaE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKi9cbiAgdG9Qb3NpdGlvbkFuY2hvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovICh0aGlzLnJvb3QudGV4dENvbnRlbnQpO1xuICAgIGNvbnN0IG1hdGNoID0gbWF0Y2hRdW90ZSh0ZXh0LCB0aGlzLmV4YWN0LCB7XG4gICAgICAuLi50aGlzLmNvbnRleHQsXG4gICAgICBoaW50OiBvcHRpb25zLmhpbnQsXG4gICAgfSk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdRdW90ZSBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb25BbmNob3IodGhpcy5yb290LCBtYXRjaC5zdGFydCwgbWF0Y2guZW5kKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgVGV4dFF1b3RlQW5jaG9yIH0gZnJvbSBcIi4vdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzXCI7XG5cbi8vIENhdGNoIEpTIGVycm9ycyB0byBsb2cgdGhlbSBpbiB0aGUgYXBwLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwiZXJyb3JcIixcbiAgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgQW5kcm9pZC5sb2dFcnJvcihldmVudC5tZXNzYWdlLCBldmVudC5maWxlbmFtZSwgZXZlbnQubGluZW5vKTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIG9uVmlld3BvcnRXaWR0aENoYW5nZWQoKTtcbiAgICAgIHNuYXBDdXJyZW50T2Zmc2V0KCk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudC5ib2R5KTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbi8qKlxuICogSGF2aW5nIGFuIG9kZCBudW1iZXIgb2YgY29sdW1ucyB3aGVuIGRpc3BsYXlpbmcgdHdvIGNvbHVtbnMgcGVyIHNjcmVlbiBjYXVzZXMgc25hcHBpbmcgYW5kIHBhZ2VcbiAqIHR1cm5pbmcgaXNzdWVzLiBUbyBmaXggdGhpcywgd2UgaW5zZXJ0IGEgYmxhbmsgdmlydHVhbCBjb2x1bW4gYXQgdGhlIGVuZCBvZiB0aGUgcmVzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGFwcGVuZFZpcnR1YWxDb2x1bW5JZk5lZWRlZCgpIHtcbiAgY29uc3QgaWQgPSBcInJlYWRpdW0tdmlydHVhbC1wYWdlXCI7XG4gIHZhciB2aXJ0dWFsQ29sID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHx8IGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkgIT0gMikge1xuICAgIGlmICh2aXJ0dWFsQ29sKSB7XG4gICAgICB2aXJ0dWFsQ29sLnJlbW92ZSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGNvbENvdW50ID0gZG9jdW1lbnRXaWR0aCAvIHBhZ2VXaWR0aDtcbiAgICB2YXIgaGFzT2RkQ29sQ291bnQgPSAoTWF0aC5yb3VuZChjb2xDb3VudCAqIDIpIC8gMikgJSAxID4gMC4xO1xuICAgIGlmIChoYXNPZGRDb2xDb3VudCkge1xuICAgICAgaWYgKHZpcnR1YWxDb2wpIHtcbiAgICAgICAgdmlydHVhbENvbC5yZW1vdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpcnR1YWxDb2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICB2aXJ0dWFsQ29sLnNldEF0dHJpYnV0ZShcImlkXCIsIGlkKTtcbiAgICAgICAgdmlydHVhbENvbC5zdHlsZS5icmVha0JlZm9yZSA9IFwiY29sdW1uXCI7XG4gICAgICAgIHZpcnR1YWxDb2wuaW5uZXJIVE1MID0gXCImIzgyMDM7XCI7IC8vIHplcm8td2lkdGggc3BhY2VcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh2aXJ0dWFsQ29sKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHZhciBwYWdlV2lkdGggPSAxO1xuXG5mdW5jdGlvbiBvblZpZXdwb3J0V2lkdGhDaGFuZ2VkKCkge1xuICAvLyBXZSBjYW4ndCByZWx5IG9uIHdpbmRvdy5pbm5lcldpZHRoIGZvciB0aGUgcGFnZVdpZHRoIG9uIEFuZHJvaWQsIGJlY2F1c2UgaWYgdGhlXG4gIC8vIGRldmljZSBwaXhlbCByYXRpbyBpcyBub3QgYW4gaW50ZWdlciwgd2UgZ2V0IHJvdW5kaW5nIGlzc3VlcyBvZmZzZXR0aW5nIHRoZSBwYWdlcy5cbiAgLy9cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFkaXVtL3JlYWRpdW0tY3NzL2lzc3Vlcy85N1xuICAvLyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL3JlYWRpdW0vcjItbmF2aWdhdG9yLWtvdGxpbi9pc3N1ZXMvMTQ2XG4gIHZhciB3aWR0aCA9IEFuZHJvaWQuZ2V0Vmlld3BvcnRXaWR0aCgpO1xuICBwYWdlV2lkdGggPSB3aWR0aCAvIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBzZXRQcm9wZXJ0eShcbiAgICBcIi0tUlNfX3ZpZXdwb3J0V2lkdGhcIixcbiAgICBcImNhbGMoXCIgKyB3aWR0aCArIFwicHggLyBcIiArIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICsgXCIpXCJcbiAgKTtcblxuICBhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkge1xuICByZXR1cm4gcGFyc2VJbnQoXG4gICAgd2luZG93XG4gICAgICAuZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpXG4gICAgICAuZ2V0UHJvcGVydHlWYWx1ZShcImNvbHVtbi1jb3VudFwiKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHtcbiAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGU7XG4gIHJldHVybiAoXG4gICAgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tVVNFUl9fdmlld1wiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiIHx8XG4gICAgLy8gRklYTUU6IFdpbGwgbmVlZCB0byBiZSByZW1vdmVkIGluIFJlYWRpdW0gMy4wLCAtLVVTRVJfX3Njcm9sbCB3YXMgaW5jb3JyZWN0LlxuICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLVVTRVJfX3Njcm9sbFwiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JUTCgpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmJvZHkuZGlyLnRvTG93ZXJDYXNlKCkgPT0gXCJydGxcIjtcbn1cblxuLy8gU2Nyb2xsIHRvIHRoZSBnaXZlbiBUYWdJZCBpbiBkb2N1bWVudCBhbmQgc25hcC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb0lkKGlkKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gc2Nyb2xsVG9SZWN0KGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG4vLyBQb3NpdGlvbiBtdXN0IGJlIGluIHRoZSByYW5nZSBbMCAtIDFdLCAwLTEwMCUuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb1Bvc2l0aW9uIFwiICsgcG9zaXRpb24pO1xuICBpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID4gMSkge1xuICAgIHRocm93IFwic2Nyb2xsVG9Qb3NpdGlvbigpIG11c3QgYmUgZ2l2ZW4gYSBwb3NpdGlvbiBmcm9tIDAuMCB0byAgMS4wXCI7XG4gIH1cblxuICBsZXQgb2Zmc2V0O1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxIZWlnaHQgKiBwb3NpdGlvbjtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IG9mZnNldDtcbiAgICAvLyB3aW5kb3cuc2Nyb2xsVG8oMCwgb2Zmc2V0KTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnRXaWR0aCAqIHBvc2l0aW9uICogZmFjdG9yO1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgfVxufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBnaXZlbiB0ZXh0IHNuaXBwZXQuXG4vL1xuLy8gVGhlIGV4cGVjdGVkIHRleHQgYXJndW1lbnQgaXMgYSBMb2NhdG9yIFRleHQgb2JqZWN0LCBhcyBkZWZpbmVkIGhlcmU6XG4vLyBodHRwczovL3JlYWRpdW0ub3JnL2FyY2hpdGVjdHVyZS9tb2RlbHMvbG9jYXRvcnMvXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9UZXh0KHRleHQpIHtcbiAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcih7IHRleHQgfSk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc2Nyb2xsVG9SYW5nZShyYW5nZSk7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JhbmdlKHJhbmdlKSB7XG4gIHJldHVybiBzY3JvbGxUb1JlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JlY3QocmVjdCkge1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPVxuICAgICAgcmVjdC50b3AgKyB3aW5kb3cuc2Nyb2xsWSAtIHdpbmRvdy5pbm5lckhlaWdodCAvIDI7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChcbiAgICAgIHJlY3QubGVmdCArIHdpbmRvdy5zY3JvbGxYXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9TdGFydCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9TdGFydFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gMDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgMCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvRW5kKCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb0VuZFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KFxuICAgICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aCAqIGZhY3RvclxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQpO1xuICB9XG59XG5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2UgaXMgYWxyZWFkeSBhdCB0aGUgbGVmdC1tb3N0IHNjcm9sbCBvZmZzZXQuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsTGVmdCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggLSBwYWdlV2lkdGg7XG4gIHZhciBtaW5PZmZzZXQgPSBpc1JUTCgpID8gLShkb2N1bWVudFdpZHRoIC0gcGFnZVdpZHRoKSA6IDA7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1heChvZmZzZXQsIG1pbk9mZnNldCkpO1xufVxuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIGlzIGFscmVhZHkgYXQgdGhlIHJpZ2h0LW1vc3Qgc2Nyb2xsIG9mZnNldC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxSaWdodCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggKyBwYWdlV2lkdGg7XG4gIHZhciBtYXhPZmZzZXQgPSBpc1JUTCgpID8gMCA6IGRvY3VtZW50V2lkdGggLSBwYWdlV2lkdGg7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1pbihvZmZzZXQsIG1heE9mZnNldCkpO1xufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBnaXZlbiBsZWZ0IG9mZnNldC5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2Ugc2Nyb2xsIHBvc2l0aW9uIGlzIGFscmVhZHkgY2xvc2UgZW5vdWdoIHRvIHRoZSBnaXZlbiBvZmZzZXQuXG5mdW5jdGlvbiBzY3JvbGxUb09mZnNldChvZmZzZXQpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9PZmZzZXQgXCIgKyBvZmZzZXQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgdGhyb3cgXCJDYWxsZWQgc2Nyb2xsVG9PZmZzZXQoKSB3aXRoIHNjcm9sbCBtb2RlIGVuYWJsZWQuIFRoaXMgY2FuIG9ubHkgYmUgdXNlZCBpbiBwYWdpbmF0ZWQgbW9kZS5cIjtcbiAgfVxuXG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgLy8gSW4gc29tZSBjYXNlIHRoZSBzY3JvbGxYIGNhbm5vdCByZWFjaCB0aGUgcG9zaXRpb24gcmVzcGVjdGluZyB0byBpbm5lcldpZHRoXG4gIHZhciBkaWZmID0gTWF0aC5hYnMoY3VycmVudE9mZnNldCAtIG9mZnNldCkgLyBwYWdlV2lkdGg7XG4gIHJldHVybiBkaWZmID4gMC4wMTtcbn1cblxuLy8gU25hcCB0aGUgb2Zmc2V0IHRvIHRoZSBzY3JlZW4gd2lkdGggKHBhZ2Ugd2lkdGgpLlxuZnVuY3Rpb24gc25hcE9mZnNldChvZmZzZXQpIHtcbiAgdmFyIHZhbHVlID0gb2Zmc2V0ICsgKGlzUlRMKCkgPyAtMSA6IDEpO1xuICByZXR1cm4gdmFsdWUgLSAodmFsdWUgJSBwYWdlV2lkdGgpO1xufVxuXG4vLyBTbmFwcyB0aGUgY3VycmVudCBvZmZzZXQgdG8gdGhlIHBhZ2Ugd2lkdGguXG5leHBvcnQgZnVuY3Rpb24gc25hcEN1cnJlbnRPZmZzZXQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNuYXBDdXJyZW50T2Zmc2V0XCIpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIC8vIEFkZHMgaGFsZiBhIHBhZ2UgdG8gbWFrZSBzdXJlIHdlIGRvbid0IHNuYXAgdG8gdGhlIHByZXZpb3VzIHBhZ2UuXG4gIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICB2YXIgZGVsdGEgPSBmYWN0b3IgKiAocGFnZVdpZHRoIC8gMik7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoY3VycmVudE9mZnNldCArIGRlbHRhKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlRnJvbUxvY2F0b3IobG9jYXRvcikge1xuICB0cnkge1xuICAgIGxldCBsb2NhdGlvbnMgPSBsb2NhdG9yLmxvY2F0aW9ucztcbiAgICBsZXQgdGV4dCA9IGxvY2F0b3IudGV4dDtcbiAgICBpZiAodGV4dCAmJiB0ZXh0LmhpZ2hsaWdodCkge1xuICAgICAgdmFyIHJvb3Q7XG4gICAgICBpZiAobG9jYXRpb25zICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICByb290ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuICAgICAgaWYgKCFyb290KSB7XG4gICAgICAgIHJvb3QgPSBkb2N1bWVudC5ib2R5O1xuICAgICAgfVxuXG4gICAgICBsZXQgYW5jaG9yID0gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCB0ZXh0LmhpZ2hsaWdodCwge1xuICAgICAgICBwcmVmaXg6IHRleHQuYmVmb3JlLFxuICAgICAgICBzdWZmaXg6IHRleHQuYWZ0ZXIsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhbmNob3IudG9SYW5nZSgpO1xuICAgIH1cblxuICAgIGlmIChsb2NhdGlvbnMpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gbnVsbDtcblxuICAgICAgaWYgKCFlbGVtZW50ICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnQgJiYgbG9jYXRpb25zLmZyYWdtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IGh0bWxJZCBvZiBsb2NhdGlvbnMuZnJhZ21lbnRzKSB7XG4gICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGh0bWxJZCk7XG4gICAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBsZXQgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEJlZm9yZShlbGVtZW50KTtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kQWZ0ZXIoZWxlbWVudCk7XG4gICAgICAgIHJldHVybiByYW5nZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dFcnJvcihlKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vLy8gVXNlciBTZXR0aW5ncy5cblxuZXhwb3J0IGZ1bmN0aW9uIHNldENTU1Byb3BlcnRpZXMocHJvcGVydGllcykge1xuICBmb3IgKGNvbnN0IG5hbWUgaW4gcHJvcGVydGllcykge1xuICAgIHNldFByb3BlcnR5KG5hbWUsIHByb3BlcnRpZXNbbmFtZV0pO1xuICB9XG59XG5cbi8vIEZvciBzZXR0aW5nIHVzZXIgc2V0dGluZy5cbmV4cG9ydCBmdW5jdGlvbiBzZXRQcm9wZXJ0eShrZXksIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikge1xuICAgIHJlbW92ZVByb3BlcnR5KGtleSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgLy8gVGhlIGAhaW1wb3J0YW50YCBhbm5vdGF0aW9uIGlzIGFkZGVkIHdpdGggYHNldFByb3BlcnR5KClgIGJlY2F1c2UgaWYgaXQncyBwYXJ0IG9mIHRoZVxuICAgIC8vIGB2YWx1ZWAsIGl0IHdpbGwgYmUgaWdub3JlZCBieSB0aGUgV2ViIFZpZXcuXG4gICAgcm9vdC5zdHlsZS5zZXRQcm9wZXJ0eShrZXksIHZhbHVlLCBcImltcG9ydGFudFwiKTtcbiAgfVxufVxuXG4vLyBGb3IgcmVtb3ZpbmcgdXNlciBzZXR0aW5nLlxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5KGtleSkge1xuICB2YXIgcm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuICByb290LnN0eWxlLnJlbW92ZVByb3BlcnR5KGtleSk7XG59XG5cbi8vLyBUb29sa2l0XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2coKSB7XG4gIHZhciBtZXNzYWdlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKFwiIFwiKTtcbiAgQW5kcm9pZC5sb2cobWVzc2FnZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dFcnJvcihtZXNzYWdlKSB7XG4gIEFuZHJvaWQubG9nRXJyb3IobWVzc2FnZSwgXCJcIiwgMCk7XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBsb2cgYXMgbG9nTmF0aXZlIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuY29uc3QgZGVidWcgPSBmYWxzZTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIERPTVJlY3QgaW50byBhIEpTT04gb2JqZWN0IHVuZGVyc3RhbmRhYmxlIGJ5IHRoZSBuYXRpdmUgc2lkZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvTmF0aXZlUmVjdChyZWN0KSB7XG4gIGNvbnN0IHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgY29uc3Qgd2lkdGggPSByZWN0LndpZHRoICogcGl4ZWxSYXRpbztcbiAgY29uc3QgaGVpZ2h0ID0gcmVjdC5oZWlnaHQgKiBwaXhlbFJhdGlvO1xuICBjb25zdCBsZWZ0ID0gcmVjdC5sZWZ0ICogcGl4ZWxSYXRpbztcbiAgY29uc3QgdG9wID0gcmVjdC50b3AgKiBwaXhlbFJhdGlvO1xuICBjb25zdCByaWdodCA9IGxlZnQgKyB3aWR0aDtcbiAgY29uc3QgYm90dG9tID0gdG9wICsgaGVpZ2h0O1xuICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0LCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20gfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICByYW5nZSxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGxldCBjbGllbnRSZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG5cbiAgY29uc3QgdG9sZXJhbmNlID0gMTtcbiAgY29uc3Qgb3JpZ2luYWxSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJhbmdlQ2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIG9yaWdpbmFsUmVjdHMucHVzaCh7XG4gICAgICBib3R0b206IHJhbmdlQ2xpZW50UmVjdC5ib3R0b20sXG4gICAgICBoZWlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUNsaWVudFJlY3QubGVmdCxcbiAgICAgIHJpZ2h0OiByYW5nZUNsaWVudFJlY3QucmlnaHQsXG4gICAgICB0b3A6IHJhbmdlQ2xpZW50UmVjdC50b3AsXG4gICAgICB3aWR0aDogcmFuZ2VDbGllbnRSZWN0LndpZHRoLFxuICAgIH0pO1xuICB9XG4gIGNvbnN0IG1lcmdlZFJlY3RzID0gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgIG9yaWdpbmFsUmVjdHMsXG4gICAgdG9sZXJhbmNlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgY29uc3Qgbm9Db250YWluZWRSZWN0cyA9IHJlbW92ZUNvbnRhaW5lZFJlY3RzKG1lcmdlZFJlY3RzLCB0b2xlcmFuY2UpO1xuICBjb25zdCBuZXdSZWN0cyA9IHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobm9Db250YWluZWRSZWN0cyk7XG4gIGNvbnN0IG1pbkFyZWEgPSAyICogMjtcbiAgZm9yIChsZXQgaiA9IG5ld1JlY3RzLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgY29uc3QgcmVjdCA9IG5ld1JlY3RzW2pdO1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggKiByZWN0LmhlaWdodCA+IG1pbkFyZWE7XG4gICAgaWYgKCFiaWdFbm91Z2gpIHtcbiAgICAgIGlmIChuZXdSZWN0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGxcIik7XG4gICAgICAgIG5ld1JlY3RzLnNwbGljZShqLCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGwsIGJ1dCBrZWVwIG90aGVyd2lzZSBlbXB0eSFcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBsb2coYENMSUVOVCBSRUNUOiByZWR1Y2VkICR7b3JpZ2luYWxSZWN0cy5sZW5ndGh9IC0tPiAke25ld1JlY3RzLmxlbmd0aH1gKTtcbiAgcmV0dXJuIG5ld1JlY3RzO1xufVxuXG5mdW5jdGlvbiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gIHJlY3RzLFxuICB0b2xlcmFuY2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJtZXJnZVRvdWNoaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0c0xpbmVVcFZlcnRpY2FsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIubGVmdCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCBob3Jpem9udGFsQWxsb3dlZCA9ICFkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzO1xuICAgICAgY29uc3QgYWxpZ25lZCA9XG4gICAgICAgIChyZWN0c0xpbmVVcEhvcml6b250YWxseSAmJiBob3Jpem9udGFsQWxsb3dlZCkgfHxcbiAgICAgICAgKHJlY3RzTGluZVVwVmVydGljYWxseSAmJiAhcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkpO1xuICAgICAgY29uc3QgY2FuTWVyZ2UgPSBhbGlnbmVkICYmIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpO1xuICAgICAgaWYgKGNhbk1lcmdlKSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICBgQ0xJRU5UIFJFQ1Q6IG1lcmdpbmcgdHdvIGludG8gb25lLCBWRVJUSUNBTDogJHtyZWN0c0xpbmVVcFZlcnRpY2FsbHl9IEhPUklaT05UQUw6ICR7cmVjdHNMaW5lVXBIb3Jpem9udGFsbHl9ICgke2RvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHN9KWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gcmVjdDEgJiYgcmVjdCAhPT0gcmVjdDI7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXBsYWNlbWVudENsaWVudFJlY3QgPSBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgbmV3UmVjdHMucHVzaChyZXBsYWNlbWVudENsaWVudFJlY3QpO1xuICAgICAgICByZXR1cm4gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgICAgICAgIG5ld1JlY3RzLFxuICAgICAgICAgIHRvbGVyYW5jZSxcbiAgICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCBsZWZ0ID0gTWF0aC5taW4ocmVjdDEubGVmdCwgcmVjdDIubGVmdCk7XG4gIGNvbnN0IHJpZ2h0ID0gTWF0aC5tYXgocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0KTtcbiAgY29uc3QgdG9wID0gTWF0aC5taW4ocmVjdDEudG9wLCByZWN0Mi50b3ApO1xuICBjb25zdCBib3R0b20gPSBNYXRoLm1heChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSk7XG4gIHJldHVybiB7XG4gICAgYm90dG9tLFxuICAgIGhlaWdodDogYm90dG9tIC0gdG9wLFxuICAgIGxlZnQsXG4gICAgcmlnaHQsXG4gICAgdG9wLFxuICAgIHdpZHRoOiByaWdodCAtIGxlZnQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNvbnRhaW5lZFJlY3RzKHJlY3RzLCB0b2xlcmFuY2UpIHtcbiAgY29uc3QgcmVjdHNUb0tlZXAgPSBuZXcgU2V0KHJlY3RzKTtcbiAgZm9yIChjb25zdCByZWN0IG9mIHJlY3RzKSB7XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCA+IDEgJiYgcmVjdC5oZWlnaHQgPiAxO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHRpbnlcIik7XG4gICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwb3NzaWJseUNvbnRhaW5pbmdSZWN0IG9mIHJlY3RzKSB7XG4gICAgICBpZiAocmVjdCA9PT0gcG9zc2libHlDb250YWluaW5nUmVjdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjdHNUb0tlZXAuaGFzKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RDb250YWlucyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0LCByZWN0LCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgY29udGFpbmVkXCIpO1xuICAgICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gQXJyYXkuZnJvbShyZWN0c1RvS2VlcCk7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWlucyhyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjdENvbnRhaW5zUG9pbnQocmVjdCwgeCwgeSwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QubGVmdCA8IHggfHwgYWxtb3N0RXF1YWwocmVjdC5sZWZ0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnJpZ2h0ID4geCB8fCBhbG1vc3RFcXVhbChyZWN0LnJpZ2h0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnRvcCA8IHkgfHwgYWxtb3N0RXF1YWwocmVjdC50b3AsIHksIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QuYm90dG9tID4geSB8fCBhbG1vc3RFcXVhbChyZWN0LmJvdHRvbSwgeSwgdG9sZXJhbmNlKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhyZWN0cykge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgbGV0IHRvQWRkID0gW107XG4gICAgICAgIGxldCB0b1JlbW92ZTtcbiAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czEgPSByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMiA9IHJlY3RTdWJ0cmFjdChyZWN0MiwgcmVjdDEpO1xuICAgICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPCBzdWJ0cmFjdFJlY3RzMi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMyO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbG9nKGBDTElFTlQgUkVDVDogb3ZlcmxhcCwgY3V0IG9uZSByZWN0IGludG8gJHt0b0FkZC5sZW5ndGh9YCk7XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHRvUmVtb3ZlO1xuICAgICAgICB9KTtcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkobmV3UmVjdHMsIHRvQWRkKTtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobmV3UmVjdHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgcmVjdEludGVyc2VjdGVkID0gcmVjdEludGVyc2VjdChyZWN0MiwgcmVjdDEpO1xuICBpZiAocmVjdEludGVyc2VjdGVkLmhlaWdodCA9PT0gMCB8fCByZWN0SW50ZXJzZWN0ZWQud2lkdGggPT09IDApIHtcbiAgICByZXR1cm4gW3JlY3QxXTtcbiAgfVxuICBjb25zdCByZWN0cyA9IFtdO1xuICB7XG4gICAgY29uc3QgcmVjdEEgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3QxLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEEud2lkdGggPSByZWN0QS5yaWdodCAtIHJlY3RBLmxlZnQ7XG4gICAgcmVjdEEuaGVpZ2h0ID0gcmVjdEEuYm90dG9tIC0gcmVjdEEudG9wO1xuICAgIGlmIChyZWN0QS5oZWlnaHQgIT09IDAgJiYgcmVjdEEud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEEpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEIgPSB7XG4gICAgICBib3R0b206IHJlY3RJbnRlcnNlY3RlZC50b3AsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEIud2lkdGggPSByZWN0Qi5yaWdodCAtIHJlY3RCLmxlZnQ7XG4gICAgcmVjdEIuaGVpZ2h0ID0gcmVjdEIuYm90dG9tIC0gcmVjdEIudG9wO1xuICAgIGlmIChyZWN0Qi5oZWlnaHQgIT09IDAgJiYgcmVjdEIud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEIpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEMgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdEludGVyc2VjdGVkLmJvdHRvbSxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEMud2lkdGggPSByZWN0Qy5yaWdodCAtIHJlY3RDLmxlZnQ7XG4gICAgcmVjdEMuaGVpZ2h0ID0gcmVjdEMuYm90dG9tIC0gcmVjdEMudG9wO1xuICAgIGlmIChyZWN0Qy5oZWlnaHQgIT09IDAgJiYgcmVjdEMud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEMpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEQgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHJpZ2h0OiByZWN0MS5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0RC53aWR0aCA9IHJlY3RELnJpZ2h0IC0gcmVjdEQubGVmdDtcbiAgICByZWN0RC5oZWlnaHQgPSByZWN0RC5ib3R0b20gLSByZWN0RC50b3A7XG4gICAgaWYgKHJlY3RELmhlaWdodCAhPT0gMCAmJiByZWN0RC53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0RCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gcmVjdEludGVyc2VjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbWF4TGVmdCA9IE1hdGgubWF4KHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCBtaW5SaWdodCA9IE1hdGgubWluKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IG1heFRvcCA9IE1hdGgubWF4KHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgbWluQm90dG9tID0gTWF0aC5taW4ocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbTogbWluQm90dG9tLFxuICAgIGhlaWdodDogTWF0aC5tYXgoMCwgbWluQm90dG9tIC0gbWF4VG9wKSxcbiAgICBsZWZ0OiBtYXhMZWZ0LFxuICAgIHJpZ2h0OiBtaW5SaWdodCxcbiAgICB0b3A6IG1heFRvcCxcbiAgICB3aWR0aDogTWF0aC5tYXgoMCwgbWluUmlnaHQgLSBtYXhMZWZ0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0MS5sZWZ0IDwgcmVjdDIucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLmxlZnQgPCByZWN0MS5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLmxlZnQsIHJlY3QxLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDEudG9wIDwgcmVjdDIuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi50b3AgPCByZWN0MS5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi50b3AsIHJlY3QxLmJvdHRvbSwgdG9sZXJhbmNlKSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGFsbW9zdEVxdWFsKGEsIGIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gTWF0aC5hYnMoYSAtIGIpIDw9IHRvbGVyYW5jZTtcbn1cblxuZnVuY3Rpb24gbG9nKCkge1xuICBpZiAoZGVidWcpIHtcbiAgICBsb2dOYXRpdmUuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHtcbiAgZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAsXG4gIHJlY3RDb250YWluc1BvaW50LFxuICB0b05hdGl2ZVJlY3QsXG59IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IGxvZywgbG9nRXJyb3IsIHJhbmdlRnJvbUxvY2F0b3IgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5sZXQgc3R5bGVzID0gbmV3IE1hcCgpO1xubGV0IGdyb3VwcyA9IG5ldyBNYXAoKTtcbnZhciBsYXN0R3JvdXBJZCA9IDA7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgbGlzdCBvZiBhZGRpdGlvbmFsIHN1cHBvcnRlZCBEZWNvcmF0aW9uIFRlbXBsYXRlcy5cbiAqXG4gKiBFYWNoIHRlbXBsYXRlIG9iamVjdCBpcyBpbmRleGVkIGJ5IHRoZSBzdHlsZSBJRC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyVGVtcGxhdGVzKG5ld1N0eWxlcykge1xuICB2YXIgc3R5bGVzaGVldCA9IFwiXCI7XG5cbiAgZm9yIChjb25zdCBbaWQsIHN0eWxlXSBvZiBPYmplY3QuZW50cmllcyhuZXdTdHlsZXMpKSB7XG4gICAgc3R5bGVzLnNldChpZCwgc3R5bGUpO1xuICAgIGlmIChzdHlsZS5zdHlsZXNoZWV0KSB7XG4gICAgICBzdHlsZXNoZWV0ICs9IHN0eWxlLnN0eWxlc2hlZXQgKyBcIlxcblwiO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdHlsZXNoZWV0KSB7XG4gICAgbGV0IHN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICBzdHlsZUVsZW1lbnQuaW5uZXJIVE1MID0gc3R5bGVzaGVldDtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRGVjb3JhdGlvbkdyb3VwIGZvciB0aGUgZ2l2ZW4gZ3JvdXAgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlY29yYXRpb25zKGdyb3VwTmFtZSkge1xuICB2YXIgZ3JvdXAgPSBncm91cHMuZ2V0KGdyb3VwTmFtZSk7XG4gIGlmICghZ3JvdXApIHtcbiAgICBsZXQgaWQgPSBcInIyLWRlY29yYXRpb24tXCIgKyBsYXN0R3JvdXBJZCsrO1xuICAgIGdyb3VwID0gRGVjb3JhdGlvbkdyb3VwKGlkLCBncm91cE5hbWUpO1xuICAgIGdyb3Vwcy5zZXQoZ3JvdXBOYW1lLCBncm91cCk7XG4gIH1cbiAgcmV0dXJuIGdyb3VwO1xufVxuXG4vKipcbiAqIEhhbmRsZXMgY2xpY2sgZXZlbnRzIG9uIGEgRGVjb3JhdGlvbi5cbiAqIFJldHVybnMgd2hldGhlciBhIGRlY29yYXRpb24gbWF0Y2hlZCB0aGlzIGV2ZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQoZXZlbnQsIGNsaWNrRXZlbnQpIHtcbiAgaWYgKGdyb3Vwcy5zaXplID09PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZFRhcmdldCgpIHtcbiAgICBmb3IgKGNvbnN0IFtncm91cCwgZ3JvdXBDb250ZW50XSBvZiBncm91cHMpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBncm91cENvbnRlbnQuaXRlbXMucmV2ZXJzZSgpKSB7XG4gICAgICAgIGlmICghaXRlbS5jbGlja2FibGVFbGVtZW50cykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzKSB7XG4gICAgICAgICAgbGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvSlNPTigpO1xuICAgICAgICAgIGlmIChyZWN0Q29udGFpbnNQb2ludChyZWN0LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCAxKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgZ3JvdXAsIGl0ZW0sIGVsZW1lbnQsIHJlY3QgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgdGFyZ2V0ID0gZmluZFRhcmdldCgpO1xuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBBbmRyb2lkLm9uRGVjb3JhdGlvbkFjdGl2YXRlZChcbiAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBpZDogdGFyZ2V0Lml0ZW0uZGVjb3JhdGlvbi5pZCxcbiAgICAgIGdyb3VwOiB0YXJnZXQuZ3JvdXAsXG4gICAgICByZWN0OiB0b05hdGl2ZVJlY3QodGFyZ2V0Lml0ZW0ucmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpLFxuICAgICAgY2xpY2s6IGNsaWNrRXZlbnQsXG4gICAgfSlcbiAgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgRGVjb3JhdGlvbkdyb3VwIG9iamVjdCBmcm9tIGEgdW5pcXVlIEhUTUwgSUQgYW5kIGl0cyBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gRGVjb3JhdGlvbkdyb3VwKGdyb3VwSWQsIGdyb3VwTmFtZSkge1xuICB2YXIgaXRlbXMgPSBbXTtcbiAgdmFyIGxhc3RJdGVtSWQgPSAwO1xuICB2YXIgY29udGFpbmVyID0gbnVsbDtcblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBkZWNvcmF0aW9uIHRvIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIGFkZChkZWNvcmF0aW9uKSB7XG4gICAgbGV0IGlkID0gZ3JvdXBJZCArIFwiLVwiICsgbGFzdEl0ZW1JZCsrO1xuXG4gICAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcihkZWNvcmF0aW9uLmxvY2F0b3IpO1xuICAgIGlmICghcmFuZ2UpIHtcbiAgICAgIGxvZyhcIkNhbid0IGxvY2F0ZSBET00gcmFuZ2UgZm9yIGRlY29yYXRpb25cIiwgZGVjb3JhdGlvbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSB7IGlkLCBkZWNvcmF0aW9uLCByYW5nZSB9O1xuICAgIGl0ZW1zLnB1c2goaXRlbSk7XG4gICAgbGF5b3V0KGl0ZW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGRlY29yYXRpb24gd2l0aCBnaXZlbiBJRCBmcm9tIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZShkZWNvcmF0aW9uSWQpIHtcbiAgICBsZXQgaW5kZXggPSBpdGVtcy5maW5kSW5kZXgoKGkpID0+IGkuZGVjb3JhdGlvbi5pZCA9PT0gZGVjb3JhdGlvbklkKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSBpdGVtc1tpbmRleF07XG4gICAgaXRlbXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gbnVsbDtcbiAgICBpZiAoaXRlbS5jb250YWluZXIpIHtcbiAgICAgIGl0ZW0uY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgaXRlbS5jb250YWluZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZmllcyB0aGF0IHRoZSBnaXZlbiBkZWNvcmF0aW9uIHdhcyBtb2RpZmllZCBhbmQgbmVlZHMgdG8gYmUgdXBkYXRlZC5cbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZShkZWNvcmF0aW9uKSB7XG4gICAgcmVtb3ZlKGRlY29yYXRpb24uaWQpO1xuICAgIGFkZChkZWNvcmF0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFsbCBkZWNvcmF0aW9ucyBmcm9tIHRoaXMgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICBjbGVhckNvbnRhaW5lcigpO1xuICAgIGl0ZW1zLmxlbmd0aCA9IDA7XG4gIH1cblxuICAvKipcbiAgICogUmVjcmVhdGVzIHRoZSBkZWNvcmF0aW9uIGVsZW1lbnRzLlxuICAgKlxuICAgKiBUbyBiZSBjYWxsZWQgYWZ0ZXIgcmVmbG93aW5nIHRoZSByZXNvdXJjZSwgZm9yIGV4YW1wbGUuXG4gICAqL1xuICBmdW5jdGlvbiByZXF1ZXN0TGF5b3V0KCkge1xuICAgIGNsZWFyQ29udGFpbmVyKCk7XG4gICAgaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4gbGF5b3V0KGl0ZW0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXlvdXRzIGEgc2luZ2xlIERlY29yYXRpb24gaXRlbS5cbiAgICovXG4gIGZ1bmN0aW9uIGxheW91dChpdGVtKSB7XG4gICAgbGV0IGdyb3VwQ29udGFpbmVyID0gcmVxdWlyZUNvbnRhaW5lcigpO1xuXG4gICAgbGV0IHN0eWxlID0gc3R5bGVzLmdldChpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGlmICghc3R5bGUpIHtcbiAgICAgIGxvZ0Vycm9yKGBVbmtub3duIGRlY29yYXRpb24gc3R5bGU6ICR7aXRlbS5kZWNvcmF0aW9uLnN0eWxlfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBpdGVtQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIGl0ZW0uaWQpO1xuICAgIGl0ZW1Db250YWluZXIuc2V0QXR0cmlidXRlKFwiZGF0YS1zdHlsZVwiLCBpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGl0ZW1Db250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG5cbiAgICBsZXQgdmlld3BvcnRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgIGxldCBjb2x1bW5Db3VudCA9IHBhcnNlSW50KFxuICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXG4gICAgICAgIFwiY29sdW1uLWNvdW50XCJcbiAgICAgIClcbiAgICApO1xuICAgIGxldCBwYWdlV2lkdGggPSB2aWV3cG9ydFdpZHRoIC8gKGNvbHVtbkNvdW50IHx8IDEpO1xuICAgIGxldCBzY3JvbGxpbmdFbGVtZW50ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudDtcbiAgICBsZXQgeE9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICBsZXQgeU9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgZnVuY3Rpb24gcG9zaXRpb25FbGVtZW50KGVsZW1lbnQsIHJlY3QsIGJvdW5kaW5nUmVjdCkge1xuICAgICAgZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblxuICAgICAgaWYgKHN0eWxlLndpZHRoID09PSBcIndyYXBcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtyZWN0LmxlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJ2aWV3cG9ydFwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHt2aWV3cG9ydFdpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGxldCBsZWZ0ID0gTWF0aC5mbG9vcihyZWN0LmxlZnQgLyB2aWV3cG9ydFdpZHRoKSAqIHZpZXdwb3J0V2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJib3VuZHNcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7Ym91bmRpbmdSZWN0LndpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2JvdW5kaW5nUmVjdC5sZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwicGFnZVwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtwYWdlV2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgbGV0IGxlZnQgPSBNYXRoLmZsb29yKHJlY3QubGVmdCAvIHBhZ2VXaWR0aCkgKiBwYWdlV2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBib3VuZGluZ1JlY3QgPSBpdGVtLnJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgbGV0IGVsZW1lbnRUZW1wbGF0ZTtcbiAgICB0cnkge1xuICAgICAgbGV0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gaXRlbS5kZWNvcmF0aW9uLmVsZW1lbnQudHJpbSgpO1xuICAgICAgZWxlbWVudFRlbXBsYXRlID0gdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGRlY29yYXRpb24gZWxlbWVudCBcIiR7aXRlbS5kZWNvcmF0aW9uLmVsZW1lbnR9XCI6ICR7ZXJyb3IubWVzc2FnZX1gXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm94ZXNcIikge1xuICAgICAgbGV0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSB0cnVlO1xuICAgICAgbGV0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgICAgIGl0ZW0ucmFuZ2UsXG4gICAgICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgICAgICk7XG5cbiAgICAgIGNsaWVudFJlY3RzID0gY2xpZW50UmVjdHMuc29ydCgocjEsIHIyKSA9PiB7XG4gICAgICAgIGlmIChyMS50b3AgPCByMi50b3ApIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH0gZWxzZSBpZiAocjEudG9wID4gcjIudG9wKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBmb3IgKGxldCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBlbGVtZW50VGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBsaW5lLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICBwb3NpdGlvbkVsZW1lbnQobGluZSwgY2xpZW50UmVjdCwgYm91bmRpbmdSZWN0KTtcbiAgICAgICAgaXRlbUNvbnRhaW5lci5hcHBlbmQobGluZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm91bmRzXCIpIHtcbiAgICAgIGNvbnN0IGJvdW5kcyA9IGVsZW1lbnRUZW1wbGF0ZS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICBib3VuZHMuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBwb3NpdGlvbkVsZW1lbnQoYm91bmRzLCBib3VuZGluZ1JlY3QsIGJvdW5kaW5nUmVjdCk7XG5cbiAgICAgIGl0ZW1Db250YWluZXIuYXBwZW5kKGJvdW5kcyk7XG4gICAgfVxuXG4gICAgZ3JvdXBDb250YWluZXIuYXBwZW5kKGl0ZW1Db250YWluZXIpO1xuICAgIGl0ZW0uY29udGFpbmVyID0gaXRlbUNvbnRhaW5lcjtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gQXJyYXkuZnJvbShcbiAgICAgIGl0ZW1Db250YWluZXIucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWFjdGl2YWJsZT0nMSddXCIpXG4gICAgKTtcbiAgICBpZiAoaXRlbS5jbGlja2FibGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGl0ZW0uY2xpY2thYmxlRWxlbWVudHMgPSBBcnJheS5mcm9tKGl0ZW1Db250YWluZXIuY2hpbGRyZW4pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBncm91cCBjb250YWluZXIgZWxlbWVudCwgYWZ0ZXIgbWFraW5nIHN1cmUgaXQgZXhpc3RzLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVxdWlyZUNvbnRhaW5lcigpIHtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBncm91cElkKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJkYXRhLWdyb3VwXCIsIGdyb3VwTmFtZSk7XG4gICAgICBjb250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChjb250YWluZXIpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdyb3VwIGNvbnRhaW5lci5cbiAgICovXG4gIGZ1bmN0aW9uIGNsZWFyQ29udGFpbmVyKCkge1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGNvbnRhaW5lciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgYWRkLCByZW1vdmUsIHVwZGF0ZSwgY2xlYXIsIGl0ZW1zLCByZXF1ZXN0TGF5b3V0IH07XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIC8vIFdpbGwgcmVsYXlvdXQgYWxsIHRoZSBkZWNvcmF0aW9ucyB3aGVuIHRoZSBkb2N1bWVudCBib2R5IGlzIHJlc2l6ZWQuXG4gICAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgdmFyIGxhc3RTaXplID0geyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBsYXN0U2l6ZS53aWR0aCA9PT0gYm9keS5jbGllbnRXaWR0aCAmJlxuICAgICAgICBsYXN0U2l6ZS5oZWlnaHQgPT09IGJvZHkuY2xpZW50SGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbGFzdFNpemUgPSB7XG4gICAgICAgIHdpZHRoOiBib2R5LmNsaWVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGJvZHkuY2xpZW50SGVpZ2h0LFxuICAgICAgfTtcblxuICAgICAgZ3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIGdyb3VwLnJlcXVlc3RMYXlvdXQoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoYm9keSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuICogYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuICovXG5cbmltcG9ydCB7IGhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50IH0gZnJvbSBcIi4vZGVjb3JhdG9yXCI7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmdW5jdGlvbiAoKSB7XG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBvbkNsaWNrLCBmYWxzZSk7XG4gIGJpbmREcmFnR2VzdHVyZShkb2N1bWVudCk7XG59KTtcblxuZnVuY3Rpb24gb25DbGljayhldmVudCkge1xuICBpZiAoIXdpbmRvdy5nZXRTZWxlY3Rpb24oKS5pc0NvbGxhcHNlZCkge1xuICAgIC8vIFRoZXJlJ3MgYW4gb24tZ29pbmcgc2VsZWN0aW9uLCB0aGUgdGFwIHdpbGwgZGlzbWlzcyBpdCBzbyB3ZSBkb24ndCBmb3J3YXJkIGl0LlxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwaXhlbFJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gIGxldCBjbGlja0V2ZW50ID0ge1xuICAgIGRlZmF1bHRQcmV2ZW50ZWQ6IGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQsXG4gICAgeDogZXZlbnQuY2xpZW50WCAqIHBpeGVsUmF0aW8sXG4gICAgeTogZXZlbnQuY2xpZW50WSAqIHBpeGVsUmF0aW8sXG4gICAgdGFyZ2V0RWxlbWVudDogZXZlbnQudGFyZ2V0Lm91dGVySFRNTCxcbiAgICBpbnRlcmFjdGl2ZUVsZW1lbnQ6IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSxcbiAgfTtcblxuICBpZiAoaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQoZXZlbnQsIGNsaWNrRXZlbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gU2VuZCB0aGUgdGFwIGRhdGEgb3ZlciB0aGUgSlMgYnJpZGdlIGV2ZW4gaWYgaXQncyBiZWVuIGhhbmRsZWQgd2l0aGluIHRoZSB3ZWIgdmlldywgc28gdGhhdFxuICAvLyBpdCBjYW4gYmUgcHJlc2VydmVkIGFuZCB1c2VkIGJ5IHRoZSB0b29sa2l0IGlmIG5lZWRlZC5cbiAgdmFyIHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vblRhcChKU09OLnN0cmluZ2lmeShjbGlja0V2ZW50KSk7XG5cbiAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBiaW5kRHJhZ0dlc3R1cmUoZWxlbWVudCkge1xuICAvLyBwYXNzaXZlOiBmYWxzZSBpcyBuZWNlc3NhcnkgdG8gYmUgYWJsZSB0byBwcmV2ZW50IHRoZSBkZWZhdWx0IGJlaGF2aW9yLlxuICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIG9uU3RhcnQsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIG9uRW5kLCB7IHBhc3NpdmU6IGZhbHNlIH0pO1xuICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgb25Nb3ZlLCB7IHBhc3NpdmU6IGZhbHNlIH0pO1xuXG4gIHZhciBzdGF0ZSA9IHVuZGVmaW5lZDtcbiAgdmFyIGlzU3RhcnRpbmdEcmFnID0gZmFsc2U7XG4gIGNvbnN0IHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcblxuICBmdW5jdGlvbiBvblN0YXJ0KGV2ZW50KSB7XG4gICAgaXNTdGFydGluZ0RyYWcgPSB0cnVlO1xuXG4gICAgY29uc3Qgc3RhcnRYID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRYICogcGl4ZWxSYXRpbztcbiAgICBjb25zdCBzdGFydFkgPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlID0ge1xuICAgICAgZGVmYXVsdFByZXZlbnRlZDogZXZlbnQuZGVmYXVsdFByZXZlbnRlZCxcbiAgICAgIHN0YXJ0WDogc3RhcnRYLFxuICAgICAgc3RhcnRZOiBzdGFydFksXG4gICAgICBjdXJyZW50WDogc3RhcnRYLFxuICAgICAgY3VycmVudFk6IHN0YXJ0WSxcbiAgICAgIG9mZnNldFg6IDAsXG4gICAgICBvZmZzZXRZOiAwLFxuICAgICAgaW50ZXJhY3RpdmVFbGVtZW50OiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGV2ZW50LnRhcmdldCksXG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uTW92ZShldmVudCkge1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcblxuICAgIHN0YXRlLmN1cnJlbnRYID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRYICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZS5jdXJyZW50WSA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUub2Zmc2V0WCA9IHN0YXRlLmN1cnJlbnRYIC0gc3RhdGUuc3RhcnRYO1xuICAgIHN0YXRlLm9mZnNldFkgPSBzdGF0ZS5jdXJyZW50WSAtIHN0YXRlLnN0YXJ0WTtcblxuICAgIHZhciBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IGZhbHNlO1xuICAgIC8vIFdhaXQgZm9yIGEgbW92ZW1lbnQgb2YgYXQgbGVhc3QgNiBwaXhlbHMgYmVmb3JlIHJlcG9ydGluZyBhIGRyYWcuXG4gICAgaWYgKGlzU3RhcnRpbmdEcmFnKSB7XG4gICAgICBpZiAoTWF0aC5hYnMoc3RhdGUub2Zmc2V0WCkgPj0gNiB8fCBNYXRoLmFicyhzdGF0ZS5vZmZzZXRZKSA+PSA2KSB7XG4gICAgICAgIGlzU3RhcnRpbmdEcmFnID0gZmFsc2U7XG4gICAgICAgIHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdTdGFydChKU09OLnN0cmluZ2lmeShzdGF0ZSkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnTW92ZShKU09OLnN0cmluZ2lmeShzdGF0ZSkpO1xuICAgIH1cblxuICAgIGlmIChzaG91bGRQcmV2ZW50RGVmYXVsdCkge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uRW5kKGV2ZW50KSB7XG4gICAgaWYgKCFzdGF0ZSkgcmV0dXJuO1xuXG4gICAgY29uc3Qgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ0VuZChKU09OLnN0cmluZ2lmeShzdGF0ZSkpO1xuICAgIGlmIChzaG91bGRQcmV2ZW50RGVmYXVsdCkge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBzdGF0ZSA9IHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vLyBTZWUuIGh0dHBzOi8vZ2l0aHViLmNvbS9KYXlQYW5vei9hcmNoaXRlY3R1cmUvdHJlZS90b3VjaC1oYW5kbGluZy9taXNjL3RvdWNoLWhhbmRsaW5nXG5mdW5jdGlvbiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQpIHtcbiAgdmFyIGludGVyYWN0aXZlVGFncyA9IFtcbiAgICBcImFcIixcbiAgICBcImF1ZGlvXCIsXG4gICAgXCJidXR0b25cIixcbiAgICBcImNhbnZhc1wiLFxuICAgIFwiZGV0YWlsc1wiLFxuICAgIFwiaW5wdXRcIixcbiAgICBcImxhYmVsXCIsXG4gICAgXCJvcHRpb25cIixcbiAgICBcInNlbGVjdFwiLFxuICAgIFwic3VibWl0XCIsXG4gICAgXCJ0ZXh0YXJlYVwiLFxuICAgIFwidmlkZW9cIixcbiAgXTtcbiAgaWYgKGludGVyYWN0aXZlVGFncy5pbmRleE9mKGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSkgIT0gLTEpIHtcbiAgICByZXR1cm4gZWxlbWVudC5vdXRlckhUTUw7XG4gIH1cblxuICAvLyBDaGVja3Mgd2hldGhlciB0aGUgZWxlbWVudCBpcyBlZGl0YWJsZSBieSB0aGUgdXNlci5cbiAgaWYgKFxuICAgIGVsZW1lbnQuaGFzQXR0cmlidXRlKFwiY29udGVudGVkaXRhYmxlXCIpICYmXG4gICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJjb250ZW50ZWRpdGFibGVcIikudG9Mb3dlckNhc2UoKSAhPSBcImZhbHNlXCJcbiAgKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQub3V0ZXJIVE1MO1xuICB9XG5cbiAgLy8gQ2hlY2tzIHBhcmVudHMgcmVjdXJzaXZlbHkgYmVjYXVzZSB0aGUgdG91Y2ggbWlnaHQgYmUgZm9yIGV4YW1wbGUgb24gYW4gPGVtPiBpbnNpZGUgYSA8YT4uXG4gIGlmIChlbGVtZW50LnBhcmVudEVsZW1lbnQpIHtcbiAgICByZXR1cm4gbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChlbGVtZW50LnBhcmVudEVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSAqL1xuLy9cbi8vICBoaWdobGlnaHQuanNcbi8vICByMi1uYXZpZ2F0b3Ita290bGluXG4vL1xuLy8gIE9yZ2FuaXplZCBieSBUYWVoeXVuIEtpbSBvbiA2LzI3LzE5IGZyb20gcjItbmF2aWdhdG9yLWpzLlxuLy9cbi8vICBDb3B5cmlnaHQgMjAxOSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB3aGljaCBpcyBkZXRhaWxlZFxuLy8gIGluIHRoZSBMSUNFTlNFIGZpbGUgcHJlc2VudCBpbiB0aGUgcHJvamVjdCByZXBvc2l0b3J5IHdoZXJlIHRoaXMgc291cmNlIGNvZGUgaXMgbWFpbnRhaW5lZC5cbi8vXG5cbmNvbnN0IFJPT1RfQ0xBU1NfUkVEVUNFX01PVElPTiA9IFwicjItcmVkdWNlLW1vdGlvblwiO1xuY29uc3QgUk9PVF9DTEFTU19OT19GT09UTk9URVMgPSBcInIyLW5vLXBvcHVwLWZvb25vdGVzXCI7XG5jb25zdCBQT1BVUF9ESUFMT0dfQ0xBU1MgPSBcInIyLXBvcHVwLWRpYWxvZ1wiO1xuY29uc3QgRk9PVE5PVEVTX0NPTlRBSU5FUl9DTEFTUyA9IFwicjItZm9vdG5vdGUtY29udGFpbmVyXCI7XG5jb25zdCBGT09UTk9URVNfQ0xPU0VfQlVUVE9OX0NMQVNTID0gXCJyMi1mb290bm90ZS1jbG9zZVwiO1xuY29uc3QgRk9PVE5PVEVfRk9SQ0VfU0hPVyA9IFwicjItZm9vdG5vdGUtZm9yY2Utc2hvd1wiO1xuY29uc3QgVFRTX0lEX1BSRVZJT1VTID0gXCJyMi10dHMtcHJldmlvdXNcIjtcbmNvbnN0IFRUU19JRF9ORVhUID0gXCJyMi10dHMtbmV4dFwiO1xuY29uc3QgVFRTX0lEX1NMSURFUiA9IFwicjItdHRzLXNsaWRlclwiO1xuY29uc3QgVFRTX0lEX0FDVElWRV9XT1JEID0gXCJyMi10dHMtYWN0aXZlLXdvcmRcIjtcbmNvbnN0IFRUU19JRF9DT05UQUlORVIgPSBcInIyLXR0cy10eHRcIjtcbmNvbnN0IFRUU19JRF9JTkZPID0gXCJyMi10dHMtaW5mb1wiO1xuY29uc3QgVFRTX05BVl9CVVRUT05fQ0xBU1MgPSBcInIyLXR0cy1idXR0b25cIjtcbmNvbnN0IFRUU19JRF9TUEVBS0lOR19ET0NfRUxFTUVOVCA9IFwicjItdHRzLXNwZWFraW5nLWVsXCI7XG5jb25zdCBUVFNfQ0xBU1NfSU5KRUNURURfU1BBTiA9IFwicjItdHRzLXNwZWFraW5nLXR4dFwiO1xuY29uc3QgVFRTX0NMQVNTX0lOSkVDVEVEX1NVQlNQQU4gPSBcInIyLXR0cy1zcGVha2luZy13b3JkXCI7XG5jb25zdCBUVFNfSURfSU5KRUNURURfUEFSRU5UID0gXCJyMi10dHMtc3BlYWtpbmctdHh0LXBhcmVudFwiO1xuY29uc3QgSURfSElHSExJR0hUU19DT05UQUlORVIgPSBcIlIyX0lEX0hJR0hMSUdIVFNfQ09OVEFJTkVSXCI7XG5jb25zdCBJRF9BTk5PVEFUSU9OX0NPTlRBSU5FUiA9IFwiUjJfSURfQU5OT1RBVElPTl9DT05UQUlORVJcIjtcbmNvbnN0IENMQVNTX0hJR0hMSUdIVF9DT05UQUlORVIgPSBcIlIyX0NMQVNTX0hJR0hMSUdIVF9DT05UQUlORVJcIjtcbmNvbnN0IENMQVNTX0FOTk9UQVRJT05fQ09OVEFJTkVSID0gXCJSMl9DTEFTU19BTk5PVEFUSU9OX0NPTlRBSU5FUlwiO1xuY29uc3QgQ0xBU1NfSElHSExJR0hUX0FSRUEgPSBcIlIyX0NMQVNTX0hJR0hMSUdIVF9BUkVBXCI7XG5jb25zdCBDTEFTU19BTk5PVEFUSU9OX0FSRUEgPSBcIlIyX0NMQVNTX0FOTk9UQVRJT05fQVJFQVwiO1xuY29uc3QgQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEgPSBcIlIyX0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBXCI7XG5jb25zdCBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUEgPSBcIlIyX0NMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQVwiO1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuY29uc3QgX2JsYWNrbGlzdElkQ2xhc3NGb3JDRkkgPSBbXG4gIFBPUFVQX0RJQUxPR19DTEFTUyxcbiAgVFRTX0NMQVNTX0lOSkVDVEVEX1NQQU4sXG4gIFRUU19DTEFTU19JTkpFQ1RFRF9TVUJTUEFOLFxuICBJRF9ISUdITElHSFRTX0NPTlRBSU5FUixcbiAgQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUixcbiAgQ0xBU1NfSElHSExJR0hUX0FSRUEsXG4gIENMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBLFxuICBcInJlc2l6ZS1zZW5zb3JcIixcbl07XG5jb25zdCBDTEFTU19QQUdJTkFURUQgPSBcInIyLWNzcy1wYWdpbmF0ZWRcIjtcblxuLy9jb25zdCBJU19ERVYgPSAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwiZGV2ZWxvcG1lbnRcIiB8fCBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJkZXZcIik7XG5jb25zdCBJU19ERVYgPSBmYWxzZTtcbmNvbnN0IF9oaWdobGlnaHRzID0gW107XG5cbmxldCBfaGlnaGxpZ2h0c0NvbnRhaW5lcjtcbmxldCBfYW5ub3RhdGlvbkNvbnRhaW5lcjtcbmxldCBsYXN0TW91c2VEb3duWCA9IC0xO1xubGV0IGxhc3RNb3VzZURvd25ZID0gLTE7XG5sZXQgYm9keUV2ZW50TGlzdGVuZXJzU2V0ID0gZmFsc2U7XG5cbmNvbnN0IFVTRV9TVkcgPSBmYWxzZTtcbmNvbnN0IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZID0gMC4zO1xuY29uc3QgQUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWSA9IDAuNDU7XG5cbi8vY29uc3QgREVCVUdfVklTVUFMUyA9IGZhbHNlO1xuY29uc3QgREVCVUdfVklTVUFMUyA9IGZhbHNlO1xuY29uc3QgREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SID0ge1xuICBibHVlOiAxMDAsXG4gIGdyZWVuOiA1MCxcbiAgcmVkOiAyMzAsXG59O1xuXG5jb25zdCBBTk5PVEFUSU9OX1dJRFRIID0gMTU7XG5cbmZ1bmN0aW9uIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZShfd2luLCBoaWdobGlnaHRCb3VuZGluZykge1xuICBpZiAoXG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgPT0gQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBXG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5vdXRsaW5lID0gXCJub25lXCI7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLnNldFByb3BlcnR5KFxuICAgIFwiYmFja2dyb3VuZC1jb2xvclwiLFxuICAgIFwidHJhbnNwYXJlbnRcIixcbiAgICBcImltcG9ydGFudFwiXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWFzLCBoaWdobGlnaHQpIHtcbiAgY29uc3QgdXNlU1ZHID0gIURFQlVHX1ZJU1VBTFMgJiYgVVNFX1NWRztcbiAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGhpZ2hsaWdodEFyZWFzKSB7XG4gICAgY29uc3QgaXNTVkcgPSB1c2VTVkcgJiYgaGlnaGxpZ2h0QXJlYS5uYW1lc3BhY2VVUkkgPT09IFNWR19YTUxfTkFNRVNQQUNFO1xuICAgIGNvbnN0IG9wYWNpdHkgPSBBTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZO1xuICAgIGlmIChpc1NWRykge1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgXCJmaWxsXCIsXG4gICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgXCJmaWxsLW9wYWNpdHlcIixcbiAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgXCJzdHJva2VcIixcbiAgICAgICAgYHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcInN0cm9rZS1vcGFjaXR5XCIsXG4gICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCIsXG4gICAgICAgIGByZ2JhKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0sICR7b3BhY2l0eX0pYCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKSB7XG4gIGNvbnN0IHVzZVNWRyA9ICFERUJVR19WSVNVQUxTICYmIFVTRV9TVkc7XG4gIC8vY29uc3QgdXNlU1ZHID0gVVNFX1NWRztcbiAgY29uc3QgaXNTVkcgPSB1c2VTVkcgJiYgaGlnaGxpZ2h0QXJlYS5uYW1lc3BhY2VVUkkgPT09IFNWR19YTUxfTkFNRVNQQUNFO1xuICBjb25zdCBpZCA9IGlzU1ZHXG4gICAgPyBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZVxuICAgICAgPyBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUoXCJpZFwiKVxuICAgICAgOiB1bmRlZmluZWRcbiAgICA6IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZVxuICAgID8gaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImlkXCIpXG4gICAgOiB1bmRlZmluZWQ7XG4gIGlmIChpZCkge1xuICAgIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzLmZpbmQoKGgpID0+IHtcbiAgICAgIHJldHVybiBoLmlkID09PSBpZDtcbiAgICB9KTtcbiAgICBpZiAoaGlnaGxpZ2h0KSB7XG4gICAgICBjb25zdCBvcGFjaXR5ID0gREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFk7XG4gICAgICBpZiAoaXNTVkcpIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcImZpbGxcIixcbiAgICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJmaWxsLW9wYWNpdHlcIixcbiAgICAgICAgICBgJHtvcGFjaXR5fWAsXG4gICAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwic3Ryb2tlXCIsXG4gICAgICAgICAgYHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KWAsXG4gICAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwic3Ryb2tlLW9wYWNpdHlcIixcbiAgICAgICAgICBgJHtvcGFjaXR5fWAsXG4gICAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIixcbiAgICAgICAgICBgcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KWAsXG4gICAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcHJvY2Vzc1RvdWNoRXZlbnQod2luLCBldikge1xuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuICBjb25zdCB4ID0gZXYuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WDtcbiAgY29uc3QgeSA9IGV2LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFk7XG4gIGlmICghX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBib2R5UmVjdCA9IGRvY3VtZW50LmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGxldCB4T2Zmc2V0O1xuICBsZXQgeU9mZnNldDtcbiAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCA6IGJvZHlSZWN0LmxlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCA6IGJvZHlSZWN0LnRvcDtcbiAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICB9XG4gIGxldCBmb3VuZEhpZ2hsaWdodDtcbiAgbGV0IGZvdW5kRWxlbWVudDtcbiAgbGV0IGZvdW5kUmVjdDtcbiAgLy8gICAgX2hpZ2hsaWdodHMuc29ydChmdW5jdGlvbihhLCBiKSB7XG4gIC8vICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShhLnNlbGVjdGlvbkluZm8pKVxuICAvLyAgICAgICAgcmV0dXJuIGEuc2VsZWN0aW9uSW5mby5jbGVhblRleHQubGVuZ3RoIDwgYi5zZWxlY3Rpb25JbmZvLmNsZWFuVGV4dC5sZW5ndGhcbiAgLy8gICAgfSlcbiAgZm9yIChsZXQgaSA9IF9oaWdobGlnaHRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHNbaV07XG4gICAgbGV0IGhpZ2hsaWdodFBhcmVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGAke2hpZ2hsaWdodC5pZH1gKTtcbiAgICBpZiAoIWhpZ2hsaWdodFBhcmVudCkge1xuICAgICAgaGlnaGxpZ2h0UGFyZW50ID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvcihgIyR7aGlnaGxpZ2h0LmlkfWApO1xuICAgIH1cbiAgICBpZiAoIWhpZ2hsaWdodFBhcmVudCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGxldCBoaXQgPSBmYWxzZTtcbiAgICBjb25zdCBoaWdobGlnaHRGcmFnbWVudHMgPSBoaWdobGlnaHRQYXJlbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEZyYWdtZW50IG9mIGhpZ2hsaWdodEZyYWdtZW50cykge1xuICAgICAgY29uc3Qgd2l0aFJlY3QgPSBoaWdobGlnaHRGcmFnbWVudDtcbiAgICAgIGNvbnN0IGxlZnQgPSB3aXRoUmVjdC5yZWN0LmxlZnQgKyB4T2Zmc2V0O1xuICAgICAgY29uc3QgdG9wID0gd2l0aFJlY3QucmVjdC50b3AgKyB5T2Zmc2V0O1xuICAgICAgZm91bmRSZWN0ID0gd2l0aFJlY3QucmVjdDtcbiAgICAgIGlmIChcbiAgICAgICAgeCA+PSBsZWZ0ICYmXG4gICAgICAgIHggPCBsZWZ0ICsgd2l0aFJlY3QucmVjdC53aWR0aCAmJlxuICAgICAgICB5ID49IHRvcCAmJlxuICAgICAgICB5IDwgdG9wICsgd2l0aFJlY3QucmVjdC5oZWlnaHRcbiAgICAgICkge1xuICAgICAgICBoaXQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGhpdCkge1xuICAgICAgZm91bmRIaWdobGlnaHQgPSBoaWdobGlnaHQ7XG4gICAgICBmb3VuZEVsZW1lbnQgPSBoaWdobGlnaHRQYXJlbnQ7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKCFmb3VuZEhpZ2hsaWdodCB8fCAhZm91bmRFbGVtZW50KSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKHdpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICAgIH1cbiAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoZm91bmRFbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtY2xpY2tcIikpIHtcbiAgICBpZiAoZXYudHlwZSA9PT0gXCJtb3VzZW1vdmVcIikge1xuICAgICAgY29uc3QgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBmb3VuZEVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YClcbiAgICAgICk7XG4gICAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcy5pbmRleE9mKGhpZ2hsaWdodEFyZWEpIDwgMCkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLCBmb3VuZEhpZ2hsaWdodCk7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyA9IGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEJvdW5kaW5ncyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRCb3VuZGluZyBvZiBhbGxIaWdobGlnaHRCb3VuZGluZ3MpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyB8fFxuICAgICAgICAgIGhpZ2hsaWdodEJvdW5kaW5nICE9PSBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZ1xuICAgICAgICApIHtcbiAgICAgICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZykge1xuICAgICAgICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgICAgICAgIHNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUoXG4gICAgICAgICAgICB3aW4sXG4gICAgICAgICAgICBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyxcbiAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXYudHlwZSA9PT0gXCJ0b3VjaHN0YXJ0XCIgfHwgZXYudHlwZSA9PT0gXCJ0b3VjaGVuZFwiKSB7XG4gICAgICBjb25zdCBzaXplID0ge1xuICAgICAgICBzY3JlZW5XaWR0aDogd2luZG93Lm91dGVyV2lkdGgsXG4gICAgICAgIHNjcmVlbkhlaWdodDogd2luZG93Lm91dGVySGVpZ2h0LFxuICAgICAgICBsZWZ0OiBmb3VuZFJlY3QubGVmdCxcbiAgICAgICAgd2lkdGg6IGZvdW5kUmVjdC53aWR0aCxcbiAgICAgICAgdG9wOiBmb3VuZFJlY3QudG9wLFxuICAgICAgICBoZWlnaHQ6IGZvdW5kUmVjdC5oZWlnaHQsXG4gICAgICB9O1xuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgaGlnaGxpZ2h0OiBmb3VuZEhpZ2hsaWdodC5pZCxcbiAgICAgICAgc2l6ZTogc2l6ZSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICB0eXBlb2Ygd2luZG93LnByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgd2luZG93LnByb2Nlc3MudHlwZSA9PT0gXCJyZW5kZXJlclwiXG4gICAgICApIHtcbiAgICAgICAgZWxlY3Ryb25fMS5pcGNSZW5kZXJlci5zZW5kVG9Ib3N0KFIyX0VWRU5UX0hJR0hMSUdIVF9DTElDSywgcGF5bG9hZCk7XG4gICAgICB9IGVsc2UgaWYgKHdpbmRvdy53ZWJraXRVUkwpIHtcbiAgICAgICAgY29uc29sZS5sb2coZm91bmRIaWdobGlnaHQuaWQuaW5jbHVkZXMoXCJSMl9BTk5PVEFUSU9OX1wiKSk7XG4gICAgICAgIGlmIChmb3VuZEhpZ2hsaWdodC5pZC5zZWFyY2goXCJSMl9BTk5PVEFUSU9OX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQoZm91bmRIaWdobGlnaHQuaWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgICAgICAgICAgd2Via2l0Lm1lc3NhZ2VIYW5kbGVycy5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0hJR0hMSUdIVF9cIikgPj0gMCkge1xuICAgICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgICAgICAgICBBbmRyb2lkLmhpZ2hsaWdodEFjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc01vdXNlRXZlbnQod2luLCBldikge1xuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuICBjb25zdCB4ID0gZXYuY2xpZW50WDtcbiAgY29uc3QgeSA9IGV2LmNsaWVudFk7XG4gIGlmICghX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBwYWdpbmF0ZWQgPSBpc1BhZ2luYXRlZChkb2N1bWVudCk7XG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgbGV0IHhPZmZzZXQ7XG4gIGxldCB5T2Zmc2V0O1xuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0IDogYm9keVJlY3QubGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiBib2R5UmVjdC50b3A7XG4gIH1cbiAgbGV0IGZvdW5kSGlnaGxpZ2h0O1xuICBsZXQgZm91bmRFbGVtZW50O1xuICBsZXQgZm91bmRSZWN0O1xuICBmb3IgKGxldCBpID0gX2hpZ2hsaWdodHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0c1tpXTtcbiAgICBsZXQgaGlnaGxpZ2h0UGFyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYCR7aGlnaGxpZ2h0LmlkfWApO1xuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBoaWdobGlnaHRQYXJlbnQgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGAjJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgfVxuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbGV0IGhpdCA9IGZhbHNlO1xuICAgIGNvbnN0IGhpZ2hsaWdodEZyYWdtZW50cyA9IGhpZ2hsaWdodFBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnQgb2YgaGlnaGxpZ2h0RnJhZ21lbnRzKSB7XG4gICAgICBjb25zdCB3aXRoUmVjdCA9IGhpZ2hsaWdodEZyYWdtZW50O1xuICAgICAgY29uc3QgbGVmdCA9IHdpdGhSZWN0LnJlY3QubGVmdCArIHhPZmZzZXQ7XG4gICAgICBjb25zdCB0b3AgPSB3aXRoUmVjdC5yZWN0LnRvcCArIHlPZmZzZXQ7XG4gICAgICBmb3VuZFJlY3QgPSB3aXRoUmVjdC5yZWN0O1xuICAgICAgaWYgKFxuICAgICAgICB4ID49IGxlZnQgJiZcbiAgICAgICAgeCA8IGxlZnQgKyB3aXRoUmVjdC5yZWN0LndpZHRoICYmXG4gICAgICAgIHkgPj0gdG9wICYmXG4gICAgICAgIHkgPCB0b3AgKyB3aXRoUmVjdC5yZWN0LmhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIGhpdCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaGl0KSB7XG4gICAgICBmb3VuZEhpZ2hsaWdodCA9IGhpZ2hsaWdodDtcbiAgICAgIGZvdW5kRWxlbWVudCA9IGhpZ2hsaWdodFBhcmVudDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmICghZm91bmRIaWdobGlnaHQgfHwgIWZvdW5kRWxlbWVudCkge1xuICAgIGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5ncyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRCb3VuZGluZyBvZiBoaWdobGlnaHRCb3VuZGluZ3MpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICB9XG4gICAgY29uc3QgYWxsSGlnaGxpZ2h0QXJlYXMgPSBBcnJheS5mcm9tKFxuICAgICAgX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YClcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBhbGxIaWdobGlnaHRBcmVhcykge1xuICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGZvdW5kRWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNsaWNrXCIpKSB7XG4gICAgaWYgKGV2LnR5cGUgPT09IFwibW91c2Vtb3ZlXCIpIHtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgICAgZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0QXJlYXMgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBhbGxIaWdobGlnaHRBcmVhcykge1xuICAgICAgICBpZiAoZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMuaW5kZXhPZihoaWdobGlnaHRBcmVhKSA8IDApIHtcbiAgICAgICAgICByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcywgZm91bmRIaWdobGlnaHQpO1xuICAgICAgY29uc3QgZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcgPSBmb3VuZEVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBjb25zdCBhbGxIaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcgfHxcbiAgICAgICAgICBoaWdobGlnaHRCb3VuZGluZyAhPT0gZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmdcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKHdpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcpIHtcbiAgICAgICAgaWYgKERFQlVHX1ZJU1VBTFMpIHtcbiAgICAgICAgICBzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKFxuICAgICAgICAgICAgd2luLFxuICAgICAgICAgICAgZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcsXG4gICAgICAgICAgICBmb3VuZEhpZ2hsaWdodFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2LnR5cGUgPT09IFwibW91c2V1cFwiIHx8IGV2LnR5cGUgPT09IFwidG91Y2hlbmRcIikge1xuICAgICAgY29uc3QgdG91Y2hlZFBvc2l0aW9uID0ge1xuICAgICAgICBzY3JlZW5XaWR0aDogd2luZG93Lm91dGVyV2lkdGgsXG4gICAgICAgIHNjcmVlbkhlaWdodDogd2luZG93LmlubmVySGVpZ2h0LFxuICAgICAgICBsZWZ0OiBmb3VuZFJlY3QubGVmdCxcbiAgICAgICAgd2lkdGg6IGZvdW5kUmVjdC53aWR0aCxcbiAgICAgICAgdG9wOiBmb3VuZFJlY3QudG9wLFxuICAgICAgICBoZWlnaHQ6IGZvdW5kUmVjdC5oZWlnaHQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBoaWdobGlnaHQ6IGZvdW5kSGlnaGxpZ2h0LFxuICAgICAgICBwb3NpdGlvbjogdG91Y2hlZFBvc2l0aW9uLFxuICAgICAgfTtcblxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgIHR5cGVvZiB3aW5kb3cucHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICB3aW5kb3cucHJvY2Vzcy50eXBlID09PSBcInJlbmRlcmVyXCJcbiAgICAgICkge1xuICAgICAgICBlbGVjdHJvbl8xLmlwY1JlbmRlcmVyLnNlbmRUb0hvc3QoUjJfRVZFTlRfSElHSExJR0hUX0NMSUNLLCBwYXlsb2FkKTtcbiAgICAgIH0gZWxzZSBpZiAod2luZG93LndlYmtpdFVSTCkge1xuICAgICAgICBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfQU5OT1RBVElPTl9cIikgPj0gMCkge1xuICAgICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgICAgICAgICBBbmRyb2lkLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0LmlkXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChmb3VuZEhpZ2hsaWdodC5pZC5zZWFyY2goXCJSMl9ISUdITElHSFRfXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBY3RpdmF0ZWQoZm91bmRIaWdobGlnaHQuaWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgICAgICAgICAgd2Via2l0Lm1lc3NhZ2VIYW5kbGVycy5oaWdobGlnaHRBY3RpdmF0ZWQucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0LmlkXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0MS5sZWZ0IDwgcmVjdDIucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLmxlZnQgPCByZWN0MS5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLmxlZnQsIHJlY3QxLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDEudG9wIDwgcmVjdDIuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi50b3AgPCByZWN0MS5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi50b3AsIHJlY3QxLmJvdHRvbSwgdG9sZXJhbmNlKSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMocmVjdHMpIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyByZWN0MSA9PT0gcmVjdDIgPz8hXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgbGV0IHRvQWRkID0gW107XG4gICAgICAgIGxldCB0b1JlbW92ZTtcbiAgICAgICAgbGV0IHRvUHJlc2VydmU7XG4gICAgICAgIGNvbnN0IHN1YnRyYWN0UmVjdHMxID0gcmVjdFN1YnRyYWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDE7XG4gICAgICAgICAgdG9QcmVzZXJ2ZSA9IHJlY3QyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHN1YnRyYWN0UmVjdHMyID0gcmVjdFN1YnRyYWN0KHJlY3QyLCByZWN0MSk7XG4gICAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA8IHN1YnRyYWN0UmVjdHMyLmxlbmd0aCkge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMTtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDE7XG4gICAgICAgICAgICB0b1ByZXNlcnZlID0gcmVjdDI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czI7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QyO1xuICAgICAgICAgICAgdG9QcmVzZXJ2ZSA9IHJlY3QxO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc3QgdG9DaGVjayA9IFtdO1xuICAgICAgICAgIHRvQ2hlY2sucHVzaCh0b1ByZXNlcnZlKTtcbiAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0b0NoZWNrLCB0b0FkZCk7XG4gICAgICAgICAgY2hlY2tPdmVybGFwcyh0b0NoZWNrKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgQ0xJRU5UIFJFQ1Q6IG92ZXJsYXAsIGN1dCBvbmUgcmVjdCBpbnRvICR7dG9BZGQubGVuZ3RofWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHRvUmVtb3ZlO1xuICAgICAgICB9KTtcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkobmV3UmVjdHMsIHRvQWRkKTtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobmV3UmVjdHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIGNoZWNrT3ZlcmxhcHMocmVjdHMpIHtcbiAgY29uc3Qgc3RpbGxPdmVybGFwaW5nUmVjdHMgPSBbXTtcbiAgZm9yIChjb25zdCByZWN0MSBvZiByZWN0cykge1xuICAgIGZvciAoY29uc3QgcmVjdDIgb2YgcmVjdHMpIHtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBoYXMxID0gc3RpbGxPdmVybGFwaW5nUmVjdHMuaW5kZXhPZihyZWN0MSkgPj0gMDtcbiAgICAgIGNvbnN0IGhhczIgPSBzdGlsbE92ZXJsYXBpbmdSZWN0cy5pbmRleE9mKHJlY3QyKSA+PSAwO1xuICAgICAgaWYgKCFoYXMxIHx8ICFoYXMyKSB7XG4gICAgICAgIGlmIChyZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgLTEpKSB7XG4gICAgICAgICAgaWYgKCFoYXMxKSB7XG4gICAgICAgICAgICBzdGlsbE92ZXJsYXBpbmdSZWN0cy5wdXNoKHJlY3QxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFoYXMyKSB7XG4gICAgICAgICAgICBzdGlsbE92ZXJsYXBpbmdSZWN0cy5wdXNoKHJlY3QyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogb3ZlcmxhcCAtLS1cIik7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgIzEgVE9QOiR7cmVjdDEudG9wfSBCT1RUT006JHtyZWN0MS5ib3R0b219IExFRlQ6JHtyZWN0MS5sZWZ0fSBSSUdIVDoke3JlY3QxLnJpZ2h0fSBXSURUSDoke3JlY3QxLndpZHRofSBIRUlHSFQ6JHtyZWN0MS5oZWlnaHR9YFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgIzIgVE9QOiR7cmVjdDIudG9wfSBCT1RUT006JHtyZWN0Mi5ib3R0b219IExFRlQ6JHtyZWN0Mi5sZWZ0fSBSSUdIVDoke3JlY3QyLnJpZ2h0fSBXSURUSDoke3JlY3QyLndpZHRofSBIRUlHSFQ6JHtyZWN0Mi5oZWlnaHR9YFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgeE92ZXJsYXAgPSBnZXRSZWN0T3ZlcmxhcFgocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgeE92ZXJsYXA6ICR7eE92ZXJsYXB9YCk7XG4gICAgICAgICAgY29uc3QgeU92ZXJsYXAgPSBnZXRSZWN0T3ZlcmxhcFkocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgeU92ZXJsYXA6ICR7eU92ZXJsYXB9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKHN0aWxsT3ZlcmxhcGluZ1JlY3RzLmxlbmd0aCkge1xuICAgIGNvbnNvbGUubG9nKGBDTElFTlQgUkVDVDogb3ZlcmxhcHMgJHtzdGlsbE92ZXJsYXBpbmdSZWN0cy5sZW5ndGh9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlQ29udGFpbmVkUmVjdHMocmVjdHMsIHRvbGVyYW5jZSkge1xuICBjb25zdCByZWN0c1RvS2VlcCA9IG5ldyBTZXQocmVjdHMpO1xuICBmb3IgKGNvbnN0IHJlY3Qgb2YgcmVjdHMpIHtcbiAgICBjb25zdCBiaWdFbm91Z2ggPSByZWN0LndpZHRoID4gMSAmJiByZWN0LmhlaWdodCA+IDE7XG4gICAgaWYgKCFiaWdFbm91Z2gpIHtcbiAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHRpbnlcIik7XG4gICAgICB9XG4gICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwb3NzaWJseUNvbnRhaW5pbmdSZWN0IG9mIHJlY3RzKSB7XG4gICAgICBpZiAocmVjdCA9PT0gcG9zc2libHlDb250YWluaW5nUmVjdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjdHNUb0tlZXAuaGFzKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RDb250YWlucyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0LCByZWN0LCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgY29udGFpbmVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJlY3RzVG9LZWVwLmRlbGV0ZShyZWN0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBBcnJheS5mcm9tKHJlY3RzVG9LZWVwKTtcbn1cblxuZnVuY3Rpb24gYWxtb3N0RXF1YWwoYSwgYiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiBNYXRoLmFicyhhIC0gYikgPD0gdG9sZXJhbmNlO1xufVxuXG5mdW5jdGlvbiByZWN0SW50ZXJzZWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCBtYXhMZWZ0ID0gTWF0aC5tYXgocmVjdDEubGVmdCwgcmVjdDIubGVmdCk7XG4gIGNvbnN0IG1pblJpZ2h0ID0gTWF0aC5taW4ocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0KTtcbiAgY29uc3QgbWF4VG9wID0gTWF0aC5tYXgocmVjdDEudG9wLCByZWN0Mi50b3ApO1xuICBjb25zdCBtaW5Cb3R0b20gPSBNYXRoLm1pbihyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSk7XG4gIGNvbnN0IHJlY3QgPSB7XG4gICAgYm90dG9tOiBtaW5Cb3R0b20sXG4gICAgaGVpZ2h0OiBNYXRoLm1heCgwLCBtaW5Cb3R0b20gLSBtYXhUb3ApLFxuICAgIGxlZnQ6IG1heExlZnQsXG4gICAgcmlnaHQ6IG1pblJpZ2h0LFxuICAgIHRvcDogbWF4VG9wLFxuICAgIHdpZHRoOiBNYXRoLm1heCgwLCBtaW5SaWdodCAtIG1heExlZnQpLFxuICB9O1xuICByZXR1cm4gcmVjdDtcbn1cblxuZnVuY3Rpb24gcmVjdFN1YnRyYWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCByZWN0SW50ZXJzZWN0ZWQgPSByZWN0SW50ZXJzZWN0KHJlY3QyLCByZWN0MSk7XG4gIGlmIChyZWN0SW50ZXJzZWN0ZWQuaGVpZ2h0ID09PSAwIHx8IHJlY3RJbnRlcnNlY3RlZC53aWR0aCA9PT0gMCkge1xuICAgIHJldHVybiBbcmVjdDFdO1xuICB9XG4gIGNvbnN0IHJlY3RzID0gW107XG4gIHtcbiAgICBjb25zdCByZWN0QSA9IHtcbiAgICAgIGJvdHRvbTogcmVjdDEuYm90dG9tLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdDEubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0QS53aWR0aCA9IHJlY3RBLnJpZ2h0IC0gcmVjdEEubGVmdDtcbiAgICByZWN0QS5oZWlnaHQgPSByZWN0QS5ib3R0b20gLSByZWN0QS50b3A7XG4gICAgaWYgKHJlY3RBLmhlaWdodCAhPT0gMCAmJiByZWN0QS53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0QSk7XG4gICAgfVxuICB9XG4gIHtcbiAgICBjb25zdCByZWN0QiA9IHtcbiAgICAgIGJvdHRvbTogcmVjdEludGVyc2VjdGVkLnRvcCxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0Qi53aWR0aCA9IHJlY3RCLnJpZ2h0IC0gcmVjdEIubGVmdDtcbiAgICByZWN0Qi5oZWlnaHQgPSByZWN0Qi5ib3R0b20gLSByZWN0Qi50b3A7XG4gICAgaWYgKHJlY3RCLmhlaWdodCAhPT0gMCAmJiByZWN0Qi53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0Qik7XG4gICAgfVxuICB9XG4gIHtcbiAgICBjb25zdCByZWN0QyA9IHtcbiAgICAgIGJvdHRvbTogcmVjdDEuYm90dG9tLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0SW50ZXJzZWN0ZWQuYm90dG9tLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0Qy53aWR0aCA9IHJlY3RDLnJpZ2h0IC0gcmVjdEMubGVmdDtcbiAgICByZWN0Qy5oZWlnaHQgPSByZWN0Qy5ib3R0b20gLSByZWN0Qy50b3A7XG4gICAgaWYgKHJlY3RDLmhlaWdodCAhPT0gMCAmJiByZWN0Qy53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0Qyk7XG4gICAgfVxuICB9XG4gIHtcbiAgICBjb25zdCByZWN0RCA9IHtcbiAgICAgIGJvdHRvbTogcmVjdDEuYm90dG9tLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgcmlnaHQ6IHJlY3QxLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RELndpZHRoID0gcmVjdEQucmlnaHQgLSByZWN0RC5sZWZ0O1xuICAgIHJlY3RELmhlaWdodCA9IHJlY3RELmJvdHRvbSAtIHJlY3RELnRvcDtcbiAgICBpZiAocmVjdEQuaGVpZ2h0ICE9PSAwICYmIHJlY3RELndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3REKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiByZWN0Q29udGFpbnNQb2ludChyZWN0LCB4LCB5LCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICAocmVjdC5sZWZ0IDwgeCB8fCBhbG1vc3RFcXVhbChyZWN0LmxlZnQsIHgsIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QucmlnaHQgPiB4IHx8IGFsbW9zdEVxdWFsKHJlY3QucmlnaHQsIHgsIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QudG9wIDwgeSB8fCBhbG1vc3RFcXVhbChyZWN0LnRvcCwgeSwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5ib3R0b20gPiB5IHx8IGFsbW9zdEVxdWFsKHJlY3QuYm90dG9tLCB5LCB0b2xlcmFuY2UpKVxuICApO1xufVxuXG5mdW5jdGlvbiByZWN0Q29udGFpbnMocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCBsZWZ0ID0gTWF0aC5taW4ocmVjdDEubGVmdCwgcmVjdDIubGVmdCk7XG4gIGNvbnN0IHJpZ2h0ID0gTWF0aC5tYXgocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0KTtcbiAgY29uc3QgdG9wID0gTWF0aC5taW4ocmVjdDEudG9wLCByZWN0Mi50b3ApO1xuICBjb25zdCBib3R0b20gPSBNYXRoLm1heChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSk7XG4gIHJldHVybiB7XG4gICAgYm90dG9tLFxuICAgIGhlaWdodDogYm90dG9tIC0gdG9wLFxuICAgIGxlZnQsXG4gICAgcmlnaHQsXG4gICAgdG9wLFxuICAgIHdpZHRoOiByaWdodCAtIGxlZnQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgcmVjdHMsXG4gIHRvbGVyYW5jZSxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCByZWN0cy5sZW5ndGg7IGorKykge1xuICAgICAgY29uc3QgcmVjdDEgPSByZWN0c1tpXTtcbiAgICAgIGNvbnN0IHJlY3QyID0gcmVjdHNbal07XG4gICAgICBpZiAocmVjdDEgPT09IHJlY3QyKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIm1lcmdlVG91Y2hpbmdSZWN0cyByZWN0MSA9PT0gcmVjdDIgPz8hXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVjdHNMaW5lVXBWZXJ0aWNhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCByZWN0c0xpbmVVcEhvcml6b250YWxseSA9XG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpO1xuICAgICAgY29uc3QgaG9yaXpvbnRhbEFsbG93ZWQgPSAhZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cztcbiAgICAgIGNvbnN0IGFsaWduZWQgPVxuICAgICAgICAocmVjdHNMaW5lVXBIb3Jpem9udGFsbHkgJiYgaG9yaXpvbnRhbEFsbG93ZWQpIHx8XG4gICAgICAgIChyZWN0c0xpbmVVcFZlcnRpY2FsbHkgJiYgIXJlY3RzTGluZVVwSG9yaXpvbnRhbGx5KTtcbiAgICAgIGNvbnN0IGNhbk1lcmdlID0gYWxpZ25lZCAmJiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKTtcbiAgICAgIGlmIChjYW5NZXJnZSkge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgQ0xJRU5UIFJFQ1Q6IG1lcmdpbmcgdHdvIGludG8gb25lLCBWRVJUSUNBTDogJHtyZWN0c0xpbmVVcFZlcnRpY2FsbHl9IEhPUklaT05UQUw6ICR7cmVjdHNMaW5lVXBIb3Jpem9udGFsbHl9ICgke2RvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHN9KWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHJlY3QxICYmIHJlY3QgIT09IHJlY3QyO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVwbGFjZW1lbnRDbGllbnRSZWN0ID0gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIG5ld1JlY3RzLnB1c2gocmVwbGFjZW1lbnRDbGllbnRSZWN0KTtcbiAgICAgICAgcmV0dXJuIG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICAgICAgICBuZXdSZWN0cyxcbiAgICAgICAgICB0b2xlcmFuY2UsXG4gICAgICAgICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwKHJhbmdlLCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzKSB7XG4gIGNvbnN0IHJhbmdlQ2xpZW50UmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xuICByZXR1cm4gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXBfKFxuICAgIHJhbmdlQ2xpZW50UmVjdHMsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xufVxuXG5mdW5jdGlvbiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcF8oXG4gIGNsaWVudFJlY3RzLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgY29uc3QgdG9sZXJhbmNlID0gMTtcbiAgY29uc3Qgb3JpZ2luYWxSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJhbmdlQ2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIG9yaWdpbmFsUmVjdHMucHVzaCh7XG4gICAgICBib3R0b206IHJhbmdlQ2xpZW50UmVjdC5ib3R0b20sXG4gICAgICBoZWlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUNsaWVudFJlY3QubGVmdCxcbiAgICAgIHJpZ2h0OiByYW5nZUNsaWVudFJlY3QucmlnaHQsXG4gICAgICB0b3A6IHJhbmdlQ2xpZW50UmVjdC50b3AsXG4gICAgICB3aWR0aDogcmFuZ2VDbGllbnRSZWN0LndpZHRoLFxuICAgIH0pO1xuICB9XG4gIGNvbnN0IG1lcmdlZFJlY3RzID0gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgIG9yaWdpbmFsUmVjdHMsXG4gICAgdG9sZXJhbmNlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgY29uc3Qgbm9Db250YWluZWRSZWN0cyA9IHJlbW92ZUNvbnRhaW5lZFJlY3RzKG1lcmdlZFJlY3RzLCB0b2xlcmFuY2UpO1xuICBjb25zdCBuZXdSZWN0cyA9IHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobm9Db250YWluZWRSZWN0cyk7XG4gIGNvbnN0IG1pbkFyZWEgPSAyICogMjtcbiAgZm9yIChsZXQgaiA9IG5ld1JlY3RzLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgY29uc3QgcmVjdCA9IG5ld1JlY3RzW2pdO1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggKiByZWN0LmhlaWdodCA+IG1pbkFyZWE7XG4gICAgaWYgKCFiaWdFbm91Z2gpIHtcbiAgICAgIGlmIChuZXdSZWN0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGxcIik7XG4gICAgICAgIH1cbiAgICAgICAgbmV3UmVjdHMuc3BsaWNlKGosIDEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBzbWFsbCwgYnV0IGtlZXAgb3RoZXJ3aXNlIGVtcHR5IVwiKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKElTX0RFVikge1xuICAgIGNoZWNrT3ZlcmxhcHMobmV3UmVjdHMpO1xuICB9XG4gIGlmIChJU19ERVYpIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBDTElFTlQgUkVDVDogcmVkdWNlZCAke29yaWdpbmFsUmVjdHMubGVuZ3RofSAtLT4gJHtuZXdSZWN0cy5sZW5ndGh9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIG5ld1JlY3RzO1xufVxuXG5mdW5jdGlvbiBpc1BhZ2luYXRlZChkb2N1bWVudCkge1xuICByZXR1cm4gKFxuICAgIGRvY3VtZW50ICYmXG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmXG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19QQUdJTkFURUQpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpIHtcbiAgaWYgKGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudDtcbiAgfVxuICByZXR1cm4gZG9jdW1lbnQuYm9keTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlQ29udGFpbmVyKHdpbiwgYW5ub3RhdGlvbkZsYWcpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG5cbiAgaWYgKCFfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIGlmICghYm9keUV2ZW50TGlzdGVuZXJzU2V0KSB7XG4gICAgICBib2R5RXZlbnRMaXN0ZW5lcnNTZXQgPSB0cnVlO1xuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcIm1vdXNlZG93blwiLFxuICAgICAgICAoZXYpID0+IHtcbiAgICAgICAgICBsYXN0TW91c2VEb3duWCA9IGV2LmNsaWVudFg7XG4gICAgICAgICAgbGFzdE1vdXNlRG93blkgPSBldi5jbGllbnRZO1xuICAgICAgICB9LFxuICAgICAgICBmYWxzZVxuICAgICAgKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJtb3VzZXVwXCIsXG4gICAgICAgIChldikgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIE1hdGguYWJzKGxhc3RNb3VzZURvd25YIC0gZXYuY2xpZW50WCkgPCAzICYmXG4gICAgICAgICAgICBNYXRoLmFicyhsYXN0TW91c2VEb3duWSAtIGV2LmNsaWVudFkpIDwgM1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgcHJvY2Vzc01vdXNlRXZlbnQod2luLCBldik7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmYWxzZVxuICAgICAgKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJtb3VzZW1vdmVcIixcbiAgICAgICAgKGV2KSA9PiB7XG4gICAgICAgICAgcHJvY2Vzc01vdXNlRXZlbnQod2luLCBldik7XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuXG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwidG91Y2hlbmRcIixcbiAgICAgICAgZnVuY3Rpb24gdG91Y2hFbmQoZSkge1xuICAgICAgICAgIHByb2Nlc3NUb3VjaEV2ZW50KHdpbiwgZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgIH1cbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgX2hpZ2hsaWdodHNDb250YWluZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgSURfSElHSExJR0hUU19DT05UQUlORVIpO1xuXG4gICAgX2hpZ2hsaWdodHNDb250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoX2hpZ2hsaWdodHNDb250YWluZXIpO1xuICB9XG5cbiAgcmV0dXJuIF9oaWdobGlnaHRzQ29udGFpbmVyO1xufVxuXG5mdW5jdGlvbiBoaWRlQWxsaGlnaGxpZ2h0cygpIHtcbiAgaWYgKF9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgX2hpZ2hsaWdodHNDb250YWluZXIucmVtb3ZlKCk7XG4gICAgX2hpZ2hsaWdodHNDb250YWluZXIgPSBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRlc3Ryb3lBbGxoaWdobGlnaHRzKCkge1xuICBoaWRlQWxsaGlnaGxpZ2h0cygpO1xuICBfaGlnaGxpZ2h0cy5zcGxpY2UoMCwgX2hpZ2hsaWdodHMubGVuZ3RoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lIaWdobGlnaHQoaWQpIHtcbiAgbGV0IGkgPSAtMTtcbiAgbGV0IF9kb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDtcbiAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCwgaikgPT4ge1xuICAgIGkgPSBqO1xuICAgIHJldHVybiBoLmlkID09PSBpZDtcbiAgfSk7XG4gIGlmIChoaWdobGlnaHQgJiYgaSA+PSAwICYmIGkgPCBfaGlnaGxpZ2h0cy5sZW5ndGgpIHtcbiAgICBfaGlnaGxpZ2h0cy5zcGxpY2UoaSwgMSk7XG4gIH1cbiAgY29uc3QgaGlnaGxpZ2h0Q29udGFpbmVyID0gX2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgaWYgKGhpZ2hsaWdodENvbnRhaW5lcikge1xuICAgIGhpZ2hsaWdodENvbnRhaW5lci5yZW1vdmUoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0NmaVRleHROb2RlKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFO1xufVxuXG5mdW5jdGlvbiBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoZWxlbWVudCwgY2hpbGQpIHtcbiAgbGV0IGZvdW5kID0gLTE7XG4gIGxldCB0ZXh0Tm9kZUluZGV4ID0gLTE7XG4gIGxldCBwcmV2aW91c1dhc0VsZW1lbnQgPSBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGlsZE5vZGUgPSBlbGVtZW50LmNoaWxkTm9kZXNbaV07XG4gICAgY29uc3QgaXNUZXh0ID0gaXNDZmlUZXh0Tm9kZShjaGlsZE5vZGUpO1xuICAgIGlmIChpc1RleHQgfHwgcHJldmlvdXNXYXNFbGVtZW50KSB7XG4gICAgICB0ZXh0Tm9kZUluZGV4ICs9IDI7XG4gICAgfVxuICAgIGlmIChpc1RleHQpIHtcbiAgICAgIGlmIChjaGlsZE5vZGUgPT09IGNoaWxkKSB7XG4gICAgICAgIGZvdW5kID0gdGV4dE5vZGVJbmRleDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHByZXZpb3VzV2FzRWxlbWVudCA9IGNoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7XG4gIH1cbiAgcmV0dXJuIGZvdW5kO1xufVxuXG5mdW5jdGlvbiBnZXRDb21tb25BbmNlc3RvckVsZW1lbnQobm9kZTEsIG5vZGUyKSB7XG4gIGlmIChub2RlMS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgbm9kZTEgPT09IG5vZGUyKSB7XG4gICAgcmV0dXJuIG5vZGUxO1xuICB9XG4gIGlmIChub2RlMS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgbm9kZTEuY29udGFpbnMobm9kZTIpKSB7XG4gICAgcmV0dXJuIG5vZGUxO1xuICB9XG4gIGlmIChub2RlMi5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgbm9kZTIuY29udGFpbnMobm9kZTEpKSB7XG4gICAgcmV0dXJuIG5vZGUyO1xuICB9XG4gIGNvbnN0IG5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4gPSBbXTtcbiAgbGV0IHBhcmVudCA9IG5vZGUxLnBhcmVudE5vZGU7XG4gIHdoaWxlIChwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIG5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4ucHVzaChwYXJlbnQpO1xuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xuICB9XG4gIGNvbnN0IG5vZGUyRWxlbWVudEFuY2VzdG9yQ2hhaW4gPSBbXTtcbiAgcGFyZW50ID0gbm9kZTIucGFyZW50Tm9kZTtcbiAgd2hpbGUgKHBhcmVudCAmJiBwYXJlbnQubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbi5wdXNoKHBhcmVudCk7XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XG4gIH1cbiAgbGV0IGNvbW1vbkFuY2VzdG9yID0gbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbi5maW5kKFxuICAgIChub2RlMUVsZW1lbnRBbmNlc3RvcikgPT4ge1xuICAgICAgcmV0dXJuIG5vZGUyRWxlbWVudEFuY2VzdG9yQ2hhaW4uaW5kZXhPZihub2RlMUVsZW1lbnRBbmNlc3RvcikgPj0gMDtcbiAgICB9XG4gICk7XG4gIGlmICghY29tbW9uQW5jZXN0b3IpIHtcbiAgICBjb21tb25BbmNlc3RvciA9IG5vZGUyRWxlbWVudEFuY2VzdG9yQ2hhaW4uZmluZCgobm9kZTJFbGVtZW50QW5jZXN0b3IpID0+IHtcbiAgICAgIHJldHVybiBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluLmluZGV4T2Yobm9kZTJFbGVtZW50QW5jZXN0b3IpID49IDA7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNvbW1vbkFuY2VzdG9yO1xufVxuXG5mdW5jdGlvbiBmdWxsUXVhbGlmaWVkU2VsZWN0b3Iobm9kZSkge1xuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICBjb25zdCBsb3dlckNhc2VOYW1lID1cbiAgICAgIChub2RlLmxvY2FsTmFtZSAmJiBub2RlLmxvY2FsTmFtZS50b0xvd2VyQ2FzZSgpKSB8fFxuICAgICAgbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHJldHVybiBsb3dlckNhc2VOYW1lO1xuICB9XG4gIC8vcmV0dXJuIGNzc1BhdGgobm9kZSwganVzdFNlbGVjdG9yKTtcbiAgcmV0dXJuIGNzc1BhdGgobm9kZSwgdHJ1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDdXJyZW50U2VsZWN0aW9uSW5mbygpIHtcbiAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICBpZiAoIXNlbGVjdGlvbikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHNlbGVjdGlvbi5pc0NvbGxhcHNlZCkge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIFNFTEVDVElPTiBDT0xMQVBTRUQuXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmF3VGV4dCA9IHNlbGVjdGlvbi50b1N0cmluZygpO1xuICBjb25zdCBjbGVhblRleHQgPSByYXdUZXh0LnRyaW0oKS5yZXBsYWNlKC9cXG4vZywgXCIgXCIpLnJlcGxhY2UoL1xcc1xccysvZywgXCIgXCIpO1xuICBpZiAoY2xlYW5UZXh0Lmxlbmd0aCA9PT0gMCkge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIFNFTEVDVElPTiBURVhUIEVNUFRZLlwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmICghc2VsZWN0aW9uLmFuY2hvck5vZGUgfHwgIXNlbGVjdGlvbi5mb2N1c05vZGUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJhbmdlID1cbiAgICBzZWxlY3Rpb24ucmFuZ2VDb3VudCA9PT0gMVxuICAgICAgPyBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKVxuICAgICAgOiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck5vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c09mZnNldFxuICAgICAgICApO1xuICBpZiAoIXJhbmdlIHx8IHJhbmdlLmNvbGxhcHNlZCkge1xuICAgIGNvbnNvbGUubG9nKFwiJCQkJCQkJCQkJCQkJCQkJCQgQ0FOTk9UIEdFVCBOT04tQ09MTEFQU0VEIFNFTEVDVElPTiBSQU5HRT8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2VJbmZvID0gY29udmVydFJhbmdlKHJhbmdlLCBmdWxsUXVhbGlmaWVkU2VsZWN0b3IsIGNvbXB1dGVDRkkpO1xuICBpZiAoIXJhbmdlSW5mbykge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIFNFTEVDVElPTiBSQU5HRSBJTkZPIEZBSUw/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKElTX0RFViAmJiBERUJVR19WSVNVQUxTKSB7XG4gICAgY29uc3QgcmVzdG9yZWRSYW5nZSA9IGNvbnZlcnRSYW5nZUluZm8od2luLmRvY3VtZW50LCByYW5nZUluZm8pO1xuICAgIGlmIChyZXN0b3JlZFJhbmdlKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHJlc3RvcmVkUmFuZ2Uuc3RhcnRPZmZzZXQgPT09IHJhbmdlLnN0YXJ0T2Zmc2V0ICYmXG4gICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kT2Zmc2V0ID09PSByYW5nZS5lbmRPZmZzZXQgJiZcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydENvbnRhaW5lciA9PT0gcmFuZ2Uuc3RhcnRDb250YWluZXIgJiZcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRDb250YWluZXIgPT09IHJhbmdlLmVuZENvbnRhaW5lclxuICAgICAgKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiU0VMRUNUSU9OIFJBTkdFIFJFU1RPUkVEIE9LQVkgKGRldiBjaGVjaykuXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJTRUxFQ1RJT04gUkFOR0UgUkVTVE9SRSBGQUlMIChkZXYgY2hlY2spLlwiKTtcbiAgICAgICAgZHVtcERlYnVnKFxuICAgICAgICAgIFwiU0VMRUNUSU9OXCIsXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck5vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c09mZnNldCxcbiAgICAgICAgICBnZXRDc3NTZWxlY3RvclxuICAgICAgICApO1xuICAgICAgICBkdW1wRGVidWcoXG4gICAgICAgICAgXCJPUkRFUkVEIFJBTkdFIEZST00gU0VMRUNUSU9OXCIsXG4gICAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAgICAgcmFuZ2UuZW5kQ29udGFpbmVyLFxuICAgICAgICAgIHJhbmdlLmVuZE9mZnNldCxcbiAgICAgICAgICBnZXRDc3NTZWxlY3RvclxuICAgICAgICApO1xuICAgICAgICBkdW1wRGVidWcoXG4gICAgICAgICAgXCJSRVNUT1JFRCBSQU5HRVwiLFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydE9mZnNldCxcbiAgICAgICAgICByZXN0b3JlZFJhbmdlLmVuZENvbnRhaW5lcixcbiAgICAgICAgICByZXN0b3JlZFJhbmdlLmVuZE9mZnNldCxcbiAgICAgICAgICBnZXRDc3NTZWxlY3RvclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhcIkNBTk5PVCBSRVNUT1JFIFNFTEVDVElPTiBSQU5HRSA/PyFcIik7XG4gICAgfVxuICB9IGVsc2Uge1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBsb2NhdGlvbnM6IHJhbmdlSW5mbzJMb2NhdGlvbihyYW5nZUluZm8pLFxuICAgIHRleHQ6IHtcbiAgICAgIGhpZ2hsaWdodDogcmF3VGV4dCxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBjaGVja0JsYWNrbGlzdGVkKGVsKSB7XG4gIGxldCBibGFja2xpc3RlZElkO1xuICBjb25zdCBpZCA9IGVsLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICBpZiAoaWQgJiYgX2JsYWNrbGlzdElkQ2xhc3NGb3JDRkkuaW5kZXhPZihpZCkgPj0gMCkge1xuICAgIGNvbnNvbGUubG9nKFwiY2hlY2tCbGFja2xpc3RlZCBJRDogXCIgKyBpZCk7XG4gICAgYmxhY2tsaXN0ZWRJZCA9IGlkO1xuICB9XG4gIGxldCBibGFja2xpc3RlZENsYXNzO1xuICBmb3IgKGNvbnN0IGl0ZW0gb2YgX2JsYWNrbGlzdElkQ2xhc3NGb3JDRkkpIHtcbiAgICBpZiAoZWwuY2xhc3NMaXN0LmNvbnRhaW5zKGl0ZW0pKSB7XG4gICAgICBjb25zb2xlLmxvZyhcImNoZWNrQmxhY2tsaXN0ZWQgQ0xBU1M6IFwiICsgaXRlbSk7XG4gICAgICBibGFja2xpc3RlZENsYXNzID0gaXRlbTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoYmxhY2tsaXN0ZWRJZCB8fCBibGFja2xpc3RlZENsYXNzKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNzc1BhdGgobm9kZSwgb3B0aW1pemVkKSB7XG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIHJldHVybiBcIlwiO1xuICB9XG5cbiAgY29uc3Qgc3RlcHMgPSBbXTtcbiAgbGV0IGNvbnRleHROb2RlID0gbm9kZTtcbiAgd2hpbGUgKGNvbnRleHROb2RlKSB7XG4gICAgY29uc3Qgc3RlcCA9IF9jc3NQYXRoU3RlcChjb250ZXh0Tm9kZSwgISFvcHRpbWl6ZWQsIGNvbnRleHROb2RlID09PSBub2RlKTtcbiAgICBpZiAoIXN0ZXApIHtcbiAgICAgIGJyZWFrOyAvLyBFcnJvciAtIGJhaWwgb3V0IGVhcmx5LlxuICAgIH1cbiAgICBzdGVwcy5wdXNoKHN0ZXAudmFsdWUpO1xuICAgIGlmIChzdGVwLm9wdGltaXplZCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNvbnRleHROb2RlID0gY29udGV4dE5vZGUucGFyZW50Tm9kZTtcbiAgfVxuICBzdGVwcy5yZXZlcnNlKCk7XG4gIHJldHVybiBzdGVwcy5qb2luKFwiID4gXCIpO1xufVxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuLy8gaHR0cHM6Ly9jaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL2JsaW5rLysvbWFzdGVyL1NvdXJjZS9kZXZ0b29scy9mcm9udF9lbmQvY29tcG9uZW50cy9ET01QcmVzZW50YXRpb25VdGlscy5qcyMzMTZcbmZ1bmN0aW9uIF9jc3NQYXRoU3RlcChub2RlLCBvcHRpbWl6ZWQsIGlzVGFyZ2V0Tm9kZSkge1xuICBmdW5jdGlvbiBwcmVmaXhlZEVsZW1lbnRDbGFzc05hbWVzKG5kKSB7XG4gICAgY29uc3QgY2xhc3NBdHRyaWJ1dGUgPSBuZC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKTtcbiAgICBpZiAoIWNsYXNzQXR0cmlidXRlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsYXNzQXR0cmlidXRlXG4gICAgICAuc3BsaXQoL1xccysvZylcbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5tYXAoKG5tKSA9PiB7XG4gICAgICAgIC8vIFRoZSBwcmVmaXggaXMgcmVxdWlyZWQgdG8gc3RvcmUgXCJfX3Byb3RvX19cIiBpbiBhIG9iamVjdC1iYXNlZCBtYXAuXG4gICAgICAgIHJldHVybiBcIiRcIiArIG5tO1xuICAgICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBpZFNlbGVjdG9yKGlkZCkge1xuICAgIHJldHVybiBcIiNcIiArIGVzY2FwZUlkZW50aWZpZXJJZk5lZWRlZChpZGQpO1xuICB9XG5cbiAgZnVuY3Rpb24gZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkKGlkZW50KSB7XG4gICAgaWYgKGlzQ1NTSWRlbnRpZmllcihpZGVudCkpIHtcbiAgICAgIHJldHVybiBpZGVudDtcbiAgICB9XG5cbiAgICBjb25zdCBzaG91bGRFc2NhcGVGaXJzdCA9IC9eKD86WzAtOV18LVswLTktXT8pLy50ZXN0KGlkZW50KTtcbiAgICBjb25zdCBsYXN0SW5kZXggPSBpZGVudC5sZW5ndGggLSAxO1xuICAgIHJldHVybiBpZGVudC5yZXBsYWNlKC8uL2csIGZ1bmN0aW9uIChjLCBpaSkge1xuICAgICAgcmV0dXJuIChzaG91bGRFc2NhcGVGaXJzdCAmJiBpaSA9PT0gMCkgfHwgIWlzQ1NTSWRlbnRDaGFyKGMpXG4gICAgICAgID8gZXNjYXBlQXNjaWlDaGFyKGMsIGlpID09PSBsYXN0SW5kZXgpXG4gICAgICAgIDogYztcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVzY2FwZUFzY2lpQ2hhcihjLCBpc0xhc3QpIHtcbiAgICByZXR1cm4gXCJcXFxcXCIgKyB0b0hleEJ5dGUoYykgKyAoaXNMYXN0ID8gXCJcIiA6IFwiIFwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvSGV4Qnl0ZShjKSB7XG4gICAgbGV0IGhleEJ5dGUgPSBjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpO1xuICAgIGlmIChoZXhCeXRlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaGV4Qnl0ZSA9IFwiMFwiICsgaGV4Qnl0ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhleEJ5dGU7XG4gIH1cblxuICBmdW5jdGlvbiBpc0NTU0lkZW50Q2hhcihjKSB7XG4gICAgaWYgKC9bYS16QS1aMC05Xy1dLy50ZXN0KGMpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGMuY2hhckNvZGVBdCgwKSA+PSAweGEwO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNDU1NJZGVudGlmaWVyKHZhbHVlKSB7XG4gICAgcmV0dXJuIC9eLT9bYS16QS1aX11bYS16QS1aMC05Xy1dKiQvLnRlc3QodmFsdWUpO1xuICB9XG5cbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBsb3dlckNhc2VOYW1lID1cbiAgICAobm9kZS5sb2NhbE5hbWUgJiYgbm9kZS5sb2NhbE5hbWUudG9Mb3dlckNhc2UoKSkgfHxcbiAgICBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgY29uc3QgZWxlbWVudCA9IG5vZGU7XG5cbiAgY29uc3QgaWQgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShcImlkXCIpO1xuXG4gIGlmIChvcHRpbWl6ZWQpIHtcbiAgICBpZiAoaWQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGlkU2VsZWN0b3IoaWQpLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgbG93ZXJDYXNlTmFtZSA9PT0gXCJib2R5XCIgfHxcbiAgICAgIGxvd2VyQ2FzZU5hbWUgPT09IFwiaGVhZFwiIHx8XG4gICAgICBsb3dlckNhc2VOYW1lID09PSBcImh0bWxcIlxuICAgICkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3B0aW1pemVkOiB0cnVlLFxuICAgICAgICB2YWx1ZTogbG93ZXJDYXNlTmFtZSwgLy8gbm9kZS5ub2RlTmFtZUluQ29ycmVjdENhc2UoKSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgbm9kZU5hbWUgPSBsb3dlckNhc2VOYW1lOyAvLyBub2RlLm5vZGVOYW1lSW5Db3JyZWN0Q2FzZSgpO1xuICBpZiAoaWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgb3B0aW1pemVkOiB0cnVlLFxuICAgICAgdmFsdWU6IG5vZGVOYW1lICsgaWRTZWxlY3RvcihpZCksXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZTtcblxuICBpZiAoIXBhcmVudCB8fCBwYXJlbnQubm9kZVR5cGUgPT09IE5vZGUuRE9DVU1FTlRfTk9ERSkge1xuICAgIHJldHVybiB7XG4gICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICB2YWx1ZTogbm9kZU5hbWUsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5XyA9IHByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMoZWxlbWVudCk7XG5cbiAgY29uc3QgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkgPSBbXTsgLy8gLmtleVNldCgpXG4gIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5Xy5mb3JFYWNoKChhcnJJdGVtKSA9PiB7XG4gICAgaWYgKHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5LmluZGV4T2YoYXJySXRlbSkgPCAwKSB7XG4gICAgICBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheS5wdXNoKGFyckl0ZW0pO1xuICAgIH1cbiAgfSk7XG5cbiAgbGV0IG5lZWRzQ2xhc3NOYW1lcyA9IGZhbHNlO1xuICBsZXQgbmVlZHNOdGhDaGlsZCA9IGZhbHNlO1xuICBsZXQgb3duSW5kZXggPSAtMTtcbiAgbGV0IGVsZW1lbnRJbmRleCA9IC0xO1xuICBjb25zdCBzaWJsaW5ncyA9IHBhcmVudC5jaGlsZHJlbjtcblxuICBmb3IgKFxuICAgIGxldCBpID0gMDtcbiAgICAob3duSW5kZXggPT09IC0xIHx8ICFuZWVkc050aENoaWxkKSAmJiBpIDwgc2libGluZ3MubGVuZ3RoO1xuICAgICsraVxuICApIHtcbiAgICBjb25zdCBzaWJsaW5nID0gc2libGluZ3NbaV07XG4gICAgaWYgKHNpYmxpbmcubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZWxlbWVudEluZGV4ICs9IDE7XG4gICAgaWYgKHNpYmxpbmcgPT09IG5vZGUpIHtcbiAgICAgIG93bkluZGV4ID0gZWxlbWVudEluZGV4O1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChuZWVkc050aENoaWxkKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBzaWJsaW5nLm5vZGVOYW1lSW5Db3JyZWN0Q2FzZSgpXG4gICAgY29uc3Qgc2libGluZ05hbWUgPVxuICAgICAgKHNpYmxpbmcubG9jYWxOYW1lICYmIHNpYmxpbmcubG9jYWxOYW1lLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgICBzaWJsaW5nLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKHNpYmxpbmdOYW1lICE9PSBub2RlTmFtZSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIG5lZWRzQ2xhc3NOYW1lcyA9IHRydWU7XG5cbiAgICBjb25zdCBvd25DbGFzc05hbWVzID0gW107XG4gICAgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkuZm9yRWFjaCgoYXJySXRlbSkgPT4ge1xuICAgICAgb3duQ2xhc3NOYW1lcy5wdXNoKGFyckl0ZW0pO1xuICAgIH0pO1xuICAgIGxldCBvd25DbGFzc05hbWVDb3VudCA9IG93bkNsYXNzTmFtZXMubGVuZ3RoO1xuXG4gICAgaWYgKG93bkNsYXNzTmFtZUNvdW50ID09PSAwKSB7XG4gICAgICBuZWVkc050aENoaWxkID0gdHJ1ZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBzaWJsaW5nQ2xhc3NOYW1lc0FycmF5XyA9IHByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMoc2libGluZyk7XG4gICAgY29uc3Qgc2libGluZ0NsYXNzTmFtZXNBcnJheSA9IFtdOyAvLyAua2V5U2V0KClcbiAgICBzaWJsaW5nQ2xhc3NOYW1lc0FycmF5Xy5mb3JFYWNoKChhcnJJdGVtKSA9PiB7XG4gICAgICBpZiAoc2libGluZ0NsYXNzTmFtZXNBcnJheS5pbmRleE9mKGFyckl0ZW0pIDwgMCkge1xuICAgICAgICBzaWJsaW5nQ2xhc3NOYW1lc0FycmF5LnB1c2goYXJySXRlbSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IHNpYmxpbmdDbGFzcyBvZiBzaWJsaW5nQ2xhc3NOYW1lc0FycmF5KSB7XG4gICAgICBjb25zdCBpbmQgPSBvd25DbGFzc05hbWVzLmluZGV4T2Yoc2libGluZ0NsYXNzKTtcbiAgICAgIGlmIChpbmQgPCAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBvd25DbGFzc05hbWVzLnNwbGljZShpbmQsIDEpOyAvLyBkZWxldGUgb3duQ2xhc3NOYW1lc1tzaWJsaW5nQ2xhc3NdO1xuXG4gICAgICBpZiAoIS0tb3duQ2xhc3NOYW1lQ291bnQpIHtcbiAgICAgICAgbmVlZHNOdGhDaGlsZCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGxldCByZXN1bHQgPSBub2RlTmFtZTtcbiAgaWYgKFxuICAgIGlzVGFyZ2V0Tm9kZSAmJlxuICAgIG5vZGVOYW1lID09PSBcImlucHV0XCIgJiZcbiAgICBlbGVtZW50LmdldEF0dHJpYnV0ZShcInR5cGVcIikgJiZcbiAgICAhZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJpZFwiKSAmJlxuICAgICFlbGVtZW50LmdldEF0dHJpYnV0ZShcImNsYXNzXCIpXG4gICkge1xuICAgIHJlc3VsdCArPSAnW3R5cGU9XCInICsgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpICsgJ1wiXSc7XG4gIH1cbiAgaWYgKG5lZWRzTnRoQ2hpbGQpIHtcbiAgICByZXN1bHQgKz0gXCI6bnRoLWNoaWxkKFwiICsgKG93bkluZGV4ICsgMSkgKyBcIilcIjtcbiAgfSBlbHNlIGlmIChuZWVkc0NsYXNzTmFtZXMpIHtcbiAgICBmb3IgKGNvbnN0IHByZWZpeGVkTmFtZSBvZiBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheSkge1xuICAgICAgcmVzdWx0ICs9IFwiLlwiICsgZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkKHByZWZpeGVkTmFtZS5zdWJzdHIoMSkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgb3B0aW1pemVkOiBmYWxzZSxcbiAgICB2YWx1ZTogcmVzdWx0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQ0ZJKG5vZGUpIHtcbiAgLy8gVE9ETzogaGFuZGxlIGNoYXJhY3RlciBwb3NpdGlvbiBpbnNpZGUgdGV4dCBub2RlXG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBsZXQgY2ZpID0gXCJcIjtcblxuICBsZXQgY3VycmVudEVsZW1lbnQgPSBub2RlO1xuICB3aGlsZSAoXG4gICAgY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZSAmJlxuICAgIGN1cnJlbnRFbGVtZW50LnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXG4gICkge1xuICAgIGNvbnN0IGJsYWNrbGlzdGVkID0gY2hlY2tCbGFja2xpc3RlZChjdXJyZW50RWxlbWVudCk7XG4gICAgaWYgKCFibGFja2xpc3RlZCkge1xuICAgICAgY29uc3QgY3VycmVudEVsZW1lbnRQYXJlbnRDaGlsZHJlbiA9IGN1cnJlbnRFbGVtZW50LnBhcmVudE5vZGUuY2hpbGRyZW47XG4gICAgICBsZXQgY3VycmVudEVsZW1lbnRJbmRleCA9IC0xO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChjdXJyZW50RWxlbWVudCA9PT0gY3VycmVudEVsZW1lbnRQYXJlbnRDaGlsZHJlbltpXSkge1xuICAgICAgICAgIGN1cnJlbnRFbGVtZW50SW5kZXggPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoY3VycmVudEVsZW1lbnRJbmRleCA+PSAwKSB7XG4gICAgICAgIGNvbnN0IGNmaUluZGV4ID0gKGN1cnJlbnRFbGVtZW50SW5kZXggKyAxKSAqIDI7XG4gICAgICAgIGNmaSA9XG4gICAgICAgICAgY2ZpSW5kZXggK1xuICAgICAgICAgIChjdXJyZW50RWxlbWVudC5pZCA/IFwiW1wiICsgY3VycmVudEVsZW1lbnQuaWQgKyBcIl1cIiA6IFwiXCIpICtcbiAgICAgICAgICAoY2ZpLmxlbmd0aCA/IFwiL1wiICsgY2ZpIDogXCJcIik7XG4gICAgICB9XG4gICAgfVxuICAgIGN1cnJlbnRFbGVtZW50ID0gY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZTtcbiAgfVxuXG4gIHJldHVybiBcIi9cIiArIGNmaTtcbn1cblxuZnVuY3Rpb24gX2NyZWF0ZUhpZ2hsaWdodChsb2NhdGlvbnMsIGNvbG9yLCBwb2ludGVySW50ZXJhY3Rpb24sIHR5cGUpIHtcbiAgY29uc3QgcmFuZ2VJbmZvID0gbG9jYXRpb24yUmFuZ2VJbmZvKGxvY2F0aW9ucyk7XG4gIGNvbnN0IHVuaXF1ZVN0ciA9IGAke3JhbmdlSW5mby5jZml9JHtyYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3J9JHtyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXh9JHtyYW5nZUluZm8uc3RhcnRPZmZzZXR9JHtyYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yfSR7cmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleH0ke3JhbmdlSW5mby5lbmRPZmZzZXR9YDtcblxuICBjb25zdCBoYXNoID0gcmVxdWlyZShcImhhc2guanNcIik7XG4gIGNvbnN0IHNoYTI1NkhleCA9IGhhc2guc2hhMjU2KCkudXBkYXRlKHVuaXF1ZVN0cikuZGlnZXN0KFwiaGV4XCIpO1xuXG4gIHZhciBpZDtcbiAgaWYgKHR5cGUgPT0gSURfSElHSExJR0hUU19DT05UQUlORVIpIHtcbiAgICBpZCA9IFwiUjJfSElHSExJR0hUX1wiICsgc2hhMjU2SGV4O1xuICB9IGVsc2Uge1xuICAgIGlkID0gXCJSMl9BTk5PVEFUSU9OX1wiICsgc2hhMjU2SGV4O1xuICB9XG5cbiAgZGVzdHJveUhpZ2hsaWdodChpZCk7XG5cbiAgY29uc3QgaGlnaGxpZ2h0ID0ge1xuICAgIGNvbG9yOiBjb2xvciA/IGNvbG9yIDogREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SLFxuICAgIGlkLFxuICAgIHBvaW50ZXJJbnRlcmFjdGlvbixcbiAgICByYW5nZUluZm8sXG4gIH07XG4gIF9oaWdobGlnaHRzLnB1c2goaGlnaGxpZ2h0KTtcbiAgY3JlYXRlSGlnaGxpZ2h0RG9tKFxuICAgIHdpbmRvdyxcbiAgICBoaWdobGlnaHQsXG4gICAgdHlwZSA9PSBJRF9BTk5PVEFUSU9OX0NPTlRBSU5FUiA/IHRydWUgOiBmYWxzZVxuICApO1xuXG4gIHJldHVybiBoaWdobGlnaHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVIaWdobGlnaHQoc2VsZWN0aW9uSW5mbywgY29sb3IsIHBvaW50ZXJJbnRlcmFjdGlvbikge1xuICByZXR1cm4gX2NyZWF0ZUhpZ2hsaWdodChcbiAgICBzZWxlY3Rpb25JbmZvLFxuICAgIGNvbG9yLFxuICAgIHBvaW50ZXJJbnRlcmFjdGlvbixcbiAgICBJRF9ISUdITElHSFRTX0NPTlRBSU5FUlxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQW5ub3RhdGlvbihpZCkge1xuICBsZXQgaSA9IC0xO1xuXG4gIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzLmZpbmQoKGgsIGopID0+IHtcbiAgICBpID0gajtcbiAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gIH0pO1xuICBpZiAoaSA9PSBfaGlnaGxpZ2h0cy5sZW5ndGgpIHJldHVybjtcblxuICB2YXIgbG9jYXRpb25zID0ge1xuICAgIGxvY2F0aW9uczogcmFuZ2VJbmZvMkxvY2F0aW9uKGhpZ2hsaWdodC5yYW5nZUluZm8pLFxuICB9O1xuXG4gIHJldHVybiBfY3JlYXRlSGlnaGxpZ2h0KFxuICAgIGxvY2F0aW9ucyxcbiAgICBoaWdobGlnaHQuY29sb3IsXG4gICAgdHJ1ZSxcbiAgICBJRF9BTk5PVEFUSU9OX0NPTlRBSU5FUlxuICApO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVIaWdobGlnaHREb20od2luLCBoaWdobGlnaHQsIGFubm90YXRpb25GbGFnKSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuXG4gIGNvbnN0IHNjYWxlID1cbiAgICAxIC9cbiAgICAod2luLlJFQURJVU0yICYmIHdpbi5SRUFESVVNMi5pc0ZpeGVkTGF5b3V0XG4gICAgICA/IHdpbi5SRUFESVVNMi5meGxWaWV3cG9ydFNjYWxlXG4gICAgICA6IDEpO1xuXG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcblxuICBjb25zdCByYW5nZSA9IGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIGhpZ2hsaWdodC5yYW5nZUluZm8pO1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgaGlnaGxpZ2h0c0NvbnRhaW5lciA9IGVuc3VyZUNvbnRhaW5lcih3aW4sIGFubm90YXRpb25GbGFnKTtcbiAgY29uc3QgaGlnaGxpZ2h0UGFyZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuICBoaWdobGlnaHRQYXJlbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaGlnaGxpZ2h0LmlkKTtcbiAgaGlnaGxpZ2h0UGFyZW50LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9DT05UQUlORVIpO1xuXG4gIGRvY3VtZW50LmJvZHkuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG4gIGhpZ2hsaWdodFBhcmVudC5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgaWYgKGhpZ2hsaWdodC5wb2ludGVySW50ZXJhY3Rpb24pIHtcbiAgICBoaWdobGlnaHRQYXJlbnQuc2V0QXR0cmlidXRlKFwiZGF0YS1jbGlja1wiLCBcIjFcIik7XG4gIH1cblxuICBjb25zdCBib2R5UmVjdCA9IGRvY3VtZW50LmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGNvbnN0IHVzZVNWRyA9ICFERUJVR19WSVNVQUxTICYmIFVTRV9TVkc7XG4gIC8vY29uc3QgdXNlU1ZHID0gVVNFX1NWRztcbiAgY29uc3QgZHJhd1VuZGVybGluZSA9IGZhbHNlO1xuICBjb25zdCBkcmF3U3RyaWtlVGhyb3VnaCA9IGZhbHNlO1xuICBjb25zdCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gZHJhd1VuZGVybGluZSB8fCBkcmF3U3RyaWtlVGhyb3VnaDtcbiAgLy9jb25zdCBjbGllbnRSZWN0cyA9IERFQlVHX1ZJU1VBTFMgPyByYW5nZS5nZXRDbGllbnRSZWN0cygpIDpcbiAgY29uc3QgY2xpZW50UmVjdHMgPSBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgICByYW5nZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG4gIGxldCBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZztcbiAgY29uc3Qgcm91bmRlZENvcm5lciA9IDM7XG4gIGNvbnN0IHVuZGVybGluZVRoaWNrbmVzcyA9IDI7XG4gIGNvbnN0IHN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzID0gMztcbiAgY29uc3Qgb3BhY2l0eSA9IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZO1xuICBsZXQgZXh0cmEgPSBcIlwiO1xuICBjb25zdCByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QgPVxuICAgIGZyYW1lRm9ySGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtXaXRoSUQod2luLCBoaWdobGlnaHQuaWQpO1xuXG4gIGxldCB4T2Zmc2V0O1xuICBsZXQgeU9mZnNldDtcbiAgbGV0IGFubm90YXRpb25PZmZzZXQ7XG5cbiAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCA6IGJvZHlSZWN0LmxlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCA6IGJvZHlSZWN0LnRvcDtcbiAgICBhbm5vdGF0aW9uT2Zmc2V0ID1cbiAgICAgIHBhcnNlSW50KFxuICAgICAgICAocmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnJpZ2h0IC0geE9mZnNldCkgLyB3aW5kb3cuaW5uZXJXaWR0aFxuICAgICAgKSArIDE7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgICBhbm5vdGF0aW9uT2Zmc2V0ID0gcGFyc2VJbnQoXG4gICAgICByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QucmlnaHQgLyB3aW5kb3cuaW5uZXJXaWR0aCArIDFcbiAgICApO1xuICB9XG5cbiAgZm9yIChjb25zdCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgaWYgKHVzZVNWRykge1xuICAgICAgY29uc3QgYm9yZGVyVGhpY2tuZXNzID0gMDtcbiAgICAgIGlmICghaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcpIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICB9XG4gICAgICBjb25zdCBoaWdobGlnaHRBcmVhU1ZHUmVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgU1ZHX1hNTF9OQU1FU1BBQ0UsXG4gICAgICAgIFwicmVjdFwiXG4gICAgICApO1xuXG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgYGZpbGw6IHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KSAhaW1wb3J0YW50OyBmaWxsLW9wYWNpdHk6ICR7b3BhY2l0eX0gIWltcG9ydGFudDsgc3Ryb2tlLXdpZHRoOiAwO2BcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zY2FsZSA9IHNjYWxlO1xuXG4gICAgICAvKlxuICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QgPSB7XG4gICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgKi9cblxuICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QgPSB7XG4gICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcInJ4XCIsIGAke3JvdW5kZWRDb3JuZXIgKiBzY2FsZX1gKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcInJ5XCIsIGAke3JvdW5kZWRDb3JuZXIgKiBzY2FsZX1gKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJ4XCIsXG4gICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0LmxlZnQgLSBib3JkZXJUaGlja25lc3MpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJ5XCIsXG4gICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0LnRvcCAtIGJvcmRlclRoaWNrbmVzcykgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcImhlaWdodFwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC5oZWlnaHQgKyBib3JkZXJUaGlja25lc3MgKiAyKSAqIHNjYWxlfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwid2lkdGhcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3Qud2lkdGggKyBib3JkZXJUaGlja25lc3MgKiAyKSAqIHNjYWxlfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZy5hcHBlbmRDaGlsZChoaWdobGlnaHRBcmVhU1ZHUmVjdCk7XG4gICAgICBpZiAoZHJhd1VuZGVybGluZSkge1xuICAgICAgICBjb25zdCBoaWdobGlnaHRBcmVhU1ZHTGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICBTVkdfWE1MX05BTUVTUEFDRSxcbiAgICAgICAgICBcImxpbmVcIlxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgICAgYHN0cm9rZS1saW5lY2FwOiByb3VuZDsgc3Ryb2tlLXdpZHRoOiAke1xuICAgICAgICAgICAgdW5kZXJsaW5lVGhpY2tuZXNzICogc2NhbGVcbiAgICAgICAgICB9OyBzdHJva2U6IHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7XG4gICAgICAgICAgICBoaWdobGlnaHQuY29sb3IuYmx1ZVxuICAgICAgICAgIH0pICFpbXBvcnRhbnQ7IHN0cm9rZS1vcGFjaXR5OiAke29wYWNpdHl9ICFpbXBvcnRhbnRgXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNjYWxlID0gc2NhbGU7XG4gICAgICAgIC8qXG4gICAgICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpbmVPZmZzZXQgPVxuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGggPiByb3VuZGVkQ29ybmVyID8gcm91bmRlZENvcm5lciA6IDA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngxXCIsXG4gICAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QubGVmdCArIGxpbmVPZmZzZXQpICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ4MlwiLFxuICAgICAgICAgIGAke1xuICAgICAgICAgICAgKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QubGVmdCArXG4gICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGggLVxuICAgICAgICAgICAgICBsaW5lT2Zmc2V0KSAqXG4gICAgICAgICAgICBzY2FsZVxuICAgICAgICAgIH1gXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHkgPVxuICAgICAgICAgIChoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LnRvcCArXG4gICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmhlaWdodCAtXG4gICAgICAgICAgICB1bmRlcmxpbmVUaGlja25lc3MgLyAyKSAqXG4gICAgICAgICAgc2NhbGU7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkxXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkyXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcImhlaWdodFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0ICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ3aWR0aFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGggKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnLmFwcGVuZENoaWxkKGhpZ2hsaWdodEFyZWFTVkdMaW5lKTtcbiAgICAgIH1cbiAgICAgIGlmIChkcmF3U3RyaWtlVGhyb3VnaCkge1xuICAgICAgICBjb25zdCBoaWdobGlnaHRBcmVhU1ZHTGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICBTVkdfWE1MX05BTUVTUEFDRSxcbiAgICAgICAgICBcImxpbmVcIlxuICAgICAgICApO1xuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgICBgc3Ryb2tlLWxpbmVjYXA6IGJ1dHQ7IHN0cm9rZS13aWR0aDogJHtcbiAgICAgICAgICAgIHN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzICogc2NhbGVcbiAgICAgICAgICB9OyBzdHJva2U6IHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7XG4gICAgICAgICAgICBoaWdobGlnaHQuY29sb3IuYmx1ZVxuICAgICAgICAgIH0pICFpbXBvcnRhbnQ7IHN0cm9rZS1vcGFjaXR5OiAke29wYWNpdHl9ICFpbXBvcnRhbnRgXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNjYWxlID0gc2NhbGU7XG5cbiAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqL1xuXG4gICAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ4MVwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QubGVmdCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDJcIixcbiAgICAgICAgICBgJHtcbiAgICAgICAgICAgIChoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmxlZnQgKyBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoKSAqXG4gICAgICAgICAgICBzY2FsZVxuICAgICAgICAgIH1gXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGxpbmVPZmZzZXQgPSBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmhlaWdodCAvIDI7XG4gICAgICAgIGNvbnN0IHkgPSAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC50b3AgKyBsaW5lT2Zmc2V0KSAqIHNjYWxlO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXCJ5MVwiLCBgJHt5fWApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXCJ5MlwiLCBgJHt5fWApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJoZWlnaHRcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmhlaWdodCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwid2lkdGhcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZy5hcHBlbmRDaGlsZChoaWdobGlnaHRBcmVhU1ZHTGluZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG4gICAgICBoaWdobGlnaHRBcmVhLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcblxuICAgICAgaWYgKERFQlVHX1ZJU1VBTFMpIHtcbiAgICAgICAgY29uc3QgcmdiID0gTWF0aC5yb3VuZCgweGZmZmZmZiAqIE1hdGgucmFuZG9tKCkpO1xuICAgICAgICBjb25zdCByID0gcmdiID4+IDE2O1xuICAgICAgICBjb25zdCBnID0gKHJnYiA+PiA4KSAmIDI1NTtcbiAgICAgICAgY29uc3QgYiA9IHJnYiAmIDI1NTtcbiAgICAgICAgZXh0cmEgPSBgb3V0bGluZS1jb2xvcjogcmdiKCR7cn0sICR7Z30sICR7Yn0pOyBvdXRsaW5lLXN0eWxlOiBzb2xpZDsgb3V0bGluZS13aWR0aDogMXB4OyBvdXRsaW5lLW9mZnNldDogLTFweDtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRyYXdVbmRlcmxpbmUpIHtcbiAgICAgICAgICBleHRyYSArPSBgYm9yZGVyLWJvdHRvbTogJHt1bmRlcmxpbmVUaGlja25lc3MgKiBzY2FsZX1weCBzb2xpZCByZ2JhKCR7XG4gICAgICAgICAgICBoaWdobGlnaHQuY29sb3IucmVkXG4gICAgICAgICAgfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke1xuICAgICAgICAgICAgaGlnaGxpZ2h0LmNvbG9yLmJsdWVcbiAgICAgICAgICB9LCAke29wYWNpdHl9KSAhaW1wb3J0YW50YDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGlnaGxpZ2h0QXJlYS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgYGJvcmRlci1yYWRpdXM6ICR7cm91bmRlZENvcm5lcn1weCAhaW1wb3J0YW50OyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0sICR7b3BhY2l0eX0pICFpbXBvcnRhbnQ7ICR7ZXh0cmF9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnBvc2l0aW9uID0gcGFnaW5hdGVkID8gXCJmaXhlZFwiIDogXCJhYnNvbHV0ZVwiO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zY2FsZSA9IHNjYWxlO1xuICAgICAgLypcbiAgICAgICAgICAgICBoaWdobGlnaHRBcmVhLnJlY3QgPSB7XG4gICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgKi9cbiAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnJlY3QgPSB7XG4gICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS53aWR0aCA9IGAke2hpZ2hsaWdodEFyZWEucmVjdC53aWR0aCAqIHNjYWxlfXB4YDtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuaGVpZ2h0ID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LmhlaWdodCAqIHNjYWxlfXB4YDtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUubGVmdCA9IGAke2hpZ2hsaWdodEFyZWEucmVjdC5sZWZ0ICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS50b3AgPSBgJHtoaWdobGlnaHRBcmVhLnJlY3QudG9wICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRBcmVhKTtcbiAgICAgIGlmICghREVCVUdfVklTVUFMUyAmJiBkcmF3U3RyaWtlVGhyb3VnaCkge1xuICAgICAgICAvL2lmIChkcmF3U3RyaWtlVGhyb3VnaCkge1xuICAgICAgICBjb25zdCBoaWdobGlnaHRBcmVhTGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcblxuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICAgIGBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0sICR7b3BhY2l0eX0pICFpbXBvcnRhbnQ7YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnNjYWxlID0gc2NhbGU7XG4gICAgICAgIC8qXG4gICAgICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgKi9cblxuICAgICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUud2lkdGggPSBgJHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0LndpZHRoICogc2NhbGVcbiAgICAgICAgfXB4YDtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUuaGVpZ2h0ID0gYCR7XG4gICAgICAgICAgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgKiBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5sZWZ0ID0gYCR7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC5sZWZ0ICogc2NhbGVcbiAgICAgICAgfXB4YDtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUudG9wID0gYCR7XG4gICAgICAgICAgKGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QudG9wICtcbiAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QuaGVpZ2h0IC8gMiAtXG4gICAgICAgICAgICBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyAvIDIpICpcbiAgICAgICAgICBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRQYXJlbnQuYXBwZW5kKGhpZ2hsaWdodEFyZWFMaW5lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmICh1c2VTVkcgJiYgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcpIHtcbiAgICBjb25zdCBoaWdobGlnaHRBcmVhU1ZHID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFNWR19YTUxfTkFNRVNQQUNFLCBcInN2Z1wiKTtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLnNldEF0dHJpYnV0ZShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLnN0eWxlLnBvc2l0aW9uID0gcGFnaW5hdGVkID8gXCJmaXhlZFwiIDogXCJhYnNvbHV0ZVwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUub3ZlcmZsb3cgPSBcInZpc2libGVcIjtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLnN0eWxlLmxlZnQgPSBcIjBcIjtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLnN0eWxlLnRvcCA9IFwiMFwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuYXBwZW5kKGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnKTtcbiAgICBoaWdobGlnaHRQYXJlbnQuYXBwZW5kKGhpZ2hsaWdodEFyZWFTVkcpO1xuICB9XG5cbiAgY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG4gIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQSk7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcuc2V0QXR0cmlidXRlKFxuICAgICAgXCJzdHlsZVwiLFxuICAgICAgYGJvcmRlci1yYWRpdXM6ICR7cm91bmRlZENvcm5lcn1weCAhaW1wb3J0YW50OyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0sICR7b3BhY2l0eX0pICFpbXBvcnRhbnQ7ICR7ZXh0cmF9YFxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEpO1xuICB9XG5cbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLnBvc2l0aW9uID0gcGFnaW5hdGVkID8gXCJmaXhlZFwiIDogXCJhYnNvbHV0ZVwiO1xuICBoaWdobGlnaHRCb3VuZGluZy5zY2FsZSA9IHNjYWxlO1xuXG4gIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcuc2V0QXR0cmlidXRlKFxuICAgICAgXCJzdHlsZVwiLFxuICAgICAgYG91dGxpbmUtY29sb3I6IG1hZ2VudGE7IG91dGxpbmUtc3R5bGU6IHNvbGlkOyBvdXRsaW5lLXdpZHRoOiAxcHg7IG91dGxpbmUtb2Zmc2V0OiAtMXB4O2BcbiAgICApO1xuICB9XG5cbiAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcucmVjdCA9IHtcbiAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0ID0gcmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcucmVjdCA9IHtcbiAgICAgIGhlaWdodDogcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgbGVmdDogcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICB0b3A6IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICB3aWR0aDogcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3Qud2lkdGgsXG4gICAgfTtcbiAgfVxuXG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLndpZHRoID0gYCR7aGlnaGxpZ2h0Qm91bmRpbmcucmVjdC53aWR0aCAqIHNjYWxlfXB4YDtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUuaGVpZ2h0ID0gYCR7aGlnaGxpZ2h0Qm91bmRpbmcucmVjdC5oZWlnaHQgKiBzY2FsZX1weGA7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLmxlZnQgPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LmxlZnQgKiBzY2FsZX1weGA7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLnRvcCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3QudG9wICogc2NhbGV9cHhgO1xuXG4gIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICBoaWdobGlnaHRzQ29udGFpbmVyLmFwcGVuZChoaWdobGlnaHRQYXJlbnQpO1xuXG4gIHJldHVybiBoaWdobGlnaHRQYXJlbnQ7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9yZGVyZWRSYW5nZShzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0LCBlbmROb2RlLCBlbmRPZmZzZXQpIHtcbiAgY29uc3QgcmFuZ2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIHJhbmdlLnNldEVuZChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICBpZiAoIXJhbmdlLmNvbGxhcHNlZCkge1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBjb25zb2xlLmxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgQ09MTEFQU0VEIC4uLiBSQU5HRSBSRVZFUlNFP1wiKTtcbiAgY29uc3QgcmFuZ2VSZXZlcnNlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRTdGFydChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICByYW5nZVJldmVyc2Uuc2V0RW5kKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICBpZiAoIXJhbmdlUmV2ZXJzZS5jb2xsYXBzZWQpIHtcbiAgICBjb25zb2xlLmxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgUkFOR0UgUkVWRVJTRSBPSy5cIik7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGNvbnNvbGUubG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIEFMU08gQ09MTEFQU0VEPyFcIik7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSYW5nZShyYW5nZSwgZ2V0Q3NzU2VsZWN0b3IsIGNvbXB1dGVFbGVtZW50Q0ZJKSB7XG4gIGNvbnN0IHN0YXJ0SXNFbGVtZW50ID0gcmFuZ2Uuc3RhcnRDb250YWluZXIubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFO1xuICBjb25zdCBzdGFydENvbnRhaW5lckVsZW1lbnQgPSBzdGFydElzRWxlbWVudFxuICAgID8gcmFuZ2Uuc3RhcnRDb250YWluZXJcbiAgICA6IHJhbmdlLnN0YXJ0Q29udGFpbmVyLnBhcmVudE5vZGUgJiZcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXG4gICAgPyByYW5nZS5zdGFydENvbnRhaW5lci5wYXJlbnROb2RlXG4gICAgOiB1bmRlZmluZWQ7XG4gIGlmICghc3RhcnRDb250YWluZXJFbGVtZW50KSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA9IHN0YXJ0SXNFbGVtZW50XG4gICAgPyAtMVxuICAgIDogQXJyYXkuZnJvbShzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2RlcykuaW5kZXhPZihcbiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXJcbiAgICAgICk7XG4gIGlmIChzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA8IC0xKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciA9IGdldENzc1NlbGVjdG9yKFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudFxuICApO1xuICBjb25zdCBlbmRJc0VsZW1lbnQgPSByYW5nZS5lbmRDb250YWluZXIubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFO1xuICBjb25zdCBlbmRDb250YWluZXJFbGVtZW50ID0gZW5kSXNFbGVtZW50XG4gICAgPyByYW5nZS5lbmRDb250YWluZXJcbiAgICA6IHJhbmdlLmVuZENvbnRhaW5lci5wYXJlbnROb2RlICYmXG4gICAgICByYW5nZS5lbmRDb250YWluZXIucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICA/IHJhbmdlLmVuZENvbnRhaW5lci5wYXJlbnROb2RlXG4gICAgOiB1bmRlZmluZWQ7XG4gIGlmICghZW5kQ29udGFpbmVyRWxlbWVudCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID0gZW5kSXNFbGVtZW50XG4gICAgPyAtMVxuICAgIDogQXJyYXkuZnJvbShlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMpLmluZGV4T2YocmFuZ2UuZW5kQ29udGFpbmVyKTtcbiAgaWYgKGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA8IC0xKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IgPSBnZXRDc3NTZWxlY3RvcihlbmRDb250YWluZXJFbGVtZW50KTtcbiAgY29uc3QgY29tbW9uRWxlbWVudEFuY2VzdG9yID0gZ2V0Q29tbW9uQW5jZXN0b3JFbGVtZW50KFxuICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgIHJhbmdlLmVuZENvbnRhaW5lclxuICApO1xuICBpZiAoIWNvbW1vbkVsZW1lbnRBbmNlc3Rvcikge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIE5PIFJBTkdFIENPTU1PTiBBTkNFU1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyKSB7XG4gICAgY29uc3QgcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQgPVxuICAgICAgcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXG4gICAgICAgID8gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXJcbiAgICAgICAgOiByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lci5wYXJlbnROb2RlO1xuICAgIGlmIChcbiAgICAgIHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50ICYmXG4gICAgICByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICApIHtcbiAgICAgIGlmIChjb21tb25FbGVtZW50QW5jZXN0b3IgIT09IHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiPj4+Pj4+IENPTU1PTiBBTkNFU1RPUiBDT05UQUlORVIgRElGRj8/IVwiKTtcbiAgICAgICAgY29uc29sZS5sb2coZ2V0Q3NzU2VsZWN0b3IoY29tbW9uRWxlbWVudEFuY2VzdG9yKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKGdldENzc1NlbGVjdG9yKHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50KSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGNvbnN0IHJvb3RFbGVtZW50Q2ZpID0gY29tcHV0ZUVsZW1lbnRDRkkoY29tbW9uRWxlbWVudEFuY2VzdG9yKTtcbiAgY29uc3Qgc3RhcnRFbGVtZW50Q2ZpID0gY29tcHV0ZUVsZW1lbnRDRkkoc3RhcnRDb250YWluZXJFbGVtZW50KTtcbiAgY29uc3QgZW5kRWxlbWVudENmaSA9IGNvbXB1dGVFbGVtZW50Q0ZJKGVuZENvbnRhaW5lckVsZW1lbnQpO1xuICBsZXQgY2ZpO1xuICBpZiAocm9vdEVsZW1lbnRDZmkgJiYgc3RhcnRFbGVtZW50Q2ZpICYmIGVuZEVsZW1lbnRDZmkpIHtcbiAgICBsZXQgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID0gc3RhcnRFbGVtZW50Q2ZpO1xuICAgIGlmICghc3RhcnRJc0VsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQsXG4gICAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyXG4gICAgICApO1xuICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgc3RhcnRFbGVtZW50Q2ZpICtcbiAgICAgICAgXCIvXCIgK1xuICAgICAgICBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSArXG4gICAgICAgIFwiOlwiICtcbiAgICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChcbiAgICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQgPj0gMCAmJlxuICAgICAgICByYW5nZS5zdGFydE9mZnNldCA8IHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkTm9kZSA9IHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlLnN0YXJ0T2Zmc2V0XTtcbiAgICAgICAgaWYgKGNoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgc3RhcnRFbGVtZW50Q2ZpICsgXCIvXCIgKyAocmFuZ2Uuc3RhcnRPZmZzZXQgKyAxKSAqIDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgY2ZpVGV4dE5vZGVJbmRleCA9IGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChcbiAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgICAgIGNoaWxkTm9kZVxuICAgICAgICAgICk7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID0gc3RhcnRFbGVtZW50Q2ZpICsgXCIvXCIgKyBjZmlUZXh0Tm9kZUluZGV4O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBjZmlJbmRleE9mTGFzdEVsZW1lbnQgPVxuICAgICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudCAqIDI7XG4gICAgICAgIGNvbnN0IGxhc3RDaGlsZE5vZGUgPVxuICAgICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzW1xuICAgICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoIC0gMVxuICAgICAgICAgIF07XG4gICAgICAgIGlmIChsYXN0Q2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIChjZmlJbmRleE9mTGFzdEVsZW1lbnQgKyAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgc3RhcnRFbGVtZW50Q2ZpICsgXCIvXCIgKyAoY2ZpSW5kZXhPZkxhc3RFbGVtZW50ICsgMik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGVuZEVsZW1lbnRPclRleHRDZmkgPSBlbmRFbGVtZW50Q2ZpO1xuICAgIGlmICghZW5kSXNFbGVtZW50KSB7XG4gICAgICBjb25zdCBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkgPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgIGVuZENvbnRhaW5lckVsZW1lbnQsXG4gICAgICAgIHJhbmdlLmVuZENvbnRhaW5lclxuICAgICAgKTtcbiAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICBlbmRFbGVtZW50Q2ZpICtcbiAgICAgICAgXCIvXCIgK1xuICAgICAgICBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkgK1xuICAgICAgICBcIjpcIiArXG4gICAgICAgIHJhbmdlLmVuZE9mZnNldDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICByYW5nZS5lbmRPZmZzZXQgPj0gMCAmJlxuICAgICAgICByYW5nZS5lbmRPZmZzZXQgPCBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgY2hpbGROb2RlID0gZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlLmVuZE9mZnNldF07XG4gICAgICAgIGlmIChjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9IGVuZEVsZW1lbnRDZmkgKyBcIi9cIiArIChyYW5nZS5lbmRPZmZzZXQgKyAxKSAqIDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgY2ZpVGV4dE5vZGVJbmRleCA9IGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChcbiAgICAgICAgICAgIGVuZENvbnRhaW5lckVsZW1lbnQsXG4gICAgICAgICAgICBjaGlsZE5vZGVcbiAgICAgICAgICApO1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPSBlbmRFbGVtZW50Q2ZpICsgXCIvXCIgKyBjZmlUZXh0Tm9kZUluZGV4O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBjZmlJbmRleE9mTGFzdEVsZW1lbnQgPSBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkRWxlbWVudENvdW50ICogMjtcbiAgICAgICAgY29uc3QgbGFzdENoaWxkTm9kZSA9XG4gICAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzW1xuICAgICAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICBdO1xuICAgICAgICBpZiAobGFzdENoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIGVuZEVsZW1lbnRDZmkgKyBcIi9cIiArIChjZmlJbmRleE9mTGFzdEVsZW1lbnQgKyAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIGVuZEVsZW1lbnRDZmkgKyBcIi9cIiArIChjZmlJbmRleE9mTGFzdEVsZW1lbnQgKyAyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBjZmkgPVxuICAgICAgcm9vdEVsZW1lbnRDZmkgK1xuICAgICAgXCIsXCIgK1xuICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpLnJlcGxhY2Uocm9vdEVsZW1lbnRDZmksIFwiXCIpICtcbiAgICAgIFwiLFwiICtcbiAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkucmVwbGFjZShyb290RWxlbWVudENmaSwgXCJcIik7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBjZmksXG4gICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4LFxuICAgIGVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICBlbmRPZmZzZXQ6IHJhbmdlLmVuZE9mZnNldCxcbiAgICBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICBzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICBzdGFydE9mZnNldDogcmFuZ2Uuc3RhcnRPZmZzZXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIHJhbmdlSW5mbykge1xuICBjb25zdCBzdGFydEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIXN0YXJ0RWxlbWVudCkge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gU1RBUlQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBzdGFydENvbnRhaW5lciA9IHN0YXJ0RWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICApIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBzdGFydEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgc3RhcnRDb250YWluZXIgPVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4XTtcbiAgICBpZiAoc3RhcnRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyBzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgY29uc3QgZW5kRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIWVuZEVsZW1lbnQpIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIEVORCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IGVuZENvbnRhaW5lciA9IGVuZEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IGVuZEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICApIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBlbmRDb250YWluZXIgPVxuICAgICAgZW5kRWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChlbmRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyBlbmRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgIGVuZENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uZW5kT2Zmc2V0XG4gICk7XG59XG5cbmZ1bmN0aW9uIGZyYW1lRm9ySGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtXaXRoSUQod2luLCBpZCkge1xuICBsZXQgY2xpZW50UmVjdHMgPSBmcmFtZUZvckhpZ2hsaWdodFdpdGhJRChpZCk7XG4gIGlmICghY2xpZW50UmVjdHMpIHJldHVybjtcblxuICB2YXIgdG9wQ2xpZW50UmVjdCA9IGNsaWVudFJlY3RzWzBdO1xuICB2YXIgbWF4SGVpZ2h0ID0gdG9wQ2xpZW50UmVjdC5oZWlnaHQ7XG4gIGZvciAoY29uc3QgY2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIGlmIChjbGllbnRSZWN0LnRvcCA8IHRvcENsaWVudFJlY3QudG9wKSB0b3BDbGllbnRSZWN0ID0gY2xpZW50UmVjdDtcbiAgICBpZiAoY2xpZW50UmVjdC5oZWlnaHQgPiBtYXhIZWlnaHQpIG1heEhlaWdodCA9IGNsaWVudFJlY3QuaGVpZ2h0O1xuICB9XG5cbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG5cbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuICBjb25zdCBwYWdpbmF0ZWQgPSBpc1BhZ2luYXRlZChkb2N1bWVudCk7XG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgbGV0IHlPZmZzZXQ7XG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCA6IGJvZHlSZWN0LnRvcDtcbiAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiBib2R5UmVjdC50b3A7XG4gIH1cbiAgdmFyIG5ld1RvcCA9IHRvcENsaWVudFJlY3QudG9wO1xuXG4gIGlmIChfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIGRvIHtcbiAgICAgIHZhciBib3VuZGluZ0FyZWFzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcbiAgICAgICAgQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBXG4gICAgICApO1xuICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAvL2ZvciAobGV0IGkgPSAwLCBsZW5ndGggPSBib3VuZGluZ0FyZWFzLnNuYXBzaG90TGVuZ3RoOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICAgIGZvciAoXG4gICAgICAgIHZhciBpID0gMCwgbGVuID0gYm91bmRpbmdBcmVhcy5sZW5ndGggfCAwO1xuICAgICAgICBpIDwgbGVuO1xuICAgICAgICBpID0gKGkgKyAxKSB8IDBcbiAgICAgICkge1xuICAgICAgICB2YXIgYm91bmRpbmdBcmVhID0gYm91bmRpbmdBcmVhc1tpXTtcbiAgICAgICAgaWYgKE1hdGguYWJzKGJvdW5kaW5nQXJlYS5yZWN0LnRvcCAtIChuZXdUb3AgLSB5T2Zmc2V0KSkgPCAzKSB7XG4gICAgICAgICAgbmV3VG9wICs9IGJvdW5kaW5nQXJlYS5yZWN0LmhlaWdodDtcbiAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlIChmb3VuZCk7XG4gIH1cblxuICB0b3BDbGllbnRSZWN0LnRvcCA9IG5ld1RvcDtcbiAgdG9wQ2xpZW50UmVjdC5oZWlnaHQgPSBtYXhIZWlnaHQ7XG5cbiAgcmV0dXJuIHRvcENsaWVudFJlY3Q7XG59XG5cbmZ1bmN0aW9uIGhpZ2hsaWdodFdpdGhJRChpZCkge1xuICBsZXQgaSA9IC0xO1xuICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoLCBqKSA9PiB7XG4gICAgaSA9IGo7XG4gICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICB9KTtcbiAgcmV0dXJuIGhpZ2hsaWdodDtcbn1cblxuZnVuY3Rpb24gZnJhbWVGb3JIaWdobGlnaHRXaXRoSUQoaWQpIHtcbiAgY29uc3QgaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0V2l0aElEKGlkKTtcbiAgaWYgKCFoaWdobGlnaHQpIHJldHVybjtcblxuICBjb25zdCBkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDtcbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuICBjb25zdCByYW5nZSA9IGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIGhpZ2hsaWdodC5yYW5nZUluZm8pO1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGRyYXdVbmRlcmxpbmUgPSBmYWxzZTtcbiAgY29uc3QgZHJhd1N0cmlrZVRocm91Z2ggPSBmYWxzZTtcbiAgY29uc3QgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cyA9IGRyYXdVbmRlcmxpbmUgfHwgZHJhd1N0cmlrZVRocm91Z2g7XG4gIC8vY29uc3QgY2xpZW50UmVjdHMgPSBERUJVR19WSVNVQUxTID8gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKSA6XG4gIGNvbnN0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgcmFuZ2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuXG4gIHJldHVybiBjbGllbnRSZWN0cztcbn1cblxuZnVuY3Rpb24gcmFuZ2VJbmZvMkxvY2F0aW9uKHJhbmdlSW5mbykge1xuICByZXR1cm4ge1xuICAgIGNzc1NlbGVjdG9yOiByYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgcGFydGlhbENmaTogcmFuZ2VJbmZvLmNmaSxcbiAgICBkb21SYW5nZToge1xuICAgICAgc3RhcnQ6IHtcbiAgICAgICAgY3NzU2VsZWN0b3I6IHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICAgICAgdGV4dE5vZGVJbmRleDogcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4LFxuICAgICAgICBvZmZzZXQ6IHJhbmdlSW5mby5zdGFydE9mZnNldCxcbiAgICAgIH0sXG4gICAgICBlbmQ6IHtcbiAgICAgICAgY3NzU2VsZWN0b3I6IHJhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgICAgIHRleHROb2RlSW5kZXg6IHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgICAgIG9mZnNldDogcmFuZ2VJbmZvLmVuZE9mZnNldCxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9jYXRpb24yUmFuZ2VJbmZvKGxvY2F0aW9uKSB7XG4gIGNvbnN0IGxvY2F0aW9ucyA9IGxvY2F0aW9uLmxvY2F0aW9ucztcbiAgY29uc3QgZG9tUmFuZ2UgPSBsb2NhdGlvbnMuZG9tUmFuZ2U7XG4gIGNvbnN0IHN0YXJ0ID0gZG9tUmFuZ2Uuc3RhcnQ7XG4gIGNvbnN0IGVuZCA9IGRvbVJhbmdlLmVuZDtcblxuICByZXR1cm4ge1xuICAgIGNmaTogbG9jYXRpb24ucGFydGlhbENmaSxcbiAgICBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IGVuZC50ZXh0Tm9kZUluZGV4LFxuICAgIGVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcjogZW5kLmNzc1NlbGVjdG9yLFxuICAgIGVuZE9mZnNldDogZW5kLm9mZnNldCxcbiAgICBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogc3RhcnQudGV4dE5vZGVJbmRleCxcbiAgICBzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcjogc3RhcnQuY3NzU2VsZWN0b3IsXG4gICAgc3RhcnRPZmZzZXQ6IHN0YXJ0Lm9mZnNldCxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRChpZCkge1xuICBjb25zdCBoaWdobGlnaHQgPSBoaWdobGlnaHRXaXRoSUQoaWQpO1xuICBpZiAoIWhpZ2hsaWdodCkgcmV0dXJuO1xuXG4gIGNvbnN0IGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHJhbmdlID0gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgaGlnaGxpZ2h0LnJhbmdlSW5mbyk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgZHJhd1VuZGVybGluZSA9IGZhbHNlO1xuICBjb25zdCBkcmF3U3RyaWtlVGhyb3VnaCA9IGZhbHNlO1xuICBjb25zdCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gZHJhd1VuZGVybGluZSB8fCBkcmF3U3RyaWtlVGhyb3VnaDtcbiAgLy9jb25zdCBjbGllbnRSZWN0cyA9IERFQlVHX1ZJU1VBTFMgPyByYW5nZS5nZXRDbGllbnRSZWN0cygpIDpcbiAgY29uc3QgY2xpZW50UmVjdHMgPSBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgICByYW5nZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG4gIHZhciBzaXplID0ge1xuICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICBzY3JlZW5IZWlnaHQ6IHdpbmRvdy5vdXRlckhlaWdodCxcbiAgICBsZWZ0OiBjbGllbnRSZWN0c1swXS5sZWZ0LFxuICAgIHdpZHRoOiBjbGllbnRSZWN0c1swXS53aWR0aCxcbiAgICB0b3A6IGNsaWVudFJlY3RzWzBdLnRvcCxcbiAgICBoZWlnaHQ6IGNsaWVudFJlY3RzWzBdLmhlaWdodCxcbiAgfTtcblxuICByZXR1cm4gc2l6ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNlbGVjdGlvblJlY3QoKSB7XG4gIHRyeSB7XG4gICAgdmFyIHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcmFuZ2UgPSBzZWwuZ2V0UmFuZ2VBdCgwKTtcblxuICAgIGNvbnN0IGNsaWVudFJlY3QgPSByYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIHZhciBoYW5kbGVCb3VuZHMgPSB7XG4gICAgICBzY3JlZW5XaWR0aDogd2luZG93Lm91dGVyV2lkdGgsXG4gICAgICBzY3JlZW5IZWlnaHQ6IHdpbmRvdy5vdXRlckhlaWdodCxcbiAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCxcbiAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCxcbiAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgfTtcbiAgICByZXR1cm4gaGFuZGxlQm91bmRzO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFNjcm9sbE1vZGUoZmxhZykge1xuICBpZiAoIWZsYWcpIHtcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19QQUdJTkFURUQpO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX1BBR0lOQVRFRCk7XG4gIH1cbn1cblxuLypcbiBpZiAoZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcikgeyAvLyBJRSA+PSA5OyBvdGhlciBicm93c2Vyc1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjb250ZXh0bWVudScsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIC8vYWxlcnQoXCJZb3UndmUgdHJpZWQgdG8gb3BlbiBjb250ZXh0IG1lbnVcIik7IC8vaGVyZSB5b3UgZHJhdyB5b3VyIG93biBtZW51XG4gICAgICAgICAgICAvL2UucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIC8vbGV0IGdldENzc1NlbGVjdG9yID0gZnVsbFF1YWxpZmllZFNlbGVjdG9yO1xuICAgICAgICAgICAgXG5cdFx0XHRsZXQgc3RyID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuXHRcdFx0bGV0IHNlbGVjdGlvbkluZm8gPSBnZXRDdXJyZW50U2VsZWN0aW9uSW5mbygpO1xuXHRcdFx0bGV0IHBvcyA9IGNyZWF0ZUhpZ2hsaWdodChzZWxlY3Rpb25JbmZvLHtyZWQ6MTAsZ3JlZW46NTAsYmx1ZToyMzB9LHRydWUpO1xuXHRcdFx0bGV0IHJldDIgPSBjcmVhdGVBbm5vdGF0aW9uKHBvcy5pZCk7XG5cdFx0XHRcbiAgfSwgZmFsc2UpO1xuICAgIH0gZWxzZSB7IC8vIElFIDwgOVxuICAgICAgICBkb2N1bWVudC5hdHRhY2hFdmVudCgnb25jb250ZXh0bWVudScsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgYWxlcnQoXCJZb3UndmUgdHJpZWQgdG8gb3BlbiBjb250ZXh0IG1lbnVcIik7XG4gICAgICAgICAgICB3aW5kb3cuZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuKi9cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjIgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IGlzU2Nyb2xsTW9kZUVuYWJsZWQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgZ2V0Q3NzU2VsZWN0b3IgfSBmcm9tIFwiY3NzLXNlbGVjdG9yLWdlbmVyYXRvclwiO1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IoKSB7XG4gIGNvbnN0IGVsZW1lbnQgPSBmaW5kRWxlbWVudChkb2N1bWVudC5ib2R5KTtcbiAgcmV0dXJuIHtcbiAgICBocmVmOiBcIiNcIixcbiAgICB0eXBlOiBcImFwcGxpY2F0aW9uL3hodG1sK3htbFwiLFxuICAgIGxvY2F0aW9uczoge1xuICAgICAgY3NzU2VsZWN0b3I6IGdldENzc1NlbGVjdG9yKGVsZW1lbnQpLFxuICAgIH0sXG4gICAgdGV4dDoge1xuICAgICAgaGlnaGxpZ2h0OiBlbGVtZW50LnRleHRDb250ZW50LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZpbmRFbGVtZW50KHJvb3RFbGVtZW50KSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcm9vdEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGlsZCA9IHJvb3RFbGVtZW50LmNoaWxkcmVuW2ldO1xuICAgIGlmICghc2hvdWxkSWdub3JlRWxlbWVudChjaGlsZCkgJiYgaXNFbGVtZW50VmlzaWJsZShjaGlsZCkpIHtcbiAgICAgIHJldHVybiBmaW5kRWxlbWVudChjaGlsZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByb290RWxlbWVudDtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50VmlzaWJsZShlbGVtZW50KSB7XG4gIGlmIChyZWFkaXVtLmlzRml4ZWRMYXlvdXQpIHJldHVybiB0cnVlO1xuXG4gIGlmIChlbGVtZW50ID09PSBkb2N1bWVudC5ib2R5IHx8IGVsZW1lbnQgPT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmICghZG9jdW1lbnQgfHwgIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCAhZG9jdW1lbnQuYm9keSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuIHJlY3QuYm90dG9tID4gMCAmJiByZWN0LnRvcCA8IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5sZWZ0IDwgd2luZG93LmlubmVyV2lkdGg7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlRWxlbWVudChlbGVtZW50KSB7XG4gIGNvbnN0IGVsU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICBpZiAoZWxTdHlsZSkge1xuICAgIGNvbnN0IGRpc3BsYXkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJkaXNwbGF5XCIpO1xuICAgIGlmIChkaXNwbGF5ICE9IFwiYmxvY2tcIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENhbm5vdCBiZSByZWxpZWQgdXBvbiwgYmVjYXVzZSB3ZWIgYnJvd3NlciBlbmdpbmUgcmVwb3J0cyBpbnZpc2libGUgd2hlbiBvdXQgb2YgdmlldyBpblxuICAgIC8vIHNjcm9sbGVkIGNvbHVtbnMhXG4gICAgLy8gY29uc3QgdmlzaWJpbGl0eSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcInZpc2liaWxpdHlcIik7XG4gICAgLy8gaWYgKHZpc2liaWxpdHkgPT09IFwiaGlkZGVuXCIpIHtcbiAgICAvLyAgICAgcmV0dXJuIGZhbHNlO1xuICAgIC8vIH1cbiAgICBjb25zdCBvcGFjaXR5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwib3BhY2l0eVwiKTtcbiAgICBpZiAob3BhY2l0eSA9PT0gXCIwXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IGxvZyBhcyBsb2dOYXRpdmUsIGxvZ0Vycm9yLCBzbmFwQ3VycmVudE9mZnNldCB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyB0b05hdGl2ZVJlY3QgfSBmcm9tIFwiLi9yZWN0XCI7XG5pbXBvcnQgeyBUZXh0UmFuZ2UgfSBmcm9tIFwiLi92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZVwiO1xuXG4vLyBQb2x5ZmlsbCBmb3IgQW5kcm9pZCBBUEkgMjZcbmltcG9ydCBtYXRjaEFsbCBmcm9tIFwic3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbFwiO1xubWF0Y2hBbGwuc2hpbSgpO1xuXG5jb25zdCBkZWJ1ZyA9IHRydWU7XG5cbi8vIE5vdGlmeSBuYXRpdmUgY29kZSB0aGF0IHRoZSBzZWxlY3Rpb24gY2hhbmdlcy5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIHZhciBpc1NlbGVjdGluZyA9IGZhbHNlO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzZWxlY3Rpb25jaGFuZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29sbGFwc2VkID0gd2luZG93LmdldFNlbGVjdGlvbigpLmlzQ29sbGFwc2VkO1xuXG4gICAgICBpZiAoY29sbGFwc2VkICYmIGlzU2VsZWN0aW5nKSB7XG4gICAgICAgIGlzU2VsZWN0aW5nID0gZmFsc2U7XG4gICAgICAgIEFuZHJvaWQub25TZWxlY3Rpb25FbmQoKTtcbiAgICAgICAgLy8gU25hcHMgdGhlIGN1cnJlbnQgY29sdW1uIGluIGNhc2UgdGhlIHVzZXIgc2hpZnRlZCB0aGUgc2Nyb2xsIGJ5IGRyYWdnaW5nIHRoZSB0ZXh0IHNlbGVjdGlvbi5cbiAgICAgICAgc25hcEN1cnJlbnRPZmZzZXQoKTtcbiAgICAgIH0gZWxzZSBpZiAoIWNvbGxhcHNlZCAmJiAhaXNTZWxlY3RpbmcpIHtcbiAgICAgICAgaXNTZWxlY3RpbmcgPSB0cnVlO1xuICAgICAgICBBbmRyb2lkLm9uU2VsZWN0aW9uU3RhcnQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDdXJyZW50U2VsZWN0aW9uKCkge1xuICBjb25zdCB0ZXh0ID0gZ2V0Q3VycmVudFNlbGVjdGlvblRleHQoKTtcbiAgaWYgKCF0ZXh0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3QgcmVjdCA9IGdldFNlbGVjdGlvblJlY3QoKTtcbiAgcmV0dXJuIHsgdGV4dCwgcmVjdCB9O1xufVxuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb25SZWN0KCkge1xuICB0cnkge1xuICAgIGxldCBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCk7XG5cbiAgICByZXR1cm4gdG9OYXRpdmVSZWN0KHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ0Vycm9yKGUpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb25UZXh0KCkge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmICghc2VsZWN0aW9uKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBoaWdobGlnaHQgPSBzZWxlY3Rpb24udG9TdHJpbmcoKTtcbiAgY29uc3QgY2xlYW5IaWdobGlnaHQgPSBoaWdobGlnaHRcbiAgICAudHJpbSgpXG4gICAgLnJlcGxhY2UoL1xcbi9nLCBcIiBcIilcbiAgICAucmVwbGFjZSgvXFxzXFxzKy9nLCBcIiBcIik7XG4gIGlmIChjbGVhbkhpZ2hsaWdodC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmICghc2VsZWN0aW9uLmFuY2hvck5vZGUgfHwgIXNlbGVjdGlvbi5mb2N1c05vZGUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJhbmdlID1cbiAgICBzZWxlY3Rpb24ucmFuZ2VDb3VudCA9PT0gMVxuICAgICAgPyBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKVxuICAgICAgOiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck5vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c09mZnNldFxuICAgICAgICApO1xuICBpZiAoIXJhbmdlIHx8IHJhbmdlLmNvbGxhcHNlZCkge1xuICAgIGxvZyhcIiQkJCQkJCQkJCQkJCQkJCQkIENBTk5PVCBHRVQgTk9OLUNPTExBUFNFRCBTRUxFQ1RJT04gUkFOR0U/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmJvZHkudGV4dENvbnRlbnQ7XG4gIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2UocmFuZ2UpLnJlbGF0aXZlVG8oZG9jdW1lbnQuYm9keSk7XG4gIGNvbnN0IHN0YXJ0ID0gdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldDtcbiAgY29uc3QgZW5kID0gdGV4dFJhbmdlLmVuZC5vZmZzZXQ7XG5cbiAgY29uc3Qgc25pcHBldExlbmd0aCA9IDIwMDtcblxuICAvLyBDb21wdXRlIHRoZSB0ZXh0IGJlZm9yZSB0aGUgaGlnaGxpZ2h0LCBpZ25vcmluZyB0aGUgZmlyc3QgXCJ3b3JkXCIsIHdoaWNoIG1pZ2h0IGJlIGN1dC5cbiAgbGV0IGJlZm9yZSA9IHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgc3RhcnQgLSBzbmlwcGV0TGVuZ3RoKSwgc3RhcnQpO1xuICBsZXQgZmlyc3RXb3JkU3RhcnQgPSBiZWZvcmUuc2VhcmNoKC9cXFB7TH1cXHB7TH0vZ3UpO1xuICBpZiAoZmlyc3RXb3JkU3RhcnQgIT09IC0xKSB7XG4gICAgYmVmb3JlID0gYmVmb3JlLnNsaWNlKGZpcnN0V29yZFN0YXJ0ICsgMSk7XG4gIH1cblxuICAvLyBDb21wdXRlIHRoZSB0ZXh0IGFmdGVyIHRoZSBoaWdobGlnaHQsIGlnbm9yaW5nIHRoZSBsYXN0IFwid29yZFwiLCB3aGljaCBtaWdodCBiZSBjdXQuXG4gIGxldCBhZnRlciA9IHRleHQuc2xpY2UoZW5kLCBNYXRoLm1pbih0ZXh0Lmxlbmd0aCwgZW5kICsgc25pcHBldExlbmd0aCkpO1xuICBsZXQgbGFzdFdvcmRFbmQgPSBBcnJheS5mcm9tKGFmdGVyLm1hdGNoQWxsKC9cXHB7TH1cXFB7TH0vZ3UpKS5wb3AoKTtcbiAgaWYgKGxhc3RXb3JkRW5kICE9PSB1bmRlZmluZWQgJiYgbGFzdFdvcmRFbmQuaW5kZXggPiAxKSB7XG4gICAgYWZ0ZXIgPSBhZnRlci5zbGljZSgwLCBsYXN0V29yZEVuZC5pbmRleCArIDEpO1xuICB9XG5cbiAgcmV0dXJuIHsgaGlnaGxpZ2h0LCBiZWZvcmUsIGFmdGVyIH07XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9yZGVyZWRSYW5nZShzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0LCBlbmROb2RlLCBlbmRPZmZzZXQpIHtcbiAgY29uc3QgcmFuZ2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIHJhbmdlLnNldEVuZChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICBpZiAoIXJhbmdlLmNvbGxhcHNlZCkge1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIENPTExBUFNFRCAuLi4gUkFOR0UgUkVWRVJTRT9cIik7XG4gIGNvbnN0IHJhbmdlUmV2ZXJzZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZVJldmVyc2Uuc2V0U3RhcnQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgcmFuZ2VSZXZlcnNlLnNldEVuZChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgaWYgKCFyYW5nZVJldmVyc2UuY29sbGFwc2VkKSB7XG4gICAgbG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIE9LLlwiKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgbG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIEFMU08gQ09MTEFQU0VEPyFcIik7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCByYW5nZUluZm8pIHtcbiAgY29uc3Qgc3RhcnRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFzdGFydEVsZW1lbnQpIHtcbiAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBTVEFSVCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IHN0YXJ0Q29udGFpbmVyID0gc3RhcnRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgbG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBzdGFydEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgc3RhcnRDb250YWluZXIgPVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4XTtcbiAgICBpZiAoc3RhcnRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIGNvbnN0IGVuZEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFlbmRFbGVtZW50KSB7XG4gICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gRU5EIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgZW5kQ29udGFpbmVyID0gZW5kRWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgbG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBlbmRDb250YWluZXIgPVxuICAgICAgZW5kRWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChlbmRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBlbmRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFPyFcIik7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5zdGFydE9mZnNldCxcbiAgICBlbmRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLmVuZE9mZnNldFxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9jYXRpb24yUmFuZ2VJbmZvKGxvY2F0aW9uKSB7XG4gIGNvbnN0IGxvY2F0aW9ucyA9IGxvY2F0aW9uLmxvY2F0aW9ucztcbiAgY29uc3QgZG9tUmFuZ2UgPSBsb2NhdGlvbnMuZG9tUmFuZ2U7XG4gIGNvbnN0IHN0YXJ0ID0gZG9tUmFuZ2Uuc3RhcnQ7XG4gIGNvbnN0IGVuZCA9IGRvbVJhbmdlLmVuZDtcblxuICByZXR1cm4ge1xuICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogZW5kLnRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBlbmQuY3NzU2VsZWN0b3IsXG4gICAgZW5kT2Zmc2V0OiBlbmQub2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBzdGFydC50ZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBzdGFydC5jc3NTZWxlY3RvcixcbiAgICBzdGFydE9mZnNldDogc3RhcnQub2Zmc2V0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBsb2coKSB7XG4gIGlmIChkZWJ1Zykge1xuICAgIGxvZ05hdGl2ZS5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICB9XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG4vLyBCYXNlIHNjcmlwdCB1c2VkIGJ5IGJvdGggcmVmbG93YWJsZSBhbmQgZml4ZWQgbGF5b3V0IHJlc291cmNlcy5cblxuaW1wb3J0IFwiLi9nZXN0dXJlc1wiO1xuaW1wb3J0IHtcbiAgcmVtb3ZlUHJvcGVydHksXG4gIHNjcm9sbExlZnQsXG4gIHNjcm9sbFJpZ2h0LFxuICBzY3JvbGxUb0VuZCxcbiAgc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9Qb3NpdGlvbixcbiAgc2Nyb2xsVG9TdGFydCxcbiAgc2Nyb2xsVG9UZXh0LFxuICBzZXRQcm9wZXJ0eSxcbiAgc2V0Q1NTUHJvcGVydGllcyxcbn0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7XG4gIGNyZWF0ZUFubm90YXRpb24sXG4gIGNyZWF0ZUhpZ2hsaWdodCxcbiAgZGVzdHJveUhpZ2hsaWdodCxcbiAgZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8sXG4gIGdldFNlbGVjdGlvblJlY3QsXG4gIHJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRCxcbiAgc2V0U2Nyb2xsTW9kZSxcbn0gZnJvbSBcIi4vaGlnaGxpZ2h0XCI7XG5pbXBvcnQgeyBmaW5kRmlyc3RWaXNpYmxlTG9jYXRvciB9IGZyb20gXCIuL2RvbVwiO1xuaW1wb3J0IHsgZ2V0Q3VycmVudFNlbGVjdGlvbiB9IGZyb20gXCIuL3NlbGVjdGlvblwiO1xuaW1wb3J0IHsgZ2V0RGVjb3JhdGlvbnMsIHJlZ2lzdGVyVGVtcGxhdGVzIH0gZnJvbSBcIi4vZGVjb3JhdG9yXCI7XG5cbi8vIFB1YmxpYyBBUEkgdXNlZCBieSB0aGUgbmF2aWdhdG9yLlxud2luZG93LnJlYWRpdW0gPSB7XG4gIC8vIHV0aWxzXG4gIHNjcm9sbFRvSWQ6IHNjcm9sbFRvSWQsXG4gIHNjcm9sbFRvUG9zaXRpb246IHNjcm9sbFRvUG9zaXRpb24sXG4gIHNjcm9sbFRvVGV4dDogc2Nyb2xsVG9UZXh0LFxuICBzY3JvbGxMZWZ0OiBzY3JvbGxMZWZ0LFxuICBzY3JvbGxSaWdodDogc2Nyb2xsUmlnaHQsXG4gIHNjcm9sbFRvU3RhcnQ6IHNjcm9sbFRvU3RhcnQsXG4gIHNjcm9sbFRvRW5kOiBzY3JvbGxUb0VuZCxcbiAgc2V0Q1NTUHJvcGVydGllczogc2V0Q1NTUHJvcGVydGllcyxcbiAgc2V0UHJvcGVydHk6IHNldFByb3BlcnR5LFxuICByZW1vdmVQcm9wZXJ0eTogcmVtb3ZlUHJvcGVydHksXG5cbiAgLy8gc2VsZWN0aW9uXG4gIGdldEN1cnJlbnRTZWxlY3Rpb246IGdldEN1cnJlbnRTZWxlY3Rpb24sXG5cbiAgLy8gZGVjb3JhdGlvblxuICByZWdpc3RlckRlY29yYXRpb25UZW1wbGF0ZXM6IHJlZ2lzdGVyVGVtcGxhdGVzLFxuICBnZXREZWNvcmF0aW9uczogZ2V0RGVjb3JhdGlvbnMsXG5cbiAgLy8gRE9NXG4gIGZpbmRGaXJzdFZpc2libGVMb2NhdG9yOiBmaW5kRmlyc3RWaXNpYmxlTG9jYXRvcixcbn07XG5cbi8vIExlZ2FjeSBoaWdobGlnaHRzIEFQSS5cbndpbmRvdy5jcmVhdGVBbm5vdGF0aW9uID0gY3JlYXRlQW5ub3RhdGlvbjtcbndpbmRvdy5jcmVhdGVIaWdobGlnaHQgPSBjcmVhdGVIaWdobGlnaHQ7XG53aW5kb3cuZGVzdHJveUhpZ2hsaWdodCA9IGRlc3Ryb3lIaWdobGlnaHQ7XG53aW5kb3cuZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8gPSBnZXRDdXJyZW50U2VsZWN0aW9uSW5mbztcbndpbmRvdy5nZXRTZWxlY3Rpb25SZWN0ID0gZ2V0U2VsZWN0aW9uUmVjdDtcbndpbmRvdy5yZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQgPSByZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQ7XG53aW5kb3cuc2V0U2Nyb2xsTW9kZSA9IHNldFNjcm9sbE1vZGU7XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG4vLyBTY3JpcHQgdXNlZCBmb3IgZml4ZWQgbGF5b3V0cyByZXNvdXJjZXMuXG5cbmltcG9ydCBcIi4vaW5kZXhcIjtcblxud2luZG93LnJlYWRpdW0uaXNGaXhlZExheW91dCA9IHRydWU7XG4iXSwibmFtZXMiOlsiYXBwcm94U2VhcmNoIiwic2VhcmNoIiwidGV4dCIsInN0ciIsIm1heEVycm9ycyIsIm1hdGNoUG9zIiwiZXhhY3RNYXRjaGVzIiwiaW5kZXhPZiIsInB1c2giLCJzdGFydCIsImVuZCIsImxlbmd0aCIsImVycm9ycyIsInRleHRNYXRjaFNjb3JlIiwibWF0Y2hlcyIsIm1hdGNoUXVvdGUiLCJxdW90ZSIsImNvbnRleHQiLCJNYXRoIiwibWluIiwic2NvcmVNYXRjaCIsIm1hdGNoIiwicXVvdGVXZWlnaHQiLCJwcmVmaXhXZWlnaHQiLCJzdWZmaXhXZWlnaHQiLCJwb3NXZWlnaHQiLCJxdW90ZVNjb3JlIiwicHJlZml4U2NvcmUiLCJwcmVmaXgiLCJzbGljZSIsIm1heCIsInN1ZmZpeFNjb3JlIiwic3VmZml4IiwicG9zU2NvcmUiLCJoaW50Iiwib2Zmc2V0IiwiYWJzIiwicmF3U2NvcmUiLCJtYXhTY29yZSIsIm5vcm1hbGl6ZWRTY29yZSIsInNjb3JlZE1hdGNoZXMiLCJtYXAiLCJtIiwic2NvcmUiLCJzb3J0IiwiYSIsImIiLCJub2RlVGV4dExlbmd0aCIsIm5vZGUiLCJub2RlVHlwZSIsIk5vZGUiLCJFTEVNRU5UX05PREUiLCJURVhUX05PREUiLCJ0ZXh0Q29udGVudCIsInByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoIiwic2libGluZyIsInByZXZpb3VzU2libGluZyIsInJlc29sdmVPZmZzZXRzIiwiZWxlbWVudCIsIm9mZnNldHMiLCJuZXh0T2Zmc2V0Iiwic2hpZnQiLCJub2RlSXRlciIsIm93bmVyRG9jdW1lbnQiLCJjcmVhdGVOb2RlSXRlcmF0b3IiLCJOb2RlRmlsdGVyIiwiU0hPV19URVhUIiwicmVzdWx0cyIsImN1cnJlbnROb2RlIiwibmV4dE5vZGUiLCJ0ZXh0Tm9kZSIsInVuZGVmaW5lZCIsImRhdGEiLCJSYW5nZUVycm9yIiwiUkVTT0xWRV9GT1JXQVJEUyIsIlJFU09MVkVfQkFDS1dBUkRTIiwiVGV4dFBvc2l0aW9uIiwiRXJyb3IiLCJwYXJlbnQiLCJjb250YWlucyIsImVsIiwicGFyZW50RWxlbWVudCIsIm9wdGlvbnMiLCJlcnIiLCJkaXJlY3Rpb24iLCJ0dyIsImRvY3VtZW50IiwiY3JlYXRlVHJlZVdhbGtlciIsImdldFJvb3ROb2RlIiwiZm9yd2FyZHMiLCJwcmV2aW91c05vZGUiLCJmcm9tUG9pbnQiLCJ0ZXh0T2Zmc2V0IiwiY2hpbGROb2RlcyIsImkiLCJUZXh0UmFuZ2UiLCJyZWxhdGl2ZVRvIiwicmVzb2x2ZSIsInJhbmdlIiwiUmFuZ2UiLCJzZXRTdGFydCIsInNldEVuZCIsInN0YXJ0Q29udGFpbmVyIiwic3RhcnRPZmZzZXQiLCJlbmRDb250YWluZXIiLCJlbmRPZmZzZXQiLCJyb290Iiwibm9kZUZyb21YUGF0aCIsInhwYXRoRnJvbU5vZGUiLCJSYW5nZUFuY2hvciIsIm5vcm1hbGl6ZWRSYW5nZSIsImZyb21SYW5nZSIsInRvUmFuZ2UiLCJ0ZXh0UmFuZ2UiLCJ0eXBlIiwic2VsZWN0b3IiLCJzdGFydFBvcyIsImZyb21DaGFyT2Zmc2V0IiwiZW5kUG9zIiwiVGV4dFBvc2l0aW9uQW5jaG9yIiwiZnJvbU9mZnNldHMiLCJUZXh0UXVvdGVBbmNob3IiLCJleGFjdCIsInRvUG9zaXRpb25BbmNob3IiLCJjb250ZXh0TGVuIiwid2luZG93IiwiYWRkRXZlbnRMaXN0ZW5lciIsImV2ZW50IiwiQW5kcm9pZCIsImxvZ0Vycm9yIiwibWVzc2FnZSIsImZpbGVuYW1lIiwibGluZW5vIiwib2JzZXJ2ZXIiLCJSZXNpemVPYnNlcnZlciIsIm9uVmlld3BvcnRXaWR0aENoYW5nZWQiLCJzbmFwQ3VycmVudE9mZnNldCIsIm9ic2VydmUiLCJib2R5IiwiYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkIiwiaWQiLCJ2aXJ0dWFsQ29sIiwiZ2V0RWxlbWVudEJ5SWQiLCJpc1Njcm9sbE1vZGVFbmFibGVkIiwiZ2V0Q29sdW1uQ291bnRQZXJTY3JlZW4iLCJyZW1vdmUiLCJkb2N1bWVudFdpZHRoIiwic2Nyb2xsaW5nRWxlbWVudCIsInNjcm9sbFdpZHRoIiwiY29sQ291bnQiLCJwYWdlV2lkdGgiLCJoYXNPZGRDb2xDb3VudCIsInJvdW5kIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsInN0eWxlIiwiYnJlYWtCZWZvcmUiLCJpbm5lckhUTUwiLCJhcHBlbmRDaGlsZCIsIndpZHRoIiwiZ2V0Vmlld3BvcnRXaWR0aCIsImRldmljZVBpeGVsUmF0aW8iLCJzZXRQcm9wZXJ0eSIsInBhcnNlSW50IiwiZ2V0Q29tcHV0ZWRTdHlsZSIsImRvY3VtZW50RWxlbWVudCIsImdldFByb3BlcnR5VmFsdWUiLCJ0cmltIiwiaXNSVEwiLCJkaXIiLCJ0b0xvd2VyQ2FzZSIsInNjcm9sbFRvSWQiLCJzY3JvbGxUb1JlY3QiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJzY3JvbGxUb1Bvc2l0aW9uIiwicG9zaXRpb24iLCJzY3JvbGxIZWlnaHQiLCJzY3JvbGxUb3AiLCJmYWN0b3IiLCJzY3JvbGxMZWZ0Iiwic25hcE9mZnNldCIsInNjcm9sbFRvVGV4dCIsInJhbmdlRnJvbUxvY2F0b3IiLCJzY3JvbGxUb1JhbmdlIiwicmVjdCIsInRvcCIsInNjcm9sbFkiLCJpbm5lckhlaWdodCIsImxlZnQiLCJzY3JvbGxYIiwic2Nyb2xsVG9TdGFydCIsInNjcm9sbFRvIiwic2Nyb2xsVG9FbmQiLCJtaW5PZmZzZXQiLCJzY3JvbGxUb09mZnNldCIsInNjcm9sbFJpZ2h0IiwibWF4T2Zmc2V0IiwiY3VycmVudE9mZnNldCIsImRpZmYiLCJ2YWx1ZSIsImRlbHRhIiwibG9jYXRvciIsImxvY2F0aW9ucyIsImhpZ2hsaWdodCIsImNzc1NlbGVjdG9yIiwicXVlcnlTZWxlY3RvciIsImFuY2hvciIsImJlZm9yZSIsImFmdGVyIiwiZnJhZ21lbnRzIiwiaHRtbElkIiwiY3JlYXRlUmFuZ2UiLCJzZXRTdGFydEJlZm9yZSIsInNldEVuZEFmdGVyIiwiZSIsInNldENTU1Byb3BlcnRpZXMiLCJwcm9wZXJ0aWVzIiwibmFtZSIsImtleSIsInJlbW92ZVByb3BlcnR5IiwibG9nIiwiQXJyYXkiLCJwcm90b3R5cGUiLCJjYWxsIiwiYXJndW1lbnRzIiwiam9pbiIsImxvZ05hdGl2ZSIsImRlYnVnIiwidG9OYXRpdmVSZWN0IiwicGl4ZWxSYXRpbyIsImhlaWdodCIsInJpZ2h0IiwiYm90dG9tIiwiZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAiLCJkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzIiwiY2xpZW50UmVjdHMiLCJnZXRDbGllbnRSZWN0cyIsInRvbGVyYW5jZSIsIm9yaWdpbmFsUmVjdHMiLCJyYW5nZUNsaWVudFJlY3QiLCJtZXJnZWRSZWN0cyIsIm1lcmdlVG91Y2hpbmdSZWN0cyIsIm5vQ29udGFpbmVkUmVjdHMiLCJyZW1vdmVDb250YWluZWRSZWN0cyIsIm5ld1JlY3RzIiwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyIsIm1pbkFyZWEiLCJqIiwiYmlnRW5vdWdoIiwic3BsaWNlIiwicmVjdHMiLCJyZWN0MSIsInJlY3QyIiwicmVjdHNMaW5lVXBWZXJ0aWNhbGx5IiwiYWxtb3N0RXF1YWwiLCJyZWN0c0xpbmVVcEhvcml6b250YWxseSIsImhvcml6b250YWxBbGxvd2VkIiwiYWxpZ25lZCIsImNhbk1lcmdlIiwicmVjdHNUb3VjaE9yT3ZlcmxhcCIsImZpbHRlciIsInJlcGxhY2VtZW50Q2xpZW50UmVjdCIsImdldEJvdW5kaW5nUmVjdCIsInJlY3RzVG9LZWVwIiwiU2V0IiwiZGVsZXRlIiwicG9zc2libHlDb250YWluaW5nUmVjdCIsImhhcyIsInJlY3RDb250YWlucyIsImZyb20iLCJyZWN0Q29udGFpbnNQb2ludCIsIngiLCJ5IiwidG9BZGQiLCJ0b1JlbW92ZSIsInN1YnRyYWN0UmVjdHMxIiwicmVjdFN1YnRyYWN0Iiwic3VidHJhY3RSZWN0czIiLCJhcHBseSIsInJlY3RJbnRlcnNlY3RlZCIsInJlY3RJbnRlcnNlY3QiLCJyZWN0QSIsInJlY3RCIiwicmVjdEMiLCJyZWN0RCIsIm1heExlZnQiLCJtaW5SaWdodCIsIm1heFRvcCIsIm1pbkJvdHRvbSIsInN0eWxlcyIsIk1hcCIsImdyb3VwcyIsImxhc3RHcm91cElkIiwicmVnaXN0ZXJUZW1wbGF0ZXMiLCJuZXdTdHlsZXMiLCJzdHlsZXNoZWV0IiwiT2JqZWN0IiwiZW50cmllcyIsInNldCIsInN0eWxlRWxlbWVudCIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwiZ2V0RGVjb3JhdGlvbnMiLCJncm91cE5hbWUiLCJncm91cCIsImdldCIsIkRlY29yYXRpb25Hcm91cCIsImhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50IiwiY2xpY2tFdmVudCIsInNpemUiLCJmaW5kVGFyZ2V0IiwiZ3JvdXBDb250ZW50IiwiaXRlbXMiLCJyZXZlcnNlIiwiaXRlbSIsImNsaWNrYWJsZUVsZW1lbnRzIiwidG9KU09OIiwiY2xpZW50WCIsImNsaWVudFkiLCJ0YXJnZXQiLCJvbkRlY29yYXRpb25BY3RpdmF0ZWQiLCJKU09OIiwic3RyaW5naWZ5IiwiZGVjb3JhdGlvbiIsImNsaWNrIiwiZ3JvdXBJZCIsImxhc3RJdGVtSWQiLCJjb250YWluZXIiLCJhZGQiLCJsYXlvdXQiLCJkZWNvcmF0aW9uSWQiLCJpbmRleCIsImZpbmRJbmRleCIsInVwZGF0ZSIsImNsZWFyIiwiY2xlYXJDb250YWluZXIiLCJyZXF1ZXN0TGF5b3V0IiwiZm9yRWFjaCIsImdyb3VwQ29udGFpbmVyIiwicmVxdWlyZUNvbnRhaW5lciIsIml0ZW1Db250YWluZXIiLCJ2aWV3cG9ydFdpZHRoIiwiaW5uZXJXaWR0aCIsImNvbHVtbkNvdW50IiwieE9mZnNldCIsInlPZmZzZXQiLCJwb3NpdGlvbkVsZW1lbnQiLCJib3VuZGluZ1JlY3QiLCJmbG9vciIsImVsZW1lbnRUZW1wbGF0ZSIsInRlbXBsYXRlIiwiY29udGVudCIsImZpcnN0RWxlbWVudENoaWxkIiwiZXJyb3IiLCJyMSIsInIyIiwiY2xpZW50UmVjdCIsImxpbmUiLCJjbG9uZU5vZGUiLCJhcHBlbmQiLCJib3VuZHMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiY2hpbGRyZW4iLCJsYXN0U2l6ZSIsImNsaWVudFdpZHRoIiwiY2xpZW50SGVpZ2h0Iiwib25DbGljayIsImJpbmREcmFnR2VzdHVyZSIsImdldFNlbGVjdGlvbiIsImlzQ29sbGFwc2VkIiwiZGVmYXVsdFByZXZlbnRlZCIsInRhcmdldEVsZW1lbnQiLCJvdXRlckhUTUwiLCJpbnRlcmFjdGl2ZUVsZW1lbnQiLCJuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50Iiwic2hvdWxkUHJldmVudERlZmF1bHQiLCJvblRhcCIsInN0b3BQcm9wYWdhdGlvbiIsInByZXZlbnREZWZhdWx0Iiwib25TdGFydCIsInBhc3NpdmUiLCJvbkVuZCIsIm9uTW92ZSIsInN0YXRlIiwiaXNTdGFydGluZ0RyYWciLCJzdGFydFgiLCJ0b3VjaGVzIiwic3RhcnRZIiwiY3VycmVudFgiLCJjdXJyZW50WSIsIm9mZnNldFgiLCJvZmZzZXRZIiwib25EcmFnU3RhcnQiLCJvbkRyYWdNb3ZlIiwib25EcmFnRW5kIiwiaW50ZXJhY3RpdmVUYWdzIiwibm9kZU5hbWUiLCJoYXNBdHRyaWJ1dGUiLCJnZXRBdHRyaWJ1dGUiLCJST09UX0NMQVNTX1JFRFVDRV9NT1RJT04iLCJST09UX0NMQVNTX05PX0ZPT1ROT1RFUyIsIlBPUFVQX0RJQUxPR19DTEFTUyIsIkZPT1ROT1RFU19DT05UQUlORVJfQ0xBU1MiLCJGT09UTk9URVNfQ0xPU0VfQlVUVE9OX0NMQVNTIiwiRk9PVE5PVEVfRk9SQ0VfU0hPVyIsIlRUU19JRF9QUkVWSU9VUyIsIlRUU19JRF9ORVhUIiwiVFRTX0lEX1NMSURFUiIsIlRUU19JRF9BQ1RJVkVfV09SRCIsIlRUU19JRF9DT05UQUlORVIiLCJUVFNfSURfSU5GTyIsIlRUU19OQVZfQlVUVE9OX0NMQVNTIiwiVFRTX0lEX1NQRUFLSU5HX0RPQ19FTEVNRU5UIiwiVFRTX0NMQVNTX0lOSkVDVEVEX1NQQU4iLCJUVFNfQ0xBU1NfSU5KRUNURURfU1VCU1BBTiIsIlRUU19JRF9JTkpFQ1RFRF9QQVJFTlQiLCJJRF9ISUdITElHSFRTX0NPTlRBSU5FUiIsIklEX0FOTk9UQVRJT05fQ09OVEFJTkVSIiwiQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUiIsIkNMQVNTX0FOTk9UQVRJT05fQ09OVEFJTkVSIiwiQ0xBU1NfSElHSExJR0hUX0FSRUEiLCJDTEFTU19BTk5PVEFUSU9OX0FSRUEiLCJDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSIsIkNMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQSIsIl9ibGFja2xpc3RJZENsYXNzRm9yQ0ZJIiwiQ0xBU1NfUEFHSU5BVEVEIiwiSVNfREVWIiwiX2hpZ2hsaWdodHMiLCJfaGlnaGxpZ2h0c0NvbnRhaW5lciIsIl9hbm5vdGF0aW9uQ29udGFpbmVyIiwibGFzdE1vdXNlRG93blgiLCJsYXN0TW91c2VEb3duWSIsImJvZHlFdmVudExpc3RlbmVyc1NldCIsIlVTRV9TVkciLCJERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWSIsIkFMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkiLCJERUJVR19WSVNVQUxTIiwiREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SIiwiYmx1ZSIsImdyZWVuIiwicmVkIiwiQU5OT1RBVElPTl9XSURUSCIsInJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSIsIl93aW4iLCJoaWdobGlnaHRCb3VuZGluZyIsIm91dGxpbmUiLCJzZXRIaWdobGlnaHRBcmVhU3R5bGUiLCJ3aW4iLCJoaWdobGlnaHRBcmVhcyIsInVzZVNWRyIsImhpZ2hsaWdodEFyZWEiLCJpc1NWRyIsIm5hbWVzcGFjZVVSSSIsIlNWR19YTUxfTkFNRVNQQUNFIiwib3BhY2l0eSIsImNvbG9yIiwicmVzZXRIaWdobGlnaHRBcmVhU3R5bGUiLCJwYXJlbnROb2RlIiwiZmluZCIsImgiLCJwcm9jZXNzVG91Y2hFdmVudCIsImV2Iiwic2Nyb2xsRWxlbWVudCIsImdldFNjcm9sbGluZ0VsZW1lbnQiLCJjaGFuZ2VkVG91Y2hlcyIsInBhZ2luYXRlZCIsImlzUGFnaW5hdGVkIiwiYm9keVJlY3QiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJmb3VuZEhpZ2hsaWdodCIsImZvdW5kRWxlbWVudCIsImZvdW5kUmVjdCIsImhpZ2hsaWdodFBhcmVudCIsImhpdCIsImhpZ2hsaWdodEZyYWdtZW50cyIsImhpZ2hsaWdodEZyYWdtZW50Iiwid2l0aFJlY3QiLCJoaWdobGlnaHRCb3VuZGluZ3MiLCJhbGxIaWdobGlnaHRBcmVhcyIsImZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzIiwiZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmciLCJhbGxIaWdobGlnaHRCb3VuZGluZ3MiLCJzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlIiwic2NyZWVuV2lkdGgiLCJvdXRlcldpZHRoIiwic2NyZWVuSGVpZ2h0Iiwib3V0ZXJIZWlnaHQiLCJwYXlsb2FkIiwicHJvY2VzcyIsImVsZWN0cm9uXzEiLCJpcGNSZW5kZXJlciIsInNlbmRUb0hvc3QiLCJSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0siLCJ3ZWJraXRVUkwiLCJjb25zb2xlIiwiaW5jbHVkZXMiLCJoaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZCIsIndlYmtpdCIsIm1lc3NhZ2VIYW5kbGVycyIsInBvc3RNZXNzYWdlIiwiaGlnaGxpZ2h0QWN0aXZhdGVkIiwicHJvY2Vzc01vdXNlRXZlbnQiLCJ0b3VjaGVkUG9zaXRpb24iLCJ0b1ByZXNlcnZlIiwidG9DaGVjayIsImNoZWNrT3ZlcmxhcHMiLCJzdGlsbE92ZXJsYXBpbmdSZWN0cyIsImhhczEiLCJoYXMyIiwieE92ZXJsYXAiLCJnZXRSZWN0T3ZlcmxhcFgiLCJ5T3ZlcmxhcCIsImdldFJlY3RPdmVybGFwWSIsInJhbmdlQ2xpZW50UmVjdHMiLCJnZXRDbGllbnRSZWN0c05vT3ZlcmxhcF8iLCJjbGFzc0xpc3QiLCJlbnN1cmVDb250YWluZXIiLCJhbm5vdGF0aW9uRmxhZyIsInRvdWNoRW5kIiwiaGlkZUFsbGhpZ2hsaWdodHMiLCJkZXN0cm95QWxsaGlnaGxpZ2h0cyIsImRlc3Ryb3lIaWdobGlnaHQiLCJfZG9jdW1lbnQiLCJoaWdobGlnaHRDb250YWluZXIiLCJpc0NmaVRleHROb2RlIiwiZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4IiwiY2hpbGQiLCJmb3VuZCIsInRleHROb2RlSW5kZXgiLCJwcmV2aW91c1dhc0VsZW1lbnQiLCJjaGlsZE5vZGUiLCJpc1RleHQiLCJnZXRDb21tb25BbmNlc3RvckVsZW1lbnQiLCJub2RlMSIsIm5vZGUyIiwibm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbiIsIm5vZGUyRWxlbWVudEFuY2VzdG9yQ2hhaW4iLCJjb21tb25BbmNlc3RvciIsIm5vZGUxRWxlbWVudEFuY2VzdG9yIiwibm9kZTJFbGVtZW50QW5jZXN0b3IiLCJmdWxsUXVhbGlmaWVkU2VsZWN0b3IiLCJsb3dlckNhc2VOYW1lIiwibG9jYWxOYW1lIiwiY3NzUGF0aCIsImdldEN1cnJlbnRTZWxlY3Rpb25JbmZvIiwic2VsZWN0aW9uIiwicmF3VGV4dCIsInRvU3RyaW5nIiwiY2xlYW5UZXh0IiwicmVwbGFjZSIsImFuY2hvck5vZGUiLCJmb2N1c05vZGUiLCJyYW5nZUNvdW50IiwiZ2V0UmFuZ2VBdCIsImNyZWF0ZU9yZGVyZWRSYW5nZSIsImFuY2hvck9mZnNldCIsImZvY3VzT2Zmc2V0IiwiY29sbGFwc2VkIiwicmFuZ2VJbmZvIiwiY29udmVydFJhbmdlIiwiY29tcHV0ZUNGSSIsInJlc3RvcmVkUmFuZ2UiLCJjb252ZXJ0UmFuZ2VJbmZvIiwiZHVtcERlYnVnIiwiZ2V0Q3NzU2VsZWN0b3IiLCJyYW5nZUluZm8yTG9jYXRpb24iLCJjaGVja0JsYWNrbGlzdGVkIiwiYmxhY2tsaXN0ZWRJZCIsImJsYWNrbGlzdGVkQ2xhc3MiLCJvcHRpbWl6ZWQiLCJzdGVwcyIsImNvbnRleHROb2RlIiwic3RlcCIsIl9jc3NQYXRoU3RlcCIsImlzVGFyZ2V0Tm9kZSIsInByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMiLCJuZCIsImNsYXNzQXR0cmlidXRlIiwic3BsaXQiLCJCb29sZWFuIiwibm0iLCJpZFNlbGVjdG9yIiwiaWRkIiwiZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkIiwiaWRlbnQiLCJpc0NTU0lkZW50aWZpZXIiLCJzaG91bGRFc2NhcGVGaXJzdCIsInRlc3QiLCJsYXN0SW5kZXgiLCJjIiwiaWkiLCJpc0NTU0lkZW50Q2hhciIsImVzY2FwZUFzY2lpQ2hhciIsImlzTGFzdCIsInRvSGV4Qnl0ZSIsImhleEJ5dGUiLCJjaGFyQ29kZUF0IiwiRE9DVU1FTlRfTk9ERSIsInByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5XyIsInByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5IiwiYXJySXRlbSIsIm5lZWRzQ2xhc3NOYW1lcyIsIm5lZWRzTnRoQ2hpbGQiLCJvd25JbmRleCIsImVsZW1lbnRJbmRleCIsInNpYmxpbmdzIiwic2libGluZ05hbWUiLCJvd25DbGFzc05hbWVzIiwib3duQ2xhc3NOYW1lQ291bnQiLCJzaWJsaW5nQ2xhc3NOYW1lc0FycmF5XyIsInNpYmxpbmdDbGFzc05hbWVzQXJyYXkiLCJzaWJsaW5nQ2xhc3MiLCJpbmQiLCJyZXN1bHQiLCJwcmVmaXhlZE5hbWUiLCJzdWJzdHIiLCJjZmkiLCJjdXJyZW50RWxlbWVudCIsImJsYWNrbGlzdGVkIiwiY3VycmVudEVsZW1lbnRQYXJlbnRDaGlsZHJlbiIsImN1cnJlbnRFbGVtZW50SW5kZXgiLCJjZmlJbmRleCIsIl9jcmVhdGVIaWdobGlnaHQiLCJwb2ludGVySW50ZXJhY3Rpb24iLCJsb2NhdGlvbjJSYW5nZUluZm8iLCJ1bmlxdWVTdHIiLCJzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciIsInN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IiwiZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yIiwiZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IiwiaGFzaCIsInJlcXVpcmUiLCJzaGEyNTZIZXgiLCJzaGEyNTYiLCJkaWdlc3QiLCJjcmVhdGVIaWdobGlnaHREb20iLCJjcmVhdGVIaWdobGlnaHQiLCJzZWxlY3Rpb25JbmZvIiwiY3JlYXRlQW5ub3RhdGlvbiIsInNjYWxlIiwiUkVBRElVTTIiLCJpc0ZpeGVkTGF5b3V0IiwiZnhsVmlld3BvcnRTY2FsZSIsImhpZ2hsaWdodHNDb250YWluZXIiLCJkcmF3VW5kZXJsaW5lIiwiZHJhd1N0cmlrZVRocm91Z2giLCJoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZyIsInJvdW5kZWRDb3JuZXIiLCJ1bmRlcmxpbmVUaGlja25lc3MiLCJzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyIsImV4dHJhIiwicmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0IiwiZnJhbWVGb3JIaWdobGlnaHRBbm5vdGF0aW9uTWFya1dpdGhJRCIsImFubm90YXRpb25PZmZzZXQiLCJib3JkZXJUaGlja25lc3MiLCJjcmVhdGVEb2N1bWVudEZyYWdtZW50IiwiaGlnaGxpZ2h0QXJlYVNWR1JlY3QiLCJjcmVhdGVFbGVtZW50TlMiLCJoaWdobGlnaHRBcmVhU1ZHTGluZSIsImxpbmVPZmZzZXQiLCJyZ2IiLCJyYW5kb20iLCJyIiwiZyIsImhpZ2hsaWdodEFyZWFMaW5lIiwiaGlnaGxpZ2h0QXJlYVNWRyIsIm92ZXJmbG93IiwicmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QiLCJzdGFydE5vZGUiLCJlbmROb2RlIiwicmFuZ2VSZXZlcnNlIiwiY29tcHV0ZUVsZW1lbnRDRkkiLCJzdGFydElzRWxlbWVudCIsInN0YXJ0Q29udGFpbmVyRWxlbWVudCIsImVuZElzRWxlbWVudCIsImVuZENvbnRhaW5lckVsZW1lbnQiLCJjb21tb25FbGVtZW50QW5jZXN0b3IiLCJjb21tb25BbmNlc3RvckNvbnRhaW5lciIsInJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50Iiwicm9vdEVsZW1lbnRDZmkiLCJzdGFydEVsZW1lbnRDZmkiLCJlbmRFbGVtZW50Q2ZpIiwic3RhcnRFbGVtZW50T3JUZXh0Q2ZpIiwic3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkiLCJjZmlUZXh0Tm9kZUluZGV4IiwiY2ZpSW5kZXhPZkxhc3RFbGVtZW50IiwiY2hpbGRFbGVtZW50Q291bnQiLCJsYXN0Q2hpbGROb2RlIiwiZW5kRWxlbWVudE9yVGV4dENmaSIsImVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSIsInN0YXJ0RWxlbWVudCIsImVuZEVsZW1lbnQiLCJmcmFtZUZvckhpZ2hsaWdodFdpdGhJRCIsInRvcENsaWVudFJlY3QiLCJtYXhIZWlnaHQiLCJuZXdUb3AiLCJib3VuZGluZ0FyZWFzIiwiZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSIsImxlbiIsImJvdW5kaW5nQXJlYSIsImhpZ2hsaWdodFdpdGhJRCIsInBhcnRpYWxDZmkiLCJkb21SYW5nZSIsImxvY2F0aW9uIiwicmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEIiwiZ2V0U2VsZWN0aW9uUmVjdCIsInNlbCIsImhhbmRsZUJvdW5kcyIsInNldFNjcm9sbE1vZGUiLCJmbGFnIiwiZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IiLCJmaW5kRWxlbWVudCIsImhyZWYiLCJyb290RWxlbWVudCIsInNob3VsZElnbm9yZUVsZW1lbnQiLCJpc0VsZW1lbnRWaXNpYmxlIiwicmVhZGl1bSIsImVsU3R5bGUiLCJkaXNwbGF5IiwibWF0Y2hBbGwiLCJzaGltIiwiaXNTZWxlY3RpbmciLCJvblNlbGVjdGlvbkVuZCIsIm9uU2VsZWN0aW9uU3RhcnQiLCJnZXRDdXJyZW50U2VsZWN0aW9uIiwiZ2V0Q3VycmVudFNlbGVjdGlvblRleHQiLCJjbGVhbkhpZ2hsaWdodCIsInNuaXBwZXRMZW5ndGgiLCJmaXJzdFdvcmRTdGFydCIsImxhc3RXb3JkRW5kIiwicG9wIiwicmVnaXN0ZXJEZWNvcmF0aW9uVGVtcGxhdGVzIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6396\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},3715:function(__unused_webpack_module,exports,__webpack_require__){eval("var hash = exports;\n\nhash.utils = __webpack_require__(6436);\nhash.common = __webpack_require__(5772);\nhash.sha = __webpack_require__(9041);\nhash.ripemd = __webpack_require__(2949);\nhash.hmac = __webpack_require__(2344);\n\n// Proxy hash functions to the main object\nhash.sha1 = hash.sha.sha1;\nhash.sha256 = hash.sha.sha256;\nhash.sha224 = hash.sha.sha224;\nhash.sha384 = hash.sha.sha384;\nhash.sha512 = hash.sha.sha512;\nhash.ripemd160 = hash.ripemd.ripemd160;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcxNS5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQSxhQUFhLG1CQUFPLENBQUMsSUFBYztBQUNuQyxjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBWTtBQUMvQixjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsSUFBYTs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanM/N2Q5MiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3715\n")},5772:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction BlockHash() {\n this.pending = null;\n this.pendingTotal = 0;\n this.blockSize = this.constructor.blockSize;\n this.outSize = this.constructor.outSize;\n this.hmacStrength = this.constructor.hmacStrength;\n this.padLength = this.constructor.padLength / 8;\n this.endian = 'big';\n\n this._delta8 = this.blockSize / 8;\n this._delta32 = this.blockSize / 32;\n}\nexports.BlockHash = BlockHash;\n\nBlockHash.prototype.update = function update(msg, enc) {\n // Convert message to array, pad it, and join into 32bit blocks\n msg = utils.toArray(msg, enc);\n if (!this.pending)\n this.pending = msg;\n else\n this.pending = this.pending.concat(msg);\n this.pendingTotal += msg.length;\n\n // Enough data, try updating\n if (this.pending.length >= this._delta8) {\n msg = this.pending;\n\n // Process pending data in blocks\n var r = msg.length % this._delta8;\n this.pending = msg.slice(msg.length - r, msg.length);\n if (this.pending.length === 0)\n this.pending = null;\n\n msg = utils.join32(msg, 0, msg.length - r, this.endian);\n for (var i = 0; i < msg.length; i += this._delta32)\n this._update(msg, i, i + this._delta32);\n }\n\n return this;\n};\n\nBlockHash.prototype.digest = function digest(enc) {\n this.update(this._pad());\n assert(this.pending === null);\n\n return this._digest(enc);\n};\n\nBlockHash.prototype._pad = function pad() {\n var len = this.pendingTotal;\n var bytes = this._delta8;\n var k = bytes - ((len + this.padLength) % bytes);\n var res = new Array(k + this.padLength);\n res[0] = 0x80;\n for (var i = 1; i < k; i++)\n res[i] = 0;\n\n // Append length\n len <<= 3;\n if (this.endian === 'big') {\n for (var t = 8; t < this.padLength; t++)\n res[i++] = 0;\n\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = len & 0xff;\n } else {\n res[i++] = len & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n\n for (t = 8; t < this.padLength; t++)\n res[i++] = 0;\n }\n\n return res;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTc3Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLE9BQU87QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzP2VkYzkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5772\n")},2344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction Hmac(hash, key, enc) {\n if (!(this instanceof Hmac))\n return new Hmac(hash, key, enc);\n this.Hash = hash;\n this.blockSize = hash.blockSize / 8;\n this.outSize = hash.outSize / 8;\n this.inner = null;\n this.outer = null;\n\n this._init(utils.toArray(key, enc));\n}\nmodule.exports = Hmac;\n\nHmac.prototype._init = function init(key) {\n // Shorten key, if needed\n if (key.length > this.blockSize)\n key = new this.Hash().update(key).digest();\n assert(key.length <= this.blockSize);\n\n // Add padding to key\n for (var i = key.length; i < this.blockSize; i++)\n key.push(0);\n\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x36;\n this.inner = new this.Hash().update(key);\n\n // 0x36 ^ 0x5c = 0x6a\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x6a;\n this.outer = new this.Hash().update(key);\n};\n\nHmac.prototype.update = function update(msg, enc) {\n this.inner.update(msg, enc);\n return this;\n};\n\nHmac.prototype.digest = function digest(enc) {\n this.outer.update(this.inner.digest());\n return this.outer.digest(enc);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsb0JBQW9CO0FBQy9DOztBQUVBLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvaG1hYy5qcz8yMTM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gSG1hYyhoYXNoLCBrZXksIGVuYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hYykpXG4gICAgcmV0dXJuIG5ldyBIbWFjKGhhc2gsIGtleSwgZW5jKTtcbiAgdGhpcy5IYXNoID0gaGFzaDtcbiAgdGhpcy5ibG9ja1NpemUgPSBoYXNoLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMub3V0U2l6ZSA9IGhhc2gub3V0U2l6ZSAvIDg7XG4gIHRoaXMuaW5uZXIgPSBudWxsO1xuICB0aGlzLm91dGVyID0gbnVsbDtcblxuICB0aGlzLl9pbml0KHV0aWxzLnRvQXJyYXkoa2V5LCBlbmMpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hYztcblxuSG1hYy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGtleSkge1xuICAvLyBTaG9ydGVuIGtleSwgaWYgbmVlZGVkXG4gIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpXG4gICAga2V5ID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xuICBhc3NlcnQoa2V5Lmxlbmd0aCA8PSB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gQWRkIHBhZGRpbmcgdG8ga2V5XG4gIGZvciAodmFyIGkgPSBrZXkubGVuZ3RoOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKylcbiAgICBrZXkucHVzaCgwKTtcblxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDM2O1xuICB0aGlzLmlubmVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xuXG4gIC8vIDB4MzYgXiAweDVjID0gMHg2YVxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2344\n")},2949:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_3 = utils.sum32_3;\nvar sum32_4 = utils.sum32_4;\nvar BlockHash = common.BlockHash;\n\nfunction RIPEMD160() {\n if (!(this instanceof RIPEMD160))\n return new RIPEMD160();\n\n BlockHash.call(this);\n\n this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];\n this.endian = 'little';\n}\nutils.inherits(RIPEMD160, BlockHash);\nexports.ripemd160 = RIPEMD160;\n\nRIPEMD160.blockSize = 512;\nRIPEMD160.outSize = 160;\nRIPEMD160.hmacStrength = 192;\nRIPEMD160.padLength = 64;\n\nRIPEMD160.prototype._update = function update(msg, start) {\n var A = this.h[0];\n var B = this.h[1];\n var C = this.h[2];\n var D = this.h[3];\n var E = this.h[4];\n var Ah = A;\n var Bh = B;\n var Ch = C;\n var Dh = D;\n var Eh = E;\n for (var j = 0; j < 80; j++) {\n var T = sum32(\n rotl32(\n sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),\n s[j]),\n E);\n A = E;\n E = D;\n D = rotl32(C, 10);\n C = B;\n B = T;\n T = sum32(\n rotl32(\n sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),\n sh[j]),\n Eh);\n Ah = Eh;\n Eh = Dh;\n Dh = rotl32(Ch, 10);\n Ch = Bh;\n Bh = T;\n }\n T = sum32_3(this.h[1], C, Dh);\n this.h[1] = sum32_3(this.h[2], D, Eh);\n this.h[2] = sum32_3(this.h[3], E, Ah);\n this.h[3] = sum32_3(this.h[4], A, Bh);\n this.h[4] = sum32_3(this.h[0], B, Ch);\n this.h[0] = T;\n};\n\nRIPEMD160.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'little');\n else\n return utils.split32(this.h, 'little');\n};\n\nfunction f(j, x, y, z) {\n if (j <= 15)\n return x ^ y ^ z;\n else if (j <= 31)\n return (x & y) | ((~x) & z);\n else if (j <= 47)\n return (x | (~y)) ^ z;\n else if (j <= 63)\n return (x & z) | (y & (~z));\n else\n return x ^ (y | (~z));\n}\n\nfunction K(j) {\n if (j <= 15)\n return 0x00000000;\n else if (j <= 31)\n return 0x5a827999;\n else if (j <= 47)\n return 0x6ed9eba1;\n else if (j <= 63)\n return 0x8f1bbcdc;\n else\n return 0xa953fd4e;\n}\n\nfunction Kh(j) {\n if (j <= 15)\n return 0x50a28be6;\n else if (j <= 31)\n return 0x5c4dd124;\n else if (j <= 47)\n return 0x6d703ef3;\n else if (j <= 63)\n return 0x7a6d76e9;\n else\n return 0x00000000;\n}\n\nvar r = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,\n 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,\n 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13\n];\n\nvar rh = [\n 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,\n 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,\n 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,\n 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,\n 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11\n];\n\nvar s = [\n 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,\n 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,\n 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,\n 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,\n 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6\n];\n\nvar sh = [\n 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,\n 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,\n 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,\n 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,\n 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11\n];\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBVTs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzP2JiNDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2949\n")},9041:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nexports.sha1 = __webpack_require__(4761);\nexports.sha224 = __webpack_require__(799);\nexports.sha256 = __webpack_require__(9344);\nexports.sha384 = __webpack_require__(772);\nexports.sha512 = __webpack_require__(5900);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA0MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix3Q0FBaUM7QUFDakMseUNBQXFDO0FBQ3JDLDBDQUFxQztBQUNyQyx5Q0FBcUM7QUFDckMsMENBQXFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcz81OTE5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGEvMScpO1xuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYS8yMjQnKTtcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEvMjU2Jyk7XG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhLzM4NCcpO1xuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYS81MTInKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9041\n")},4761:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_5 = utils.sum32_5;\nvar ft_1 = shaCommon.ft_1;\nvar BlockHash = common.BlockHash;\n\nvar sha1_K = [\n 0x5A827999, 0x6ED9EBA1,\n 0x8F1BBCDC, 0xCA62C1D6\n];\n\nfunction SHA1() {\n if (!(this instanceof SHA1))\n return new SHA1();\n\n BlockHash.call(this);\n this.h = [\n 0x67452301, 0xefcdab89, 0x98badcfe,\n 0x10325476, 0xc3d2e1f0 ];\n this.W = new Array(80);\n}\n\nutils.inherits(SHA1, BlockHash);\nmodule.exports = SHA1;\n\nSHA1.blockSize = 512;\nSHA1.outSize = 160;\nSHA1.hmacStrength = 80;\nSHA1.padLength = 64;\n\nSHA1.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n\n for(; i < W.length; i++)\n W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n\n for (i = 0; i < W.length; i++) {\n var s = ~~(i / 20);\n var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);\n e = d;\n d = c;\n c = rotl32(b, 30);\n b = a;\n a = t;\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n};\n\nSHA1.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc2MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVOztBQUVsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixRQUFRO0FBQzFCOztBQUVBLFFBQVEsY0FBYztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzEuanM/MTNlMiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGZ0XzEgPSBzaGFDb21tb24uZnRfMTtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMTtcblxuU0hBMS5ibG9ja1NpemUgPSA1MTI7XG5TSEExLm91dFNpemUgPSAxNjA7XG5TSEExLmhtYWNTdHJlbmd0aCA9IDgwO1xuU0hBMS5wYWRMZW5ndGggPSA2NDtcblxuU0hBMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuXG4gIGZvcig7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSByb3RsMzIoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSwgMSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4761\n")},799:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar SHA256 = __webpack_require__(9344);\n\nfunction SHA224() {\n if (!(this instanceof SHA224))\n return new SHA224();\n\n SHA256.call(this);\n this.h = [\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];\n}\nutils.inherits(SHA224, SHA256);\nmodule.exports = SHA224;\n\nSHA224.blockSize = 512;\nSHA224.outSize = 224;\nSHA224.hmacStrength = 192;\nSHA224.padLength = 64;\n\nSHA224.prototype._digest = function digest(enc) {\n // Just truncate output\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 7), 'big');\n else\n return utils.split32(this.h.slice(0, 7), 'big');\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVO0FBQzlCLGFBQWEsbUJBQU8sQ0FBQyxJQUFPOztBQUU1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzIyNC5qcz8wN2YyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBTSEEyNTYgPSByZXF1aXJlKCcuLzI1NicpO1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///799\n")},9344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\nvar assert = __webpack_require__(9746);\n\nvar sum32 = utils.sum32;\nvar sum32_4 = utils.sum32_4;\nvar sum32_5 = utils.sum32_5;\nvar ch32 = shaCommon.ch32;\nvar maj32 = shaCommon.maj32;\nvar s0_256 = shaCommon.s0_256;\nvar s1_256 = shaCommon.s1_256;\nvar g0_256 = shaCommon.g0_256;\nvar g1_256 = shaCommon.g1_256;\n\nvar BlockHash = common.BlockHash;\n\nvar sha256_K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\nfunction SHA256() {\n if (!(this instanceof SHA256))\n return new SHA256();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n ];\n this.k = sha256_K;\n this.W = new Array(64);\n}\nutils.inherits(SHA256, BlockHash);\nmodule.exports = SHA256;\n\nSHA256.blockSize = 512;\nSHA256.outSize = 256;\nSHA256.hmacStrength = 192;\nSHA256.padLength = 64;\n\nSHA256.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i++)\n W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n var f = this.h[5];\n var g = this.h[6];\n var h = this.h[7];\n\n assert(this.k.length === W.length);\n for (i = 0; i < W.length; i++) {\n var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);\n var T2 = sum32(s0_256(a), maj32(a, b, c));\n h = g;\n g = f;\n f = e;\n e = sum32(d, T1);\n d = c;\n c = b;\n b = a;\n a = sum32(T1, T2);\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n this.h[5] = sum32(this.h[5], f);\n this.h[6] = sum32(this.h[6], g);\n this.h[7] = sum32(this.h[7], h);\n};\n\nSHA256.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBLFNBQVMsY0FBYztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMjU2LmpzPzZlZWQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIHNoYUNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciBjaDMyID0gc2hhQ29tbW9uLmNoMzI7XG52YXIgbWFqMzIgPSBzaGFDb21tb24ubWFqMzI7XG52YXIgczBfMjU2ID0gc2hhQ29tbW9uLnMwXzI1NjtcbnZhciBzMV8yNTYgPSBzaGFDb21tb24uczFfMjU2O1xudmFyIGcwXzI1NiA9IHNoYUNvbW1vbi5nMF8yNTY7XG52YXIgZzFfMjU2ID0gc2hhQ29tbW9uLmcxXzI1NjtcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG4gIF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBUMSA9IHN1bTMyXzUoaCwgczFfMjU2KGUpLCBjaDMyKGUsIGYsIGcpLCB0aGlzLmtbaV0sIFdbaV0pO1xuICAgIHZhciBUMiA9IHN1bTMyKHMwXzI1NihhKSwgbWFqMzIoYSwgYiwgYykpO1xuICAgIGggPSBnO1xuICAgIGcgPSBmO1xuICAgIGYgPSBlO1xuICAgIGUgPSBzdW0zMihkLCBUMSk7XG4gICAgZCA9IGM7XG4gICAgYyA9IGI7XG4gICAgYiA9IGE7XG4gICAgYSA9IHN1bTMyKFQxLCBUMik7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xuICB0aGlzLmhbNV0gPSBzdW0zMih0aGlzLmhbNV0sIGYpO1xuICB0aGlzLmhbNl0gPSBzdW0zMih0aGlzLmhbNl0sIGcpO1xuICB0aGlzLmhbN10gPSBzdW0zMih0aGlzLmhbN10sIGgpO1xufTtcblxuU0hBMjU2LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9344\n")},772:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\n\nvar SHA512 = __webpack_require__(5900);\n\nfunction SHA384() {\n if (!(this instanceof SHA384))\n return new SHA384();\n\n SHA512.call(this);\n this.h = [\n 0xcbbb9d5d, 0xc1059ed8,\n 0x629a292a, 0x367cd507,\n 0x9159015a, 0x3070dd17,\n 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31,\n 0x8eb44a87, 0x68581511,\n 0xdb0c2e0d, 0x64f98fa7,\n 0x47b5481d, 0xbefa4fa4 ];\n}\nutils.inherits(SHA384, SHA512);\nmodule.exports = SHA384;\n\nSHA384.blockSize = 1024;\nSHA384.outSize = 384;\nSHA384.hmacStrength = 192;\nSHA384.padLength = 128;\n\nSHA384.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 12), 'big');\n else\n return utils.split32(this.h.slice(0, 12), 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcyLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVOztBQUU5QixhQUFhLG1CQUFPLENBQUMsSUFBTzs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMzg0LmpzPzhiOTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi81MTInKTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///772\n")},5900:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar assert = __webpack_require__(9746);\n\nvar rotr64_hi = utils.rotr64_hi;\nvar rotr64_lo = utils.rotr64_lo;\nvar shr64_hi = utils.shr64_hi;\nvar shr64_lo = utils.shr64_lo;\nvar sum64 = utils.sum64;\nvar sum64_hi = utils.sum64_hi;\nvar sum64_lo = utils.sum64_lo;\nvar sum64_4_hi = utils.sum64_4_hi;\nvar sum64_4_lo = utils.sum64_4_lo;\nvar sum64_5_hi = utils.sum64_5_hi;\nvar sum64_5_lo = utils.sum64_5_lo;\n\nvar BlockHash = common.BlockHash;\n\nvar sha512_K = [\n 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,\n 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,\n 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,\n 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,\n 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,\n 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,\n 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,\n 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,\n 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,\n 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,\n 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,\n 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,\n 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,\n 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,\n 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,\n 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,\n 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,\n 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,\n 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,\n 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,\n 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,\n 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,\n 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,\n 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,\n 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,\n 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,\n 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,\n 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,\n 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,\n 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,\n 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,\n 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,\n 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,\n 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,\n 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,\n 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,\n 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,\n 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,\n 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,\n 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817\n];\n\nfunction SHA512() {\n if (!(this instanceof SHA512))\n return new SHA512();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xf3bcc908,\n 0xbb67ae85, 0x84caa73b,\n 0x3c6ef372, 0xfe94f82b,\n 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1,\n 0x9b05688c, 0x2b3e6c1f,\n 0x1f83d9ab, 0xfb41bd6b,\n 0x5be0cd19, 0x137e2179 ];\n this.k = sha512_K;\n this.W = new Array(160);\n}\nutils.inherits(SHA512, BlockHash);\nmodule.exports = SHA512;\n\nSHA512.blockSize = 1024;\nSHA512.outSize = 512;\nSHA512.hmacStrength = 192;\nSHA512.padLength = 128;\n\nSHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {\n var W = this.W;\n\n // 32 x 32bit words\n for (var i = 0; i < 32; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i += 2) {\n var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2\n var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);\n var c1_hi = W[i - 14]; // i - 7\n var c1_lo = W[i - 13];\n var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15\n var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);\n var c3_hi = W[i - 32]; // i - 16\n var c3_lo = W[i - 31];\n\n W[i] = sum64_4_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n W[i + 1] = sum64_4_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n }\n};\n\nSHA512.prototype._update = function _update(msg, start) {\n this._prepareBlock(msg, start);\n\n var W = this.W;\n\n var ah = this.h[0];\n var al = this.h[1];\n var bh = this.h[2];\n var bl = this.h[3];\n var ch = this.h[4];\n var cl = this.h[5];\n var dh = this.h[6];\n var dl = this.h[7];\n var eh = this.h[8];\n var el = this.h[9];\n var fh = this.h[10];\n var fl = this.h[11];\n var gh = this.h[12];\n var gl = this.h[13];\n var hh = this.h[14];\n var hl = this.h[15];\n\n assert(this.k.length === W.length);\n for (var i = 0; i < W.length; i += 2) {\n var c0_hi = hh;\n var c0_lo = hl;\n var c1_hi = s1_512_hi(eh, el);\n var c1_lo = s1_512_lo(eh, el);\n var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);\n var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);\n var c3_hi = this.k[i];\n var c3_lo = this.k[i + 1];\n var c4_hi = W[i];\n var c4_lo = W[i + 1];\n\n var T1_hi = sum64_5_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n var T1_lo = sum64_5_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n\n c0_hi = s0_512_hi(ah, al);\n c0_lo = s0_512_lo(ah, al);\n c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);\n c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);\n\n var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);\n var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);\n\n hh = gh;\n hl = gl;\n\n gh = fh;\n gl = fl;\n\n fh = eh;\n fl = el;\n\n eh = sum64_hi(dh, dl, T1_hi, T1_lo);\n el = sum64_lo(dl, dl, T1_hi, T1_lo);\n\n dh = ch;\n dl = cl;\n\n ch = bh;\n cl = bl;\n\n bh = ah;\n bl = al;\n\n ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);\n al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);\n }\n\n sum64(this.h, 0, ah, al);\n sum64(this.h, 2, bh, bl);\n sum64(this.h, 4, ch, cl);\n sum64(this.h, 6, dh, dl);\n sum64(this.h, 8, eh, el);\n sum64(this.h, 10, fh, fl);\n sum64(this.h, 12, gh, gl);\n sum64(this.h, 14, hh, hl);\n};\n\nSHA512.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n\nfunction ch64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ ((~xh) & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction ch64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ ((~xl) & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 28);\n var c1_hi = rotr64_hi(xl, xh, 2); // 34\n var c2_hi = rotr64_hi(xl, xh, 7); // 39\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 28);\n var c1_lo = rotr64_lo(xl, xh, 2); // 34\n var c2_lo = rotr64_lo(xl, xh, 7); // 39\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 14);\n var c1_hi = rotr64_hi(xh, xl, 18);\n var c2_hi = rotr64_hi(xl, xh, 9); // 41\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 14);\n var c1_lo = rotr64_lo(xh, xl, 18);\n var c2_lo = rotr64_lo(xl, xh, 9); // 41\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 1);\n var c1_hi = rotr64_hi(xh, xl, 8);\n var c2_hi = shr64_hi(xh, xl, 7);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 1);\n var c1_lo = rotr64_lo(xh, xl, 8);\n var c2_lo = shr64_lo(xh, xl, 7);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 19);\n var c1_hi = rotr64_hi(xl, xh, 29); // 61\n var c2_hi = shr64_hi(xh, xl, 6);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 19);\n var c1_lo = rotr64_lo(xl, xh, 29); // 61\n var c2_lo = shr64_lo(xh, xl, 6);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTkwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixRQUFRO0FBQzFCO0FBQ0EsU0FBUyxjQUFjO0FBQ3ZCLGdEQUFnRDtBQUNoRDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzUxMi5qcz9iNTI1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbnZhciByb3RyNjRfaGkgPSB1dGlscy5yb3RyNjRfaGk7XG52YXIgcm90cjY0X2xvID0gdXRpbHMucm90cjY0X2xvO1xudmFyIHNocjY0X2hpID0gdXRpbHMuc2hyNjRfaGk7XG52YXIgc2hyNjRfbG8gPSB1dGlscy5zaHI2NF9sbztcbnZhciBzdW02NCA9IHV0aWxzLnN1bTY0O1xudmFyIHN1bTY0X2hpID0gdXRpbHMuc3VtNjRfaGk7XG52YXIgc3VtNjRfbG8gPSB1dGlscy5zdW02NF9sbztcbnZhciBzdW02NF80X2hpID0gdXRpbHMuc3VtNjRfNF9oaTtcbnZhciBzdW02NF80X2xvID0gdXRpbHMuc3VtNjRfNF9sbztcbnZhciBzdW02NF81X2hpID0gdXRpbHMuc3VtNjRfNV9oaTtcbnZhciBzdW02NF81X2xvID0gdXRpbHMuc3VtNjRfNV9sbztcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCxcbiAgICAweGJiNjdhZTg1LCAweDg0Y2FhNzNiLFxuICAgIDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIsXG4gICAgMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSxcbiAgICAweDUxMGU1MjdmLCAweGFkZTY4MmQxLFxuICAgIDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYsXG4gICAgMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YixcbiAgICAweDViZTBjZDE5LCAweDEzN2UyMTc5IF07XG4gIHRoaXMuayA9IHNoYTUxMl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoMTYwKTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTUxMiwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBNTEyO1xuXG5TSEE1MTIuYmxvY2tTaXplID0gMTAyNDtcblNIQTUxMi5vdXRTaXplID0gNTEyO1xuU0hBNTEyLmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTUxMi5wYWRMZW5ndGggPSAxMjg7XG5cblNIQTUxMi5wcm90b3R5cGUuX3ByZXBhcmVCbG9jayA9IGZ1bmN0aW9uIF9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICAvLyAzMiB4IDMyYml0IHdvcmRzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGcxXzUxMl9oaShXW2kgLSA0XSwgV1tpIC0gM10pOyAgLy8gaSAtIDJcbiAgICB2YXIgYzBfbG8gPSBnMV81MTJfbG8oV1tpIC0gNF0sIFdbaSAtIDNdKTtcbiAgICB2YXIgYzFfaGkgPSBXW2kgLSAxNF07ICAvLyBpIC0gN1xuICAgIHZhciBjMV9sbyA9IFdbaSAtIDEzXTtcbiAgICB2YXIgYzJfaGkgPSBnMF81MTJfaGkoV1tpIC0gMzBdLCBXW2kgLSAyOV0pOyAgLy8gaSAtIDE1XG4gICAgdmFyIGMyX2xvID0gZzBfNTEyX2xvKFdbaSAtIDMwXSwgV1tpIC0gMjldKTtcbiAgICB2YXIgYzNfaGkgPSBXW2kgLSAzMl07ICAvLyBpIC0gMTZcbiAgICB2YXIgYzNfbG8gPSBXW2kgLSAzMV07XG5cbiAgICBXW2ldID0gc3VtNjRfNF9oaShcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyk7XG4gICAgV1tpICsgMV0gPSBzdW02NF80X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcbiAgICB2YXIgVDFfbG8gPSBzdW02NF81X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcblxuICAgIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgYzBfbG8gPSBzMF81MTJfbG8oYWgsIGFsKTtcbiAgICBjMV9oaSA9IG1hajY0X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wpO1xuICAgIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gY2g2NF9oaSh4aCwgeGwsIHloLCB5bCwgemgpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICh4aCAmIHpoKSBeICh5aCAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKHhsICYgemwpIF4gKHlsICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDEpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDEpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5900\n")},7038:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar rotr32 = utils.rotr32;\n\nfunction ft_1(s, x, y, z) {\n if (s === 0)\n return ch32(x, y, z);\n if (s === 1 || s === 3)\n return p32(x, y, z);\n if (s === 2)\n return maj32(x, y, z);\n}\nexports.ft_1 = ft_1;\n\nfunction ch32(x, y, z) {\n return (x & y) ^ ((~x) & z);\n}\nexports.ch32 = ch32;\n\nfunction maj32(x, y, z) {\n return (x & y) ^ (x & z) ^ (y & z);\n}\nexports.maj32 = maj32;\n\nfunction p32(x, y, z) {\n return x ^ y ^ z;\n}\nexports.p32 = p32;\n\nfunction s0_256(x) {\n return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);\n}\nexports.s0_256 = s0_256;\n\nfunction s1_256(x) {\n return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);\n}\nexports.s1_256 = s1_256;\n\nfunction g0_256(x) {\n return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);\n}\nexports.g0_256 = g0_256;\n\nfunction g1_256(x) {\n return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);\n}\nexports.g1_256 = g1_256;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAzOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0EsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxjQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS9jb21tb24uanM/YWE1NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgcm90cjMyID0gdXRpbHMucm90cjMyO1xuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuZXhwb3J0cy5mdF8xID0gZnRfMTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cbmV4cG9ydHMuY2gzMiA9IGNoMzI7XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cbmV4cG9ydHMubWFqMzIgPSBtYWozMjtcblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cbmV4cG9ydHMucDMyID0gcDMyO1xuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5leHBvcnRzLnMwXzI1NiA9IHMwXzI1NjtcblxuZnVuY3Rpb24gczFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA2KSBeIHJvdHIzMih4LCAxMSkgXiByb3RyMzIoeCwgMjUpO1xufVxuZXhwb3J0cy5zMV8yNTYgPSBzMV8yNTY7XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuZXhwb3J0cy5nMF8yNTYgPSBnMF8yNTY7XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5leHBvcnRzLmcxXzI1NiA9IGcxXzI1NjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7038\n")},6436:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar assert = __webpack_require__(9746);\nvar inherits = __webpack_require__(5717);\n\nexports.inherits = inherits;\n\nfunction isSurrogatePair(msg, i) {\n if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {\n return false;\n }\n if (i < 0 || i + 1 >= msg.length) {\n return false;\n }\n return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;\n}\n\nfunction toArray(msg, enc) {\n if (Array.isArray(msg))\n return msg.slice();\n if (!msg)\n return [];\n var res = [];\n if (typeof msg === 'string') {\n if (!enc) {\n // Inspired by stringToUtf8ByteArray() in closure-library by Google\n // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143\n // Apache License 2.0\n // https://github.com/google/closure-library/blob/master/LICENSE\n var p = 0;\n for (var i = 0; i < msg.length; i++) {\n var c = msg.charCodeAt(i);\n if (c < 128) {\n res[p++] = c;\n } else if (c < 2048) {\n res[p++] = (c >> 6) | 192;\n res[p++] = (c & 63) | 128;\n } else if (isSurrogatePair(msg, i)) {\n c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);\n res[p++] = (c >> 18) | 240;\n res[p++] = ((c >> 12) & 63) | 128;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n } else {\n res[p++] = (c >> 12) | 224;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n }\n }\n } else if (enc === 'hex') {\n msg = msg.replace(/[^a-z0-9]+/ig, '');\n if (msg.length % 2 !== 0)\n msg = '0' + msg;\n for (i = 0; i < msg.length; i += 2)\n res.push(parseInt(msg[i] + msg[i + 1], 16));\n }\n } else {\n for (i = 0; i < msg.length; i++)\n res[i] = msg[i] | 0;\n }\n return res;\n}\nexports.toArray = toArray;\n\nfunction toHex(msg) {\n var res = '';\n for (var i = 0; i < msg.length; i++)\n res += zero2(msg[i].toString(16));\n return res;\n}\nexports.toHex = toHex;\n\nfunction htonl(w) {\n var res = (w >>> 24) |\n ((w >>> 8) & 0xff00) |\n ((w << 8) & 0xff0000) |\n ((w & 0xff) << 24);\n return res >>> 0;\n}\nexports.htonl = htonl;\n\nfunction toHex32(msg, endian) {\n var res = '';\n for (var i = 0; i < msg.length; i++) {\n var w = msg[i];\n if (endian === 'little')\n w = htonl(w);\n res += zero8(w.toString(16));\n }\n return res;\n}\nexports.toHex32 = toHex32;\n\nfunction zero2(word) {\n if (word.length === 1)\n return '0' + word;\n else\n return word;\n}\nexports.zero2 = zero2;\n\nfunction zero8(word) {\n if (word.length === 7)\n return '0' + word;\n else if (word.length === 6)\n return '00' + word;\n else if (word.length === 5)\n return '000' + word;\n else if (word.length === 4)\n return '0000' + word;\n else if (word.length === 3)\n return '00000' + word;\n else if (word.length === 2)\n return '000000' + word;\n else if (word.length === 1)\n return '0000000' + word;\n else\n return word;\n}\nexports.zero8 = zero8;\n\nfunction join32(msg, start, end, endian) {\n var len = end - start;\n assert(len % 4 === 0);\n var res = new Array(len / 4);\n for (var i = 0, k = start; i < res.length; i++, k += 4) {\n var w;\n if (endian === 'big')\n w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];\n else\n w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];\n res[i] = w >>> 0;\n }\n return res;\n}\nexports.join32 = join32;\n\nfunction split32(msg, endian) {\n var res = new Array(msg.length * 4);\n for (var i = 0, k = 0; i < msg.length; i++, k += 4) {\n var m = msg[i];\n if (endian === 'big') {\n res[k] = m >>> 24;\n res[k + 1] = (m >>> 16) & 0xff;\n res[k + 2] = (m >>> 8) & 0xff;\n res[k + 3] = m & 0xff;\n } else {\n res[k + 3] = m >>> 24;\n res[k + 2] = (m >>> 16) & 0xff;\n res[k + 1] = (m >>> 8) & 0xff;\n res[k] = m & 0xff;\n }\n }\n return res;\n}\nexports.split32 = split32;\n\nfunction rotr32(w, b) {\n return (w >>> b) | (w << (32 - b));\n}\nexports.rotr32 = rotr32;\n\nfunction rotl32(w, b) {\n return (w << b) | (w >>> (32 - b));\n}\nexports.rotl32 = rotl32;\n\nfunction sum32(a, b) {\n return (a + b) >>> 0;\n}\nexports.sum32 = sum32;\n\nfunction sum32_3(a, b, c) {\n return (a + b + c) >>> 0;\n}\nexports.sum32_3 = sum32_3;\n\nfunction sum32_4(a, b, c, d) {\n return (a + b + c + d) >>> 0;\n}\nexports.sum32_4 = sum32_4;\n\nfunction sum32_5(a, b, c, d, e) {\n return (a + b + c + d + e) >>> 0;\n}\nexports.sum32_5 = sum32_5;\n\nfunction sum64(buf, pos, ah, al) {\n var bh = buf[pos];\n var bl = buf[pos + 1];\n\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n buf[pos] = hi >>> 0;\n buf[pos + 1] = lo;\n}\nexports.sum64 = sum64;\n\nfunction sum64_hi(ah, al, bh, bl) {\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n return hi >>> 0;\n}\nexports.sum64_hi = sum64_hi;\n\nfunction sum64_lo(ah, al, bh, bl) {\n var lo = al + bl;\n return lo >>> 0;\n}\nexports.sum64_lo = sum64_lo;\n\nfunction sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n\n var hi = ah + bh + ch + dh + carry;\n return hi >>> 0;\n}\nexports.sum64_4_hi = sum64_4_hi;\n\nfunction sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {\n var lo = al + bl + cl + dl;\n return lo >>> 0;\n}\nexports.sum64_4_lo = sum64_4_lo;\n\nfunction sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n lo = (lo + el) >>> 0;\n carry += lo < el ? 1 : 0;\n\n var hi = ah + bh + ch + dh + eh + carry;\n return hi >>> 0;\n}\nexports.sum64_5_hi = sum64_5_hi;\n\nfunction sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var lo = al + bl + cl + dl + el;\n\n return lo >>> 0;\n}\nexports.sum64_5_lo = sum64_5_lo;\n\nfunction rotr64_hi(ah, al, num) {\n var r = (al << (32 - num)) | (ah >>> num);\n return r >>> 0;\n}\nexports.rotr64_hi = rotr64_hi;\n\nfunction rotr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.rotr64_lo = rotr64_lo;\n\nfunction shr64_hi(ah, al, num) {\n return ah >>> num;\n}\nexports.shr64_hi = shr64_hi;\n\nfunction shr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.shr64_lo = shr64_lo;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBcUI7QUFDMUMsZUFBZSxtQkFBTyxDQUFDLElBQVU7O0FBRWpDLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGdCQUFnQjtBQUN0QztBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0EsSUFBSTtBQUNKLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsZ0JBQWdCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcz9jM2MwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuaW5oZXJpdHMgPSBpbmhlcml0cztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkge1xuICBpZiAoKG1zZy5jaGFyQ29kZUF0KGkpICYgMHhGQzAwKSAhPT0gMHhEODAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpIDwgMCB8fCBpICsgMSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAobXNnLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwO1xufVxuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIC8vIEluc3BpcmVkIGJ5IHN0cmluZ1RvVXRmOEJ5dGVBcnJheSgpIGluIGNsb3N1cmUtbGlicmFyeSBieSBHb29nbGVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvODU5OGQ4NzI0MmFmNTlhYWMyMzMyNzA3NDJjODk4NGUyYjJiZGJlMC9jbG9zdXJlL2dvb2cvY3J5cHQvY3J5cHQuanMjTDExNy1MMTQzXG4gICAgICAvLyBBcGFjaGUgTGljZW5zZSAyLjBcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAgICAgIHZhciBwID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSBjO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPCAyMDQ4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyA+PiA2KSB8IDE5MjtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3Vycm9nYXRlUGFpcihtc2csIGkpKSB7XG4gICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgJiAweDAzRkYpIDw8IDEwKSArIChtc2cuY2hhckNvZGVBdCgrK2kpICYgMHgwM0ZGKTtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDE4KSB8IDI0MDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiAxMikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoKGMgPj4gNikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyAmIDYzKSB8IDEyODtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDEyKSB8IDIyNDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleCA9IHRvSGV4O1xuXG5mdW5jdGlvbiBodG9ubCh3KSB7XG4gIHZhciByZXMgPSAodyA+Pj4gMjQpIHxcbiAgICAgICAgICAgICgodyA+Pj4gOCkgJiAweGZmMDApIHxcbiAgICAgICAgICAgICgodyA8PCA4KSAmIDB4ZmYwMDAwKSB8XG4gICAgICAgICAgICAoKHcgJiAweGZmKSA8PCAyNCk7XG4gIHJldHVybiByZXMgPj4+IDA7XG59XG5leHBvcnRzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHplcm84KHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSA3KVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNilcbiAgICByZXR1cm4gJzAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA1KVxuICAgIHJldHVybiAnMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA0KVxuICAgIHJldHVybiAnMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMylcbiAgICByZXR1cm4gJzAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAyKVxuICAgIHJldHVybiAnMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMDAwMDAwMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5zcGxpdDMyID0gc3BsaXQzMjtcblxuZnVuY3Rpb24gcm90cjMyKHcsIGIpIHtcbiAgcmV0dXJuICh3ID4+PiBiKSB8ICh3IDw8ICgzMiAtIGIpKTtcbn1cbmV4cG9ydHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyID0gc3VtMzI7XG5cbmZ1bmN0aW9uIHN1bTMyXzMoYSwgYiwgYykge1xuICByZXR1cm4gKGEgKyBiICsgYykgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNSA9IHN1bTMyXzU7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0X2hpID0gc3VtNjRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0X2xvKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IGFsICsgYmw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNF9sbyA9IHN1bTY0XzRfbG87XG5cbmZ1bmN0aW9uIHN1bTY0XzVfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZWwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGVsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBlaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMucm90cjY0X2hpID0gcm90cjY0X2hpO1xuXG5mdW5jdGlvbiByb3RyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufVxuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnNocjY0X2xvID0gc2hyNjRfbG87XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6436\n")},5717:function(module){eval("if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTcxNy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzPzNmYjUiXSwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5717\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},9746:function(module){eval("module.exports = assert;\n\nfunction assert(val, msg) {\n if (!val)\n throw new Error(msg || 'Assertion failed');\n}\n\nassert.equal = function assertEqual(l, r, msg) {\n if (l != r)\n throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvbWluaW1hbGlzdGljLWFzc2VydC9pbmRleC5qcz9kYTNlIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXNzZXJ0O1xuXG5mdW5jdGlvbiBhc3NlcnQodmFsLCBtc2cpIHtcbiAgaWYgKCF2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBhc3NlcnRFcXVhbChsLCByLCBtc2cpIHtcbiAgaWYgKGwgIT0gcilcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICgnQXNzZXJ0aW9uIGZhaWxlZDogJyArIGwgKyAnICE9ICcgKyByKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9746\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz80ZWE4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz83NGM5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/YTYyMCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzPzAxZjQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NjY2MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/NmY5MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz81YTAxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/NDI2NCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz81YWVhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzPzYzOTQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz84ZDcxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/ZWFhNyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzhlMDkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz8xMzA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82NzlhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz84NzVlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZTg1OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzP2IzN2MiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzP2EwODciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz9iODZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz9iMjE4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YzQyNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzPzFkZTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz85OTYyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz8wOGE4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZjM5ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz9iYWU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzP2UzYTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz84OTU0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz80YmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz82OTRmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz9lZDNhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzU5OGMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9hODA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz9kNGYxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/Y2E0MCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz82ZDczIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzYyZjQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/NzhjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/NjBhNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9lNWExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/OGYyNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/NjEwMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/YzRkZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzP2VkYzMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzP2U3ODEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz9hODFhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzP2NmYjYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/Yjk1MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz83NzM0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzP2NlNzIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZmQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/YTNiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/NzQ3OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz84YTM0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzP2Q4MmUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/OGRmNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9lMGI2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(Q){var t=__webpack_module_cache__[Q];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[Q]={exports:{}};return __webpack_modules__[Q](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=function(Q){var t=Q&&Q.__esModule?function(){return Q.default}:function(){return Q};return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=function(Q,t){for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(Q,n)&&Object.defineProperty(Q,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=function(Q,t){return Object.prototype.hasOwnProperty.call(Q,t)};var __webpack_exports__=__webpack_require__(6396)})(); \ No newline at end of file +(function(){var __webpack_modules__={3089:function(__unused_webpack_module,exports){"use strict";eval('var __webpack_unused_export__;\n\n/**\n * Implementation of Myers\' online approximate string matching algorithm [1],\n * with additional optimizations suggested by [2].\n *\n * This has O((k/w) * n) complexity where `n` is the length of the text, `k` is\n * the maximum number of errors allowed (always <= the pattern length) and `w`\n * is the word size. Because JS only supports bitwise operations on 32 bit\n * integers, `w` is 32.\n *\n * As far as I am aware, there aren\'t any online algorithms which are\n * significantly better for a wide range of input parameters. The problem can be\n * solved faster using "filter then verify" approaches which first filter out\n * regions of the text that cannot match using a "cheap" check and then verify\n * the remaining potential matches. The verify step requires an algorithm such\n * as this one however.\n *\n * The algorithm\'s approach is essentially to optimize the classic dynamic\n * programming solution to the problem by computing columns of the matrix in\n * word-sized chunks (ie. dealing with 32 chars of the pattern at a time) and\n * avoiding calculating regions of the matrix where the minimum error count is\n * guaranteed to exceed the input threshold.\n *\n * The paper consists of two parts, the first describes the core algorithm for\n * matching patterns <= the size of a word (implemented by `advanceBlock` here).\n * The second uses the core algorithm as part of a larger block-based algorithm\n * to handle longer patterns.\n *\n * [1] G. Myers, “A Fast Bit-Vector Algorithm for Approximate String Matching\n * Based on Dynamic Programming,” vol. 46, no. 3, pp. 395–415, 1999.\n *\n * [2] Šošić, M. (2014). An simd dynamic programming c/c++ library (Doctoral\n * dissertation, Fakultet Elektrotehnike i računarstva, Sveučilište u Zagrebu).\n */\n__webpack_unused_export__ = ({ value: true });\nfunction reverse(s) {\n return s\n .split("")\n .reverse()\n .join("");\n}\n/**\n * Given the ends of approximate matches for `pattern` in `text`, find\n * the start of the matches.\n *\n * @param findEndFn - Function for finding the end of matches in\n * text.\n * @return Matches with the `start` property set.\n */\nfunction findMatchStarts(text, pattern, matches) {\n var patRev = reverse(pattern);\n return matches.map(function (m) {\n // Find start of each match by reversing the pattern and matching segment\n // of text and searching for an approx match with the same number of\n // errors.\n var minStart = Math.max(0, m.end - pattern.length - m.errors);\n var textRev = reverse(text.slice(minStart, m.end));\n // If there are multiple possible start points, choose the one that\n // maximizes the length of the match.\n var start = findMatchEnds(textRev, patRev, m.errors).reduce(function (min, rm) {\n if (m.end - rm.end < min) {\n return m.end - rm.end;\n }\n return min;\n }, m.end);\n return {\n start: start,\n end: m.end,\n errors: m.errors\n };\n });\n}\n/**\n * Return 1 if a number is non-zero or zero otherwise, without using\n * conditional operators.\n *\n * This should get inlined into `advanceBlock` below by the JIT.\n *\n * Adapted from https://stackoverflow.com/a/3912218/434243\n */\nfunction oneIfNotZero(n) {\n return ((n | -n) >> 31) & 1;\n}\n/**\n * Block calculation step of the algorithm.\n *\n * From Fig 8. on p. 408 of [1], additionally optimized to replace conditional\n * checks with bitwise operations as per Section 4.2.3 of [2].\n *\n * @param ctx - The pattern context object\n * @param peq - The `peq` array for the current character (`ctx.peq.get(ch)`)\n * @param b - The block level\n * @param hIn - Horizontal input delta ∈ {1,0,-1}\n * @return Horizontal output delta ∈ {1,0,-1}\n */\nfunction advanceBlock(ctx, peq, b, hIn) {\n var pV = ctx.P[b];\n var mV = ctx.M[b];\n var hInIsNegative = hIn >>> 31; // 1 if hIn < 0 or 0 otherwise.\n var eq = peq[b] | hInIsNegative;\n // Step 1: Compute horizontal deltas.\n var xV = eq | mV;\n var xH = (((eq & pV) + pV) ^ pV) | eq;\n var pH = mV | ~(xH | pV);\n var mH = pV & xH;\n // Step 2: Update score (value of last row of this block).\n var hOut = oneIfNotZero(pH & ctx.lastRowMask[b]) -\n oneIfNotZero(mH & ctx.lastRowMask[b]);\n // Step 3: Update vertical deltas for use when processing next char.\n pH <<= 1;\n mH <<= 1;\n mH |= hInIsNegative;\n pH |= oneIfNotZero(hIn) - hInIsNegative; // set pH[0] if hIn > 0\n pV = mH | ~(xV | pH);\n mV = pH & xV;\n ctx.P[b] = pV;\n ctx.M[b] = mV;\n return hOut;\n}\n/**\n * Find the ends and error counts for matches of `pattern` in `text`.\n *\n * Only the matches with the lowest error count are reported. Other matches\n * with error counts <= maxErrors are discarded.\n *\n * This is the block-based search algorithm from Fig. 9 on p.410 of [1].\n */\nfunction findMatchEnds(text, pattern, maxErrors) {\n if (pattern.length === 0) {\n return [];\n }\n // Clamp error count so we can rely on the `maxErrors` and `pattern.length`\n // rows being in the same block below.\n maxErrors = Math.min(maxErrors, pattern.length);\n var matches = [];\n // Word size.\n var w = 32;\n // Index of maximum block level.\n var bMax = Math.ceil(pattern.length / w) - 1;\n // Context used across block calculations.\n var ctx = {\n P: new Uint32Array(bMax + 1),\n M: new Uint32Array(bMax + 1),\n lastRowMask: new Uint32Array(bMax + 1)\n };\n ctx.lastRowMask.fill(1 << 31);\n ctx.lastRowMask[bMax] = 1 << (pattern.length - 1) % w;\n // Dummy "peq" array for chars in the text which do not occur in the pattern.\n var emptyPeq = new Uint32Array(bMax + 1);\n // Map of UTF-16 character code to bit vector indicating positions in the\n // pattern that equal that character.\n var peq = new Map();\n // Version of `peq` that only stores mappings for small characters. This\n // allows faster lookups when iterating through the text because a simple\n // array lookup can be done instead of a hash table lookup.\n var asciiPeq = [];\n for (var i = 0; i < 256; i++) {\n asciiPeq.push(emptyPeq);\n }\n // Calculate `ctx.peq` - a map of character values to bitmasks indicating\n // positions of that character within the pattern, where each bit represents\n // a position in the pattern.\n for (var c = 0; c < pattern.length; c += 1) {\n var val = pattern.charCodeAt(c);\n if (peq.has(val)) {\n // Duplicate char in pattern.\n continue;\n }\n var charPeq = new Uint32Array(bMax + 1);\n peq.set(val, charPeq);\n if (val < asciiPeq.length) {\n asciiPeq[val] = charPeq;\n }\n for (var b = 0; b <= bMax; b += 1) {\n charPeq[b] = 0;\n // Set all the bits where the pattern matches the current char (ch).\n // For indexes beyond the end of the pattern, always set the bit as if the\n // pattern contained a wildcard char in that position.\n for (var r = 0; r < w; r += 1) {\n var idx = b * w + r;\n if (idx >= pattern.length) {\n continue;\n }\n var match = pattern.charCodeAt(idx) === val;\n if (match) {\n charPeq[b] |= 1 << r;\n }\n }\n }\n }\n // Index of last-active block level in the column.\n var y = Math.max(0, Math.ceil(maxErrors / w) - 1);\n // Initialize maximum error count at bottom of each block.\n var score = new Uint32Array(bMax + 1);\n for (var b = 0; b <= y; b += 1) {\n score[b] = (b + 1) * w;\n }\n score[bMax] = pattern.length;\n // Initialize vertical deltas for each block.\n for (var b = 0; b <= y; b += 1) {\n ctx.P[b] = ~0;\n ctx.M[b] = 0;\n }\n // Process each char of the text, computing the error count for `w` chars of\n // the pattern at a time.\n for (var j = 0; j < text.length; j += 1) {\n // Lookup the bitmask representing the positions of the current char from\n // the text within the pattern.\n var charCode = text.charCodeAt(j);\n var charPeq = void 0;\n if (charCode < asciiPeq.length) {\n // Fast array lookup.\n charPeq = asciiPeq[charCode];\n }\n else {\n // Slower hash table lookup.\n charPeq = peq.get(charCode);\n if (typeof charPeq === "undefined") {\n charPeq = emptyPeq;\n }\n }\n // Calculate error count for blocks that we definitely have to process for\n // this column.\n var carry = 0;\n for (var b = 0; b <= y; b += 1) {\n carry = advanceBlock(ctx, charPeq, b, carry);\n score[b] += carry;\n }\n // Check if we also need to compute an additional block, or if we can reduce\n // the number of blocks processed for the next column.\n if (score[y] - carry <= maxErrors &&\n y < bMax &&\n (charPeq[y + 1] & 1 || carry < 0)) {\n // Error count for bottom block is under threshold, increase the number of\n // blocks processed for this column & next by 1.\n y += 1;\n ctx.P[y] = ~0;\n ctx.M[y] = 0;\n var maxBlockScore = y === bMax ? pattern.length % w : w;\n score[y] =\n score[y - 1] +\n maxBlockScore -\n carry +\n advanceBlock(ctx, charPeq, y, carry);\n }\n else {\n // Error count for bottom block exceeds threshold, reduce the number of\n // blocks processed for the next column.\n while (y > 0 && score[y] >= maxErrors + w) {\n y -= 1;\n }\n }\n // If error count is under threshold, report a match.\n if (y === bMax && score[y] <= maxErrors) {\n if (score[y] < maxErrors) {\n // Discard any earlier, worse matches.\n matches.splice(0, matches.length);\n }\n matches.push({\n start: -1,\n end: j + 1,\n errors: score[y]\n });\n // Because `search` only reports the matches with the lowest error count,\n // we can "ratchet down" the max error threshold whenever a match is\n // encountered and thereby save a small amount of work for the remainder\n // of the text.\n maxErrors = score[y];\n }\n }\n return matches;\n}\n/**\n * Search for matches for `pattern` in `text` allowing up to `maxErrors` errors.\n *\n * Returns the start, and end positions and error counts for each lowest-cost\n * match. Only the "best" matches are returned.\n */\nfunction search(text, pattern, maxErrors) {\n var matches = findMatchEnds(text, pattern, maxErrors);\n return findMatchStarts(text, pattern, matches);\n}\nexports.Z = search;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA4OS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkMsRUFBRSxhQUFhLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLE9BQU87QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2FwcHJveC1zdHJpbmctbWF0Y2gvZGlzdC9pbmRleC5qcz83MjMwIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBNeWVycycgb25saW5lIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBhbGdvcml0aG0gWzFdLFxuICogd2l0aCBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgc3VnZ2VzdGVkIGJ5IFsyXS5cbiAqXG4gKiBUaGlzIGhhcyBPKChrL3cpICogbikgY29tcGxleGl0eSB3aGVyZSBgbmAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCwgYGtgIGlzXG4gKiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIGFsbG93ZWQgKGFsd2F5cyA8PSB0aGUgcGF0dGVybiBsZW5ndGgpIGFuZCBgd2BcbiAqIGlzIHRoZSB3b3JkIHNpemUuIEJlY2F1c2UgSlMgb25seSBzdXBwb3J0cyBiaXR3aXNlIG9wZXJhdGlvbnMgb24gMzIgYml0XG4gKiBpbnRlZ2VycywgYHdgIGlzIDMyLlxuICpcbiAqIEFzIGZhciBhcyBJIGFtIGF3YXJlLCB0aGVyZSBhcmVuJ3QgYW55IG9ubGluZSBhbGdvcml0aG1zIHdoaWNoIGFyZVxuICogc2lnbmlmaWNhbnRseSBiZXR0ZXIgZm9yIGEgd2lkZSByYW5nZSBvZiBpbnB1dCBwYXJhbWV0ZXJzLiBUaGUgcHJvYmxlbSBjYW4gYmVcbiAqIHNvbHZlZCBmYXN0ZXIgdXNpbmcgXCJmaWx0ZXIgdGhlbiB2ZXJpZnlcIiBhcHByb2FjaGVzIHdoaWNoIGZpcnN0IGZpbHRlciBvdXRcbiAqIHJlZ2lvbnMgb2YgdGhlIHRleHQgdGhhdCBjYW5ub3QgbWF0Y2ggdXNpbmcgYSBcImNoZWFwXCIgY2hlY2sgYW5kIHRoZW4gdmVyaWZ5XG4gKiB0aGUgcmVtYWluaW5nIHBvdGVudGlhbCBtYXRjaGVzLiBUaGUgdmVyaWZ5IHN0ZXAgcmVxdWlyZXMgYW4gYWxnb3JpdGhtIHN1Y2hcbiAqIGFzIHRoaXMgb25lIGhvd2V2ZXIuXG4gKlxuICogVGhlIGFsZ29yaXRobSdzIGFwcHJvYWNoIGlzIGVzc2VudGlhbGx5IHRvIG9wdGltaXplIHRoZSBjbGFzc2ljIGR5bmFtaWNcbiAqIHByb2dyYW1taW5nIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGJ5IGNvbXB1dGluZyBjb2x1bW5zIG9mIHRoZSBtYXRyaXggaW5cbiAqIHdvcmQtc2l6ZWQgY2h1bmtzIChpZS4gZGVhbGluZyB3aXRoIDMyIGNoYXJzIG9mIHRoZSBwYXR0ZXJuIGF0IGEgdGltZSkgYW5kXG4gKiBhdm9pZGluZyBjYWxjdWxhdGluZyByZWdpb25zIG9mIHRoZSBtYXRyaXggd2hlcmUgdGhlIG1pbmltdW0gZXJyb3IgY291bnQgaXNcbiAqIGd1YXJhbnRlZWQgdG8gZXhjZWVkIHRoZSBpbnB1dCB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHBhcGVyIGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgdGhlIGZpcnN0IGRlc2NyaWJlcyB0aGUgY29yZSBhbGdvcml0aG0gZm9yXG4gKiBtYXRjaGluZyBwYXR0ZXJucyA8PSB0aGUgc2l6ZSBvZiBhIHdvcmQgKGltcGxlbWVudGVkIGJ5IGBhZHZhbmNlQmxvY2tgIGhlcmUpLlxuICogVGhlIHNlY29uZCB1c2VzIHRoZSBjb3JlIGFsZ29yaXRobSBhcyBwYXJ0IG9mIGEgbGFyZ2VyIGJsb2NrLWJhc2VkIGFsZ29yaXRobVxuICogdG8gaGFuZGxlIGxvbmdlciBwYXR0ZXJucy5cbiAqXG4gKiBbMV0gRy4gTXllcnMsIOKAnEEgRmFzdCBCaXQtVmVjdG9yIEFsZ29yaXRobSBmb3IgQXBwcm94aW1hdGUgU3RyaW5nIE1hdGNoaW5nXG4gKiBCYXNlZCBvbiBEeW5hbWljIFByb2dyYW1taW5nLOKAnSB2b2wuIDQ2LCBuby4gMywgcHAuIDM5NeKAkzQxNSwgMTk5OS5cbiAqXG4gKiBbMl0gxaBvxaFpxIcsIE0uICgyMDE0KS4gQW4gc2ltZCBkeW5hbWljIHByb2dyYW1taW5nIGMvYysrIGxpYnJhcnkgKERvY3RvcmFsXG4gKiBkaXNzZXJ0YXRpb24sIEZha3VsdGV0IEVsZWt0cm90ZWhuaWtlIGkgcmHEjXVuYXJzdHZhLCBTdmV1xI1pbGnFoXRlIHUgWmFncmVidSkuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJldmVyc2Uocykge1xuICAgIHJldHVybiBzXG4gICAgICAgIC5zcGxpdChcIlwiKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5qb2luKFwiXCIpO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgZW5kcyBvZiBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHRleHRgLCBmaW5kXG4gKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMuXG4gKlxuICogQHBhcmFtIGZpbmRFbmRGbiAtIEZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBlbmQgb2YgbWF0Y2hlcyBpblxuICogdGV4dC5cbiAqIEByZXR1cm4gTWF0Y2hlcyB3aXRoIHRoZSBgc3RhcnRgIHByb3BlcnR5IHNldC5cbiAqL1xuZnVuY3Rpb24gZmluZE1hdGNoU3RhcnRzKHRleHQsIHBhdHRlcm4sIG1hdGNoZXMpIHtcbiAgICB2YXIgcGF0UmV2ID0gcmV2ZXJzZShwYXR0ZXJuKTtcbiAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgLy8gRmluZCBzdGFydCBvZiBlYWNoIG1hdGNoIGJ5IHJldmVyc2luZyB0aGUgcGF0dGVybiBhbmQgbWF0Y2hpbmcgc2VnbWVudFxuICAgICAgICAvLyBvZiB0ZXh0IGFuZCBzZWFyY2hpbmcgZm9yIGFuIGFwcHJveCBtYXRjaCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZlxuICAgICAgICAvLyBlcnJvcnMuXG4gICAgICAgIHZhciBtaW5TdGFydCA9IE1hdGgubWF4KDAsIG0uZW5kIC0gcGF0dGVybi5sZW5ndGggLSBtLmVycm9ycyk7XG4gICAgICAgIHZhciB0ZXh0UmV2ID0gcmV2ZXJzZSh0ZXh0LnNsaWNlKG1pblN0YXJ0LCBtLmVuZCkpO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgc3RhcnQgcG9pbnRzLCBjaG9vc2UgdGhlIG9uZSB0aGF0XG4gICAgICAgIC8vIG1heGltaXplcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaC5cbiAgICAgICAgdmFyIHN0YXJ0ID0gZmluZE1hdGNoRW5kcyh0ZXh0UmV2LCBwYXRSZXYsIG0uZXJyb3JzKS5yZWR1Y2UoZnVuY3Rpb24gKG1pbiwgcm0pIHtcbiAgICAgICAgICAgIGlmIChtLmVuZCAtIHJtLmVuZCA8IG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmVuZCAtIHJtLmVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtaW47XG4gICAgICAgIH0sIG0uZW5kKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogbS5lbmQsXG4gICAgICAgICAgICBlcnJvcnM6IG0uZXJyb3JzXG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybiAxIGlmIGEgbnVtYmVyIGlzIG5vbi16ZXJvIG9yIHplcm8gb3RoZXJ3aXNlLCB3aXRob3V0IHVzaW5nXG4gKiBjb25kaXRpb25hbCBvcGVyYXRvcnMuXG4gKlxuICogVGhpcyBzaG91bGQgZ2V0IGlubGluZWQgaW50byBgYWR2YW5jZUJsb2NrYCBiZWxvdyBieSB0aGUgSklULlxuICpcbiAqIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzkxMjIxOC80MzQyNDNcbiAqL1xuZnVuY3Rpb24gb25lSWZOb3RaZXJvKG4pIHtcbiAgICByZXR1cm4gKChuIHwgLW4pID4+IDMxKSAmIDE7XG59XG4vKipcbiAqIEJsb2NrIGNhbGN1bGF0aW9uIHN0ZXAgb2YgdGhlIGFsZ29yaXRobS5cbiAqXG4gKiBGcm9tIEZpZyA4LiBvbiBwLiA0MDggb2YgWzFdLCBhZGRpdGlvbmFsbHkgb3B0aW1pemVkIHRvIHJlcGxhY2UgY29uZGl0aW9uYWxcbiAqIGNoZWNrcyB3aXRoIGJpdHdpc2Ugb3BlcmF0aW9ucyBhcyBwZXIgU2VjdGlvbiA0LjIuMyBvZiBbMl0uXG4gKlxuICogQHBhcmFtIGN0eCAtIFRoZSBwYXR0ZXJuIGNvbnRleHQgb2JqZWN0XG4gKiBAcGFyYW0gcGVxIC0gVGhlIGBwZXFgIGFycmF5IGZvciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgKGBjdHgucGVxLmdldChjaClgKVxuICogQHBhcmFtIGIgLSBUaGUgYmxvY2sgbGV2ZWxcbiAqIEBwYXJhbSBoSW4gLSBIb3Jpem9udGFsIGlucHV0IGRlbHRhIOKIiCB7MSwwLC0xfVxuICogQHJldHVybiBIb3Jpem9udGFsIG91dHB1dCBkZWx0YSDiiIggezEsMCwtMX1cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUJsb2NrKGN0eCwgcGVxLCBiLCBoSW4pIHtcbiAgICB2YXIgcFYgPSBjdHguUFtiXTtcbiAgICB2YXIgbVYgPSBjdHguTVtiXTtcbiAgICB2YXIgaEluSXNOZWdhdGl2ZSA9IGhJbiA+Pj4gMzE7IC8vIDEgaWYgaEluIDwgMCBvciAwIG90aGVyd2lzZS5cbiAgICB2YXIgZXEgPSBwZXFbYl0gfCBoSW5Jc05lZ2F0aXZlO1xuICAgIC8vIFN0ZXAgMTogQ29tcHV0ZSBob3Jpem9udGFsIGRlbHRhcy5cbiAgICB2YXIgeFYgPSBlcSB8IG1WO1xuICAgIHZhciB4SCA9ICgoKGVxICYgcFYpICsgcFYpIF4gcFYpIHwgZXE7XG4gICAgdmFyIHBIID0gbVYgfCB+KHhIIHwgcFYpO1xuICAgIHZhciBtSCA9IHBWICYgeEg7XG4gICAgLy8gU3RlcCAyOiBVcGRhdGUgc2NvcmUgKHZhbHVlIG9mIGxhc3Qgcm93IG9mIHRoaXMgYmxvY2spLlxuICAgIHZhciBoT3V0ID0gb25lSWZOb3RaZXJvKHBIICYgY3R4Lmxhc3RSb3dNYXNrW2JdKSAtXG4gICAgICAgIG9uZUlmTm90WmVybyhtSCAmIGN0eC5sYXN0Um93TWFza1tiXSk7XG4gICAgLy8gU3RlcCAzOiBVcGRhdGUgdmVydGljYWwgZGVsdGFzIGZvciB1c2Ugd2hlbiBwcm9jZXNzaW5nIG5leHQgY2hhci5cbiAgICBwSCA8PD0gMTtcbiAgICBtSCA8PD0gMTtcbiAgICBtSCB8PSBoSW5Jc05lZ2F0aXZlO1xuICAgIHBIIHw9IG9uZUlmTm90WmVybyhoSW4pIC0gaEluSXNOZWdhdGl2ZTsgLy8gc2V0IHBIWzBdIGlmIGhJbiA+IDBcbiAgICBwViA9IG1IIHwgfih4ViB8IHBIKTtcbiAgICBtViA9IHBIICYgeFY7XG4gICAgY3R4LlBbYl0gPSBwVjtcbiAgICBjdHguTVtiXSA9IG1WO1xuICAgIHJldHVybiBoT3V0O1xufVxuLyoqXG4gKiBGaW5kIHRoZSBlbmRzIGFuZCBlcnJvciBjb3VudHMgZm9yIG1hdGNoZXMgb2YgYHBhdHRlcm5gIGluIGB0ZXh0YC5cbiAqXG4gKiBPbmx5IHRoZSBtYXRjaGVzIHdpdGggdGhlIGxvd2VzdCBlcnJvciBjb3VudCBhcmUgcmVwb3J0ZWQuIE90aGVyIG1hdGNoZXNcbiAqIHdpdGggZXJyb3IgY291bnRzIDw9IG1heEVycm9ycyBhcmUgZGlzY2FyZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGJsb2NrLWJhc2VkIHNlYXJjaCBhbGdvcml0aG0gZnJvbSBGaWcuIDkgb24gcC40MTAgb2YgWzFdLlxuICovXG5mdW5jdGlvbiBmaW5kTWF0Y2hFbmRzKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIENsYW1wIGVycm9yIGNvdW50IHNvIHdlIGNhbiByZWx5IG9uIHRoZSBgbWF4RXJyb3JzYCBhbmQgYHBhdHRlcm4ubGVuZ3RoYFxuICAgIC8vIHJvd3MgYmVpbmcgaW4gdGhlIHNhbWUgYmxvY2sgYmVsb3cuXG4gICAgbWF4RXJyb3JzID0gTWF0aC5taW4obWF4RXJyb3JzLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgICAvLyBXb3JkIHNpemUuXG4gICAgdmFyIHcgPSAzMjtcbiAgICAvLyBJbmRleCBvZiBtYXhpbXVtIGJsb2NrIGxldmVsLlxuICAgIHZhciBiTWF4ID0gTWF0aC5jZWlsKHBhdHRlcm4ubGVuZ3RoIC8gdykgLSAxO1xuICAgIC8vIENvbnRleHQgdXNlZCBhY3Jvc3MgYmxvY2sgY2FsY3VsYXRpb25zLlxuICAgIHZhciBjdHggPSB7XG4gICAgICAgIFA6IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIE06IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIGxhc3RSb3dNYXNrOiBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpXG4gICAgfTtcbiAgICBjdHgubGFzdFJvd01hc2suZmlsbCgxIDw8IDMxKTtcbiAgICBjdHgubGFzdFJvd01hc2tbYk1heF0gPSAxIDw8IChwYXR0ZXJuLmxlbmd0aCAtIDEpICUgdztcbiAgICAvLyBEdW1teSBcInBlcVwiIGFycmF5IGZvciBjaGFycyBpbiB0aGUgdGV4dCB3aGljaCBkbyBub3Qgb2NjdXIgaW4gdGhlIHBhdHRlcm4uXG4gICAgdmFyIGVtcHR5UGVxID0gbmV3IFVpbnQzMkFycmF5KGJNYXggKyAxKTtcbiAgICAvLyBNYXAgb2YgVVRGLTE2IGNoYXJhY3RlciBjb2RlIHRvIGJpdCB2ZWN0b3IgaW5kaWNhdGluZyBwb3NpdGlvbnMgaW4gdGhlXG4gICAgLy8gcGF0dGVybiB0aGF0IGVxdWFsIHRoYXQgY2hhcmFjdGVyLlxuICAgIHZhciBwZXEgPSBuZXcgTWFwKCk7XG4gICAgLy8gVmVyc2lvbiBvZiBgcGVxYCB0aGF0IG9ubHkgc3RvcmVzIG1hcHBpbmdzIGZvciBzbWFsbCBjaGFyYWN0ZXJzLiBUaGlzXG4gICAgLy8gYWxsb3dzIGZhc3RlciBsb29rdXBzIHdoZW4gaXRlcmF0aW5nIHRocm91Z2ggdGhlIHRleHQgYmVjYXVzZSBhIHNpbXBsZVxuICAgIC8vIGFycmF5IGxvb2t1cCBjYW4gYmUgZG9uZSBpbnN0ZWFkIG9mIGEgaGFzaCB0YWJsZSBsb29rdXAuXG4gICAgdmFyIGFzY2lpUGVxID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgICBhc2NpaVBlcS5wdXNoKGVtcHR5UGVxKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlIGBjdHgucGVxYCAtIGEgbWFwIG9mIGNoYXJhY3RlciB2YWx1ZXMgdG8gYml0bWFza3MgaW5kaWNhdGluZ1xuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGF0IGNoYXJhY3RlciB3aXRoaW4gdGhlIHBhdHRlcm4sIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHNcbiAgICAvLyBhIHBvc2l0aW9uIGluIHRoZSBwYXR0ZXJuLlxuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgcGF0dGVybi5sZW5ndGg7IGMgKz0gMSkge1xuICAgICAgICB2YXIgdmFsID0gcGF0dGVybi5jaGFyQ29kZUF0KGMpO1xuICAgICAgICBpZiAocGVxLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgY2hhciBpbiBwYXR0ZXJuLlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoYXJQZXEgPSBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpO1xuICAgICAgICBwZXEuc2V0KHZhbCwgY2hhclBlcSk7XG4gICAgICAgIGlmICh2YWwgPCBhc2NpaVBlcS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFzY2lpUGVxW3ZhbF0gPSBjaGFyUGVxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGIgPSAwOyBiIDw9IGJNYXg7IGIgKz0gMSkge1xuICAgICAgICAgICAgY2hhclBlcVtiXSA9IDA7XG4gICAgICAgICAgICAvLyBTZXQgYWxsIHRoZSBiaXRzIHdoZXJlIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGN1cnJlbnQgY2hhciAoY2gpLlxuICAgICAgICAgICAgLy8gRm9yIGluZGV4ZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIGFsd2F5cyBzZXQgdGhlIGJpdCBhcyBpZiB0aGVcbiAgICAgICAgICAgIC8vIHBhdHRlcm4gY29udGFpbmVkIGEgd2lsZGNhcmQgY2hhciBpbiB0aGF0IHBvc2l0aW9uLlxuICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCB3OyByICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gYiAqIHcgKyByO1xuICAgICAgICAgICAgICAgIGlmIChpZHggPj0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IHBhdHRlcm4uY2hhckNvZGVBdChpZHgpID09PSB2YWw7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJQZXFbYl0gfD0gMSA8PCByO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJbmRleCBvZiBsYXN0LWFjdGl2ZSBibG9jayBsZXZlbCBpbiB0aGUgY29sdW1uLlxuICAgIHZhciB5ID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKG1heEVycm9ycyAvIHcpIC0gMSk7XG4gICAgLy8gSW5pdGlhbGl6ZSBtYXhpbXVtIGVycm9yIGNvdW50IGF0IGJvdHRvbSBvZiBlYWNoIGJsb2NrLlxuICAgIHZhciBzY29yZSA9IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSk7XG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIHNjb3JlW2JdID0gKGIgKyAxKSAqIHc7XG4gICAgfVxuICAgIHNjb3JlW2JNYXhdID0gcGF0dGVybi5sZW5ndGg7XG4gICAgLy8gSW5pdGlhbGl6ZSB2ZXJ0aWNhbCBkZWx0YXMgZm9yIGVhY2ggYmxvY2suXG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIGN0eC5QW2JdID0gfjA7XG4gICAgICAgIGN0eC5NW2JdID0gMDtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBlYWNoIGNoYXIgb2YgdGhlIHRleHQsIGNvbXB1dGluZyB0aGUgZXJyb3IgY291bnQgZm9yIGB3YCBjaGFycyBvZlxuICAgIC8vIHRoZSBwYXR0ZXJuIGF0IGEgdGltZS5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRleHQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBiaXRtYXNrIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb25zIG9mIHRoZSBjdXJyZW50IGNoYXIgZnJvbVxuICAgICAgICAvLyB0aGUgdGV4dCB3aXRoaW4gdGhlIHBhdHRlcm4uXG4gICAgICAgIHZhciBjaGFyQ29kZSA9IHRleHQuY2hhckNvZGVBdChqKTtcbiAgICAgICAgdmFyIGNoYXJQZXEgPSB2b2lkIDA7XG4gICAgICAgIGlmIChjaGFyQ29kZSA8IGFzY2lpUGVxLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gRmFzdCBhcnJheSBsb29rdXAuXG4gICAgICAgICAgICBjaGFyUGVxID0gYXNjaWlQZXFbY2hhckNvZGVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU2xvd2VyIGhhc2ggdGFibGUgbG9va3VwLlxuICAgICAgICAgICAgY2hhclBlcSA9IHBlcS5nZXQoY2hhckNvZGUpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyUGVxID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgY2hhclBlcSA9IGVtcHR5UGVxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3VudCBmb3IgYmxvY2tzIHRoYXQgd2UgZGVmaW5pdGVseSBoYXZlIHRvIHByb2Nlc3MgZm9yXG4gICAgICAgIC8vIHRoaXMgY29sdW1uLlxuICAgICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBiID0gMDsgYiA8PSB5OyBiICs9IDEpIHtcbiAgICAgICAgICAgIGNhcnJ5ID0gYWR2YW5jZUJsb2NrKGN0eCwgY2hhclBlcSwgYiwgY2FycnkpO1xuICAgICAgICAgICAgc2NvcmVbYl0gKz0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgYWxzbyBuZWVkIHRvIGNvbXB1dGUgYW4gYWRkaXRpb25hbCBibG9jaywgb3IgaWYgd2UgY2FuIHJlZHVjZVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGJsb2NrcyBwcm9jZXNzZWQgZm9yIHRoZSBuZXh0IGNvbHVtbi5cbiAgICAgICAgaWYgKHNjb3JlW3ldIC0gY2FycnkgPD0gbWF4RXJyb3JzICYmXG4gICAgICAgICAgICB5IDwgYk1heCAmJlxuICAgICAgICAgICAgKGNoYXJQZXFbeSArIDFdICYgMSB8fCBjYXJyeSA8IDApKSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGlzIHVuZGVyIHRocmVzaG9sZCwgaW5jcmVhc2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhpcyBjb2x1bW4gJiBuZXh0IGJ5IDEuXG4gICAgICAgICAgICB5ICs9IDE7XG4gICAgICAgICAgICBjdHguUFt5XSA9IH4wO1xuICAgICAgICAgICAgY3R4Lk1beV0gPSAwO1xuICAgICAgICAgICAgdmFyIG1heEJsb2NrU2NvcmUgPSB5ID09PSBiTWF4ID8gcGF0dGVybi5sZW5ndGggJSB3IDogdztcbiAgICAgICAgICAgIHNjb3JlW3ldID1cbiAgICAgICAgICAgICAgICBzY29yZVt5IC0gMV0gK1xuICAgICAgICAgICAgICAgICAgICBtYXhCbG9ja1Njb3JlIC1cbiAgICAgICAgICAgICAgICAgICAgY2FycnkgK1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlQmxvY2soY3R4LCBjaGFyUGVxLCB5LCBjYXJyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGV4Y2VlZHMgdGhyZXNob2xkLCByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhlIG5leHQgY29sdW1uLlxuICAgICAgICAgICAgd2hpbGUgKHkgPiAwICYmIHNjb3JlW3ldID49IG1heEVycm9ycyArIHcpIHtcbiAgICAgICAgICAgICAgICB5IC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZXJyb3IgY291bnQgaXMgdW5kZXIgdGhyZXNob2xkLCByZXBvcnQgYSBtYXRjaC5cbiAgICAgICAgaWYgKHkgPT09IGJNYXggJiYgc2NvcmVbeV0gPD0gbWF4RXJyb3JzKSB7XG4gICAgICAgICAgICBpZiAoc2NvcmVbeV0gPCBtYXhFcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIGFueSBlYXJsaWVyLCB3b3JzZSBtYXRjaGVzLlxuICAgICAgICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKDAsIG1hdGNoZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICAgICAgICAgIGVuZDogaiArIDEsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBzY29yZVt5XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBCZWNhdXNlIGBzZWFyY2hgIG9ubHkgcmVwb3J0cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBsb3dlc3QgZXJyb3IgY291bnQsXG4gICAgICAgICAgICAvLyB3ZSBjYW4gXCJyYXRjaGV0IGRvd25cIiB0aGUgbWF4IGVycm9yIHRocmVzaG9sZCB3aGVuZXZlciBhIG1hdGNoIGlzXG4gICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbmQgdGhlcmVieSBzYXZlIGEgc21hbGwgYW1vdW50IG9mIHdvcmsgZm9yIHRoZSByZW1haW5kZXJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB0ZXh0LlxuICAgICAgICAgICAgbWF4RXJyb3JzID0gc2NvcmVbeV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59XG4vKipcbiAqIFNlYXJjaCBmb3IgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogUmV0dXJucyB0aGUgc3RhcnQsIGFuZCBlbmQgcG9zaXRpb25zIGFuZCBlcnJvciBjb3VudHMgZm9yIGVhY2ggbG93ZXN0LWNvc3RcbiAqIG1hdGNoLiBPbmx5IHRoZSBcImJlc3RcIiBtYXRjaGVzIGFyZSByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoRW5kcyh0ZXh0LCBwYXR0ZXJuLCBtYXhFcnJvcnMpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hTdGFydHModGV4dCwgcGF0dGVybiwgbWF0Y2hlcyk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzZWFyY2g7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3089\n')},3088:function(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__){"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/approx-string-match/dist/index.js\nvar dist = __webpack_require__(3089);\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/match-quote.js\n\n/**\n * @typedef {import(\'approx-string-match\').Match} StringMatch\n */\n\n/**\n * @typedef Match\n * @prop {number} start - Start offset of match in text\n * @prop {number} end - End offset of match in text\n * @prop {number} score -\n * Score for the match between 0 and 1.0, where 1.0 indicates a perfect match\n * for the quote and context.\n */\n\n/**\n * Find the best approximate matches for `str` in `text` allowing up to `maxErrors` errors.\n *\n * @param {string} text\n * @param {string} str\n * @param {number} maxErrors\n * @return {StringMatch[]}\n */\n\nfunction search(text, str, maxErrors) {\n // Do a fast search for exact matches. The `approx-string-match` library\n // doesn\'t currently incorporate this optimization itself.\n var matchPos = 0;\n var exactMatches = [];\n\n while (matchPos !== -1) {\n matchPos = text.indexOf(str, matchPos);\n\n if (matchPos !== -1) {\n exactMatches.push({\n start: matchPos,\n end: matchPos + str.length,\n errors: 0\n });\n matchPos += 1;\n }\n }\n\n if (exactMatches.length > 0) {\n return exactMatches;\n } // If there are no exact matches, do a more expensive search for matches\n // with errors.\n\n\n return (0,dist/* default */.Z)(text, str, maxErrors);\n}\n/**\n * Compute a score between 0 and 1.0 for the similarity between `text` and `str`.\n *\n * @param {string} text\n * @param {string} str\n */\n\n\nfunction textMatchScore(text, str) {\n /* istanbul ignore next - `scoreMatch` will never pass an empty string */\n if (str.length === 0 || text.length === 0) {\n return 0.0;\n }\n\n var matches = search(text, str, str.length); // prettier-ignore\n\n return 1 - matches[0].errors / str.length;\n}\n/**\n * Find the best approximate match for `quote` in `text`.\n *\n * Returns `null` if no match exceeding the minimum quality threshold was found.\n *\n * @param {string} text - Document text to search\n * @param {string} quote - String to find within `text`\n * @param {Object} context -\n * Context in which the quote originally appeared. This is used to choose the\n * best match.\n * @param {string} [context.prefix] - Expected text before the quote\n * @param {string} [context.suffix] - Expected text after the quote\n * @param {number} [context.hint] - Expected offset of match within text\n * @return {Match|null}\n */\n\n\nfunction matchQuote(text, quote) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (quote.length === 0) {\n return null;\n } // Choose the maximum number of errors to allow for the initial search.\n // This choice involves a tradeoff between:\n //\n // - Recall (proportion of "good" matches found)\n // - Precision (proportion of matches found which are "good")\n // - Cost of the initial search and of processing the candidate matches [1]\n //\n // [1] Specifically, the expected-time complexity of the initial search is\n // `O((maxErrors / 32) * text.length)`. See `approx-string-match` docs.\n\n\n var maxErrors = Math.min(256, quote.length / 2); // Find closest matches for `quote` in `text` based on edit distance.\n\n var matches = search(text, quote, maxErrors);\n\n if (matches.length === 0) {\n return null;\n }\n /**\n * Compute a score between 0 and 1.0 for a match candidate.\n *\n * @param {StringMatch} match\n */\n\n\n var scoreMatch = function scoreMatch(match) {\n var quoteWeight = 50; // Similarity of matched text to quote.\n\n var prefixWeight = 20; // Similarity of text before matched text to `context.prefix`.\n\n var suffixWeight = 20; // Similarity of text after matched text to `context.suffix`.\n\n var posWeight = 2; // Proximity to expected location. Used as a tie-breaker.\n\n var quoteScore = 1 - match.errors / quote.length;\n var prefixScore = context.prefix ? textMatchScore(text.slice(Math.max(0, match.start - context.prefix.length), match.start), context.prefix) : 1.0;\n var suffixScore = context.suffix ? textMatchScore(text.slice(match.end, match.end + context.suffix.length), context.suffix) : 1.0;\n var posScore = 1.0;\n\n if (typeof context.hint === \'number\') {\n var offset = Math.abs(match.start - context.hint);\n posScore = 1.0 - offset / text.length;\n }\n\n var rawScore = quoteWeight * quoteScore + prefixWeight * prefixScore + suffixWeight * suffixScore + posWeight * posScore;\n var maxScore = quoteWeight + prefixWeight + suffixWeight + posWeight;\n var normalizedScore = rawScore / maxScore;\n return normalizedScore;\n }; // Rank matches based on similarity of actual and expected surrounding text\n // and actual/expected offset in the document text.\n\n\n var scoredMatches = matches.map(function (m) {\n return {\n start: m.start,\n end: m.end,\n score: scoreMatch(m)\n };\n }); // Choose match with highest score.\n\n scoredMatches.sort(function (a, b) {\n return b.score - a.score;\n });\n return scoredMatches[0];\n}\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/text-range.js\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Return the combined length of text nodes contained in `node`.\n *\n * @param {Node} node\n */\nfunction nodeTextLength(node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.TEXT_NODE:\n // nb. `textContent` excludes text in comments and processing instructions\n // when called on a parent element, so we don\'t need to subtract that here.\n return (\n /** @type {string} */\n node.textContent.length\n );\n\n default:\n return 0;\n }\n}\n/**\n * Return the total length of the text of all previous siblings of `node`.\n *\n * @param {Node} node\n */\n\n\nfunction previousSiblingsTextLength(node) {\n var sibling = node.previousSibling;\n var length = 0;\n\n while (sibling) {\n length += nodeTextLength(sibling);\n sibling = sibling.previousSibling;\n }\n\n return length;\n}\n/**\n * Resolve one or more character offsets within an element to (text node, position)\n * pairs.\n *\n * @param {Element} element\n * @param {number[]} offsets - Offsets, which must be sorted in ascending order\n * @return {{ node: Text, offset: number }[]}\n */\n\n\nfunction resolveOffsets(element) {\n for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n offsets[_key - 1] = arguments[_key];\n }\n\n var nextOffset = offsets.shift();\n var nodeIter =\n /** @type {Document} */\n element.ownerDocument.createNodeIterator(element, NodeFilter.SHOW_TEXT);\n var results = [];\n var currentNode = nodeIter.nextNode();\n var textNode;\n var length = 0; // Find the text node containing the `nextOffset`th character from the start\n // of `element`.\n\n while (nextOffset !== undefined && currentNode) {\n textNode =\n /** @type {Text} */\n currentNode;\n\n if (length + textNode.data.length > nextOffset) {\n results.push({\n node: textNode,\n offset: nextOffset - length\n });\n nextOffset = offsets.shift();\n } else {\n currentNode = nodeIter.nextNode();\n length += textNode.data.length;\n }\n } // Boundary case.\n\n\n while (nextOffset !== undefined && textNode && length === nextOffset) {\n results.push({\n node: textNode,\n offset: textNode.data.length\n });\n nextOffset = offsets.shift();\n }\n\n if (nextOffset !== undefined) {\n throw new RangeError(\'Offset exceeds text length\');\n }\n\n return results;\n}\n\nvar RESOLVE_FORWARDS = 1;\nvar RESOLVE_BACKWARDS = 2;\n/**\n * Represents an offset within the text content of an element.\n *\n * This position can be resolved to a specific descendant node in the current\n * DOM subtree of the element using the `resolve` method.\n */\n\nvar text_range_TextPosition = /*#__PURE__*/function () {\n /**\n * Construct a `TextPosition` that refers to the text position `offset` within\n * the text content of `element`.\n *\n * @param {Element} element\n * @param {number} offset\n */\n function TextPosition(element, offset) {\n _classCallCheck(this, TextPosition);\n\n if (offset < 0) {\n throw new Error(\'Offset is invalid\');\n }\n /** Element that `offset` is relative to. */\n\n\n this.element = element;\n /** Character offset from the start of the element\'s `textContent`. */\n\n this.offset = offset;\n }\n /**\n * Return a copy of this position with offset relative to a given ancestor\n * element.\n *\n * @param {Element} parent - Ancestor of `this.element`\n * @return {TextPosition}\n */\n\n\n _createClass(TextPosition, [{\n key: "relativeTo",\n value: function relativeTo(parent) {\n if (!parent.contains(this.element)) {\n throw new Error(\'Parent is not an ancestor of current element\');\n }\n\n var el = this.element;\n var offset = this.offset;\n\n while (el !== parent) {\n offset += previousSiblingsTextLength(el);\n el =\n /** @type {Element} */\n el.parentElement;\n }\n\n return new TextPosition(el, offset);\n }\n /**\n * Resolve the position to a specific text node and offset within that node.\n *\n * Throws if `this.offset` exceeds the length of the element\'s text. In the\n * case where the element has no text and `this.offset` is 0, the `direction`\n * option determines what happens.\n *\n * Offsets at the boundary between two nodes are resolved to the start of the\n * node that begins at the boundary.\n *\n * @param {Object} [options]\n * @param {RESOLVE_FORWARDS|RESOLVE_BACKWARDS} [options.direction] -\n * Specifies in which direction to search for the nearest text node if\n * `this.offset` is `0` and `this.element` has no text. If not specified\n * an error is thrown.\n * @return {{ node: Text, offset: number }}\n * @throws {RangeError}\n */\n\n }, {\n key: "resolve",\n value: function resolve() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n try {\n return resolveOffsets(this.element, this.offset)[0];\n } catch (err) {\n if (this.offset === 0 && options.direction !== undefined) {\n var tw = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);\n tw.currentNode = this.element;\n var forwards = options.direction === RESOLVE_FORWARDS;\n var text =\n /** @type {Text|null} */\n forwards ? tw.nextNode() : tw.previousNode();\n\n if (!text) {\n throw err;\n }\n\n return {\n node: text,\n offset: forwards ? 0 : text.data.length\n };\n } else {\n throw err;\n }\n }\n }\n /**\n * Construct a `TextPosition` that refers to the `offset`th character within\n * `node`.\n *\n * @param {Node} node\n * @param {number} offset\n * @return {TextPosition}\n */\n\n }], [{\n key: "fromCharOffset",\n value: function fromCharOffset(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n return TextPosition.fromPoint(node, offset);\n\n case Node.ELEMENT_NODE:\n return new TextPosition(\n /** @type {Element} */\n node, offset);\n\n default:\n throw new Error(\'Node is not an element or text node\');\n }\n }\n /**\n * Construct a `TextPosition` representing the range start or end point (node, offset).\n *\n * @param {Node} node - Text or Element node\n * @param {number} offset - Offset within the node.\n * @return {TextPosition}\n */\n\n }, {\n key: "fromPoint",\n value: function fromPoint(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n {\n if (offset < 0 || offset >\n /** @type {Text} */\n node.data.length) {\n throw new Error(\'Text node offset is out of range\');\n }\n\n if (!node.parentElement) {\n throw new Error(\'Text node has no parent\');\n } // Get the offset from the start of the parent element.\n\n\n var textOffset = previousSiblingsTextLength(node) + offset;\n return new TextPosition(node.parentElement, textOffset);\n }\n\n case Node.ELEMENT_NODE:\n {\n if (offset < 0 || offset > node.childNodes.length) {\n throw new Error(\'Child node offset is out of range\');\n } // Get the text length before the `offset`th child of element.\n\n\n var _textOffset = 0;\n\n for (var i = 0; i < offset; i++) {\n _textOffset += nodeTextLength(node.childNodes[i]);\n }\n\n return new TextPosition(\n /** @type {Element} */\n node, _textOffset);\n }\n\n default:\n throw new Error(\'Point is not in an element or text node\');\n }\n }\n }]);\n\n return TextPosition;\n}();\n/**\n * Represents a region of a document as a (start, end) pair of `TextPosition` points.\n *\n * Representing a range in this way allows for changes in the DOM content of the\n * range which don\'t affect its text content, without affecting the text content\n * of the range itself.\n */\n\nvar text_range_TextRange = /*#__PURE__*/function () {\n /**\n * Construct an immutable `TextRange` from a `start` and `end` point.\n *\n * @param {TextPosition} start\n * @param {TextPosition} end\n */\n function TextRange(start, end) {\n _classCallCheck(this, TextRange);\n\n this.start = start;\n this.end = end;\n }\n /**\n * Return a copy of this range with start and end positions relative to a\n * given ancestor. See `TextPosition.relativeTo`.\n *\n * @param {Element} element\n */\n\n\n _createClass(TextRange, [{\n key: "relativeTo",\n value: function relativeTo(element) {\n return new TextRange(this.start.relativeTo(element), this.end.relativeTo(element));\n }\n /**\n * Resolve the `TextRange` to a DOM range.\n *\n * The resulting DOM Range will always start and end in a `Text` node.\n * Hence `TextRange.fromRange(range).toRange()` can be used to "shrink" a\n * range to the text it contains.\n *\n * May throw if the `start` or `end` positions cannot be resolved to a range.\n *\n * @return {Range}\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var start;\n var end;\n\n if (this.start.element === this.end.element && this.start.offset <= this.end.offset) {\n // Fast path for start and end points in same element.\n var _resolveOffsets = resolveOffsets(this.start.element, this.start.offset, this.end.offset);\n\n var _resolveOffsets2 = _slicedToArray(_resolveOffsets, 2);\n\n start = _resolveOffsets2[0];\n end = _resolveOffsets2[1];\n } else {\n start = this.start.resolve({\n direction: RESOLVE_FORWARDS\n });\n end = this.end.resolve({\n direction: RESOLVE_BACKWARDS\n });\n }\n\n var range = new Range();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range;\n }\n /**\n * Convert an existing DOM `Range` to a `TextRange`\n *\n * @param {Range} range\n * @return {TextRange}\n */\n\n }], [{\n key: "fromRange",\n value: function fromRange(range) {\n var start = text_range_TextPosition.fromPoint(range.startContainer, range.startOffset);\n var end = text_range_TextPosition.fromPoint(range.endContainer, range.endOffset);\n return new TextRange(start, end);\n }\n /**\n * Return a `TextRange` from the `start`th to `end`th characters in `root`.\n *\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n\n }, {\n key: "fromOffsets",\n value: function fromOffsets(root, start, end) {\n return new TextRange(new text_range_TextPosition(root, start), new text_range_TextPosition(root, end));\n }\n }]);\n\n return TextRange;\n}();\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/types.js\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction types_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction types_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction types_createClass(Constructor, protoProps, staticProps) { if (protoProps) types_defineProperties(Constructor.prototype, protoProps); if (staticProps) types_defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This module exports a set of classes for converting between DOM `Range`\n * objects and different types of selectors. It is mostly a thin wrapper around a\n * set of anchoring libraries. It serves two main purposes:\n *\n * 1. Providing a consistent interface across different types of anchors.\n * 2. Insulating the rest of the code from API changes in the underlying anchoring\n * libraries.\n */\n\n\n\n/**\n * @typedef {import(\'../../types/api\').RangeSelector} RangeSelector\n * @typedef {import(\'../../types/api\').TextPositionSelector} TextPositionSelector\n * @typedef {import(\'../../types/api\').TextQuoteSelector} TextQuoteSelector\n */\n\n/**\n * Converts between `RangeSelector` selectors and `Range` objects.\n */\n\nvar RangeAnchor = /*#__PURE__*/(/* unused pure expression or super */ null && (function () {\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n function RangeAnchor(root, range) {\n types_classCallCheck(this, RangeAnchor);\n\n this.root = root;\n this.range = range;\n }\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n\n\n types_createClass(RangeAnchor, [{\n key: "toRange",\n value: function toRange() {\n return this.range;\n }\n /**\n * @return {RangeSelector}\n */\n\n }, {\n key: "toSelector",\n value: function toSelector() {\n // "Shrink" the range so that it tightly wraps its text. This ensures more\n // predictable output for a given text selection.\n var normalizedRange = TextRange.fromRange(this.range).toRange();\n var textRange = TextRange.fromRange(normalizedRange);\n var startContainer = xpathFromNode(textRange.start.element, this.root);\n var endContainer = xpathFromNode(textRange.end.element, this.root);\n return {\n type: \'RangeSelector\',\n startContainer: startContainer,\n startOffset: textRange.start.offset,\n endContainer: endContainer,\n endOffset: textRange.end.offset\n };\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n return new RangeAnchor(root, range);\n }\n /**\n * Create an anchor from a serialized `RangeSelector` selector.\n *\n * @param {Element} root - A root element from which to anchor.\n * @param {RangeSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var startContainer = nodeFromXPath(selector.startContainer, root);\n\n if (!startContainer) {\n throw new Error(\'Failed to resolve startContainer XPath\');\n }\n\n var endContainer = nodeFromXPath(selector.endContainer, root);\n\n if (!endContainer) {\n throw new Error(\'Failed to resolve endContainer XPath\');\n }\n\n var startPos = TextPosition.fromCharOffset(startContainer, selector.startOffset);\n var endPos = TextPosition.fromCharOffset(endContainer, selector.endOffset);\n var range = new TextRange(startPos, endPos).toRange();\n return new RangeAnchor(root, range);\n }\n }]);\n\n return RangeAnchor;\n}()));\n/**\n * Converts between `TextPositionSelector` selectors and `Range` objects.\n */\n\nvar TextPositionAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n function TextPositionAnchor(root, start, end) {\n types_classCallCheck(this, TextPositionAnchor);\n\n this.root = root;\n this.start = start;\n this.end = end;\n }\n /**\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextPositionAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextPositionSelector}\n */\n function toSelector() {\n return {\n type: \'TextPositionSelector\',\n start: this.start,\n end: this.end\n };\n }\n }, {\n key: "toRange",\n value: function toRange() {\n return text_range_TextRange.fromOffsets(this.root, this.start, this.end).toRange();\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n return new TextPositionAnchor(root, textRange.start.offset, textRange.end.offset);\n }\n /**\n * @param {Element} root\n * @param {TextPositionSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n return new TextPositionAnchor(root, selector.start, selector.end);\n }\n }]);\n\n return TextPositionAnchor;\n}();\n/**\n * @typedef QuoteMatchOptions\n * @prop {number} [hint] - Expected position of match in text. See `matchQuote`.\n */\n\n/**\n * Converts between `TextQuoteSelector` selectors and `Range` objects.\n */\n\nvar TextQuoteAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root - A root element from which to anchor.\n * @param {string} exact\n * @param {Object} context\n * @param {string} [context.prefix]\n * @param {string} [context.suffix]\n */\n function TextQuoteAnchor(root, exact) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n types_classCallCheck(this, TextQuoteAnchor);\n\n this.root = root;\n this.exact = exact;\n this.context = context;\n }\n /**\n * Create a `TextQuoteAnchor` from a range.\n *\n * Will throw if `range` does not contain any text nodes.\n *\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextQuoteAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextQuoteSelector}\n */\n function toSelector() {\n return {\n type: \'TextQuoteSelector\',\n exact: this.exact,\n prefix: this.context.prefix,\n suffix: this.context.suffix\n };\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return this.toPositionAnchor(options).toRange();\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toPositionAnchor",\n value: function toPositionAnchor() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var text =\n /** @type {string} */\n this.root.textContent;\n var match = matchQuote(text, this.exact, _objectSpread(_objectSpread({}, this.context), {}, {\n hint: options.hint\n }));\n\n if (!match) {\n throw new Error(\'Quote not found\');\n }\n\n return new TextPositionAnchor(this.root, match.start, match.end);\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var text =\n /** @type {string} */\n root.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n var start = textRange.start.offset;\n var end = textRange.end.offset; // Number of characters around the quote to capture as context. We currently\n // always use a fixed amount, but it would be better if this code was aware\n // of logical boundaries in the document (paragraph, article etc.) to avoid\n // capturing text unrelated to the quote.\n //\n // In regular prose the ideal content would often be the surrounding sentence.\n // This is a natural unit of meaning which enables displaying quotes in\n // context even when the document is not available. We could use `Intl.Segmenter`\n // for this when available.\n\n var contextLen = 32;\n return new TextQuoteAnchor(root, text.slice(start, end), {\n prefix: text.slice(Math.max(0, start - contextLen), start),\n suffix: text.slice(end, Math.min(text.length, end + contextLen))\n });\n }\n /**\n * @param {Element} root\n * @param {TextQuoteSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var prefix = selector.prefix,\n suffix = selector.suffix;\n return new TextQuoteAnchor(root, selector.exact, {\n prefix: prefix,\n suffix: suffix\n });\n }\n }]);\n\n return TextQuoteAnchor;\n}();\n;// CONCATENATED MODULE: ./src/utils.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = utils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction utils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return utils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return utils_arrayLikeToArray(o, minLen); }\n\nfunction utils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n // Catch JS errors to log them in the app.\n\nwindow.addEventListener("error", function (event) {\n Android.logError(event.message, event.filename, event.lineno);\n}, false);\nwindow.addEventListener("load", function () {\n var observer = new ResizeObserver(function () {\n onViewportWidthChanged();\n snapCurrentOffset();\n });\n observer.observe(document.body);\n}, false);\n/**\n * Having an odd number of columns when displaying two columns per screen causes snapping and page\n * turning issues. To fix this, we insert a blank virtual column at the end of the resource.\n */\n\nfunction appendVirtualColumnIfNeeded() {\n var id = "readium-virtual-page";\n var virtualCol = document.getElementById(id);\n\n if (isScrollModeEnabled() || getColumnCountPerScreen() != 2) {\n if (virtualCol) {\n virtualCol.remove();\n }\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var colCount = documentWidth / pageWidth;\n var hasOddColCount = Math.round(colCount * 2) / 2 % 1 > 0.1;\n\n if (hasOddColCount) {\n if (virtualCol) {\n virtualCol.remove();\n } else {\n virtualCol = document.createElement("div");\n virtualCol.setAttribute("id", id);\n virtualCol.style.breakBefore = "column";\n virtualCol.innerHTML = "​"; // zero-width space\n\n document.body.appendChild(virtualCol);\n }\n }\n }\n}\n\nvar pageWidth = 1;\n\nfunction onViewportWidthChanged() {\n // We can\'t rely on window.innerWidth for the pageWidth on Android, because if the\n // device pixel ratio is not an integer, we get rounding issues offsetting the pages.\n //\n // See https://github.com/readium/readium-css/issues/97\n // and https://github.com/readium/r2-navigator-kotlin/issues/146\n var width = Android.getViewportWidth();\n pageWidth = width / window.devicePixelRatio;\n setProperty("--RS__viewportWidth", "calc(" + width + "px / " + window.devicePixelRatio + ")");\n appendVirtualColumnIfNeeded();\n}\n\nfunction getColumnCountPerScreen() {\n return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n}\nfunction isScrollModeEnabled() {\n var style = document.documentElement.style;\n return style.getPropertyValue("--USER__view").trim() == "readium-scroll-on" || // FIXME: Will need to be removed in Readium 3.0, --USER__scroll was incorrect.\n style.getPropertyValue("--USER__scroll").trim() == "readium-scroll-on";\n}\nfunction isRTL() {\n return document.body.dir.toLowerCase() == "rtl";\n} // Scroll to the given TagId in document and snap.\n\nfunction scrollToId(id) {\n var element = document.getElementById(id);\n\n if (!element) {\n return false;\n }\n\n return scrollToRect(element.getBoundingClientRect());\n} // Position must be in the range [0 - 1], 0-100%.\n\nfunction scrollToPosition(position) {\n // Android.log("scrollToPosition " + position);\n if (position < 0 || position > 1) {\n throw "scrollToPosition() must be given a position from 0.0 to 1.0";\n }\n\n var offset;\n\n if (isScrollModeEnabled()) {\n offset = document.scrollingElement.scrollHeight * position;\n document.scrollingElement.scrollTop = offset; // window.scrollTo(0, offset);\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var factor = isRTL() ? -1 : 1;\n offset = documentWidth * position * factor;\n document.scrollingElement.scrollLeft = snapOffset(offset);\n }\n} // Scrolls to the first occurrence of the given text snippet.\n//\n// The expected text argument is a Locator Text object, as defined here:\n// https://readium.org/architecture/models/locators/\n\nfunction scrollToText(text) {\n var range = rangeFromLocator({\n text: text\n });\n\n if (!range) {\n return false;\n }\n\n scrollToRange(range);\n return true;\n}\n\nfunction scrollToRange(range) {\n return scrollToRect(range.getBoundingClientRect());\n}\n\nfunction scrollToRect(rect) {\n if (isScrollModeEnabled()) {\n document.scrollingElement.scrollTop = rect.top + window.scrollY - window.innerHeight / 2;\n } else {\n document.scrollingElement.scrollLeft = snapOffset(rect.left + window.scrollX);\n }\n\n return true;\n}\n\nfunction scrollToStart() {\n // Android.log("scrollToStart");\n if (!isScrollModeEnabled()) {\n document.scrollingElement.scrollLeft = 0;\n } else {\n document.scrollingElement.scrollTop = 0;\n window.scrollTo(0, 0);\n }\n}\nfunction scrollToEnd() {\n // Android.log("scrollToEnd");\n if (!isScrollModeEnabled()) {\n var factor = isRTL() ? -1 : 1;\n document.scrollingElement.scrollLeft = snapOffset(document.scrollingElement.scrollWidth * factor);\n } else {\n document.scrollingElement.scrollTop = document.body.scrollHeight;\n window.scrollTo(0, document.body.scrollHeight);\n }\n} // Returns false if the page is already at the left-most scroll offset.\n\nfunction scrollLeft() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX - pageWidth;\n var minOffset = isRTL() ? -(documentWidth - pageWidth) : 0;\n return scrollToOffset(Math.max(offset, minOffset));\n} // Returns false if the page is already at the right-most scroll offset.\n\nfunction scrollRight() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX + pageWidth;\n var maxOffset = isRTL() ? 0 : documentWidth - pageWidth;\n return scrollToOffset(Math.min(offset, maxOffset));\n} // Scrolls to the given left offset.\n// Returns false if the page scroll position is already close enough to the given offset.\n\nfunction scrollToOffset(offset) {\n // Android.log("scrollToOffset " + offset);\n if (isScrollModeEnabled()) {\n throw "Called scrollToOffset() with scroll mode enabled. This can only be used in paginated mode.";\n }\n\n var currentOffset = window.scrollX;\n document.scrollingElement.scrollLeft = snapOffset(offset); // In some case the scrollX cannot reach the position respecting to innerWidth\n\n var diff = Math.abs(currentOffset - offset) / pageWidth;\n return diff > 0.01;\n} // Snap the offset to the screen width (page width).\n\n\nfunction snapOffset(offset) {\n var value = offset + (isRTL() ? -1 : 1);\n return value - value % pageWidth;\n} // Snaps the current offset to the page width.\n\n\nfunction snapCurrentOffset() {\n // Android.log("snapCurrentOffset");\n if (isScrollModeEnabled()) {\n return;\n }\n\n var currentOffset = window.scrollX; // Adds half a page to make sure we don\'t snap to the previous page.\n\n var factor = isRTL() ? -1 : 1;\n var delta = factor * (pageWidth / 2);\n document.scrollingElement.scrollLeft = snapOffset(currentOffset + delta);\n}\nfunction rangeFromLocator(locator) {\n try {\n var locations = locator.locations;\n var text = locator.text;\n\n if (text && text.highlight) {\n var root;\n\n if (locations && locations.cssSelector) {\n root = document.querySelector(locations.cssSelector);\n }\n\n if (!root) {\n root = document.body;\n }\n\n var anchor = new TextQuoteAnchor(root, text.highlight, {\n prefix: text.before,\n suffix: text.after\n });\n return anchor.toRange();\n }\n\n if (locations) {\n var element = null;\n\n if (!element && locations.cssSelector) {\n element = document.querySelector(locations.cssSelector);\n }\n\n if (!element && locations.fragments) {\n var _iterator = _createForOfIteratorHelper(locations.fragments),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var htmlId = _step.value;\n element = document.getElementById(htmlId);\n\n if (element) {\n break;\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n if (element) {\n var range = document.createRange();\n range.setStartBefore(element);\n range.setEndAfter(element);\n return range;\n }\n }\n } catch (e) {\n logError(e);\n }\n\n return null;\n} /// User Settings.\n\nfunction setCSSProperties(properties) {\n for (var name in properties) {\n setProperty(name, properties[name]);\n }\n} // For setting user setting.\n\nfunction setProperty(key, value) {\n if (value === null || value === "") {\n removeProperty(key);\n } else {\n var root = document.documentElement; // The `!important` annotation is added with `setProperty()` because if it\'s part of the\n // `value`, it will be ignored by the Web View.\n\n root.style.setProperty(key, value, "important");\n }\n} // For removing user setting.\n\nfunction removeProperty(key) {\n var root = document.documentElement;\n root.style.removeProperty(key);\n} /// Toolkit\n\nfunction log() {\n var message = Array.prototype.slice.call(arguments).join(" ");\n Android.log(message);\n}\nfunction logError(message) {\n Android.logError(message, "", 0);\n}\n;// CONCATENATED MODULE: ./src/rect.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction rect_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = rect_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction rect_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return rect_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return rect_arrayLikeToArray(o, minLen); }\n\nfunction rect_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nvar debug = false;\n/**\n * Converts a DOMRect into a JSON object understandable by the native side.\n */\n\nfunction toNativeRect(rect) {\n var pixelRatio = window.devicePixelRatio;\n var width = rect.width * pixelRatio;\n var height = rect.height * pixelRatio;\n var left = rect.left * pixelRatio;\n var top = rect.top * pixelRatio;\n var right = left + width;\n var bottom = top + height;\n return {\n width: width,\n height: height,\n left: left,\n top: top,\n right: right,\n bottom: bottom\n };\n}\nfunction getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var clientRects = range.getClientRects();\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator = rect_createForOfIteratorHelper(clientRects),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var rangeClientRect = _step.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n var mergedRects = mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = removeContainedRects(mergedRects, tolerance);\n var newRects = replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n rect_log("CLIENT RECT: remove small");\n newRects.splice(j, 1);\n } else {\n rect_log("CLIENT RECT: remove small, but keep otherwise empty!");\n break;\n }\n }\n }\n\n rect_log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n return newRects;\n}\n\nfunction mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("mergeTouchingRects rect1 === rect2 ??!");\n return "continue";\n }\n\n var rectsLineUpVertically = almostEqual(rect1.top, rect2.top, tolerance) && almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = almostEqual(rect1.left, rect2.left, tolerance) && almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n rect_log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret = _loop(j);\n\n if (_ret === "continue") continue;\n if (_typeof(_ret) === "object") return _ret.v;\n }\n }\n\n return rects;\n}\n\nfunction getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator2 = rect_createForOfIteratorHelper(rects),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var rect = _step2.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n rect_log("CLIENT RECT: remove tiny");\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator3 = rect_createForOfIteratorHelper(rects),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var possiblyContainingRect = _step3.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (rectContains(possiblyContainingRect, rect, tolerance)) {\n rect_log("CLIENT RECT: remove contained");\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction rectContains(rect1, rect2, tolerance) {\n return rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || almostEqual(rect.left, x, tolerance)) && (rect.right > x || almostEqual(rect.right, x, tolerance)) && (rect.top < y || almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("replaceOverlapingRects rect1 === rect2 ??!");\n continue;\n }\n\n if (rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret2 = function () {\n var toAdd = [];\n var toRemove = void 0;\n var subtractRects1 = rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n var subtractRects2 = rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n }\n }\n\n rect_log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: replaceOverlapingRects(newRects)\n };\n }();\n\n if (_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction rectSubtract(rect1, rect2) {\n var rectIntersected = rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n return {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n}\n\nfunction rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction rect_log() {\n if (debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/decorator.js\nfunction decorator_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = decorator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction decorator_slicedToArray(arr, i) { return decorator_arrayWithHoles(arr) || decorator_iterableToArrayLimit(arr, i) || decorator_unsupportedIterableToArray(arr, i) || decorator_nonIterableRest(); }\n\nfunction decorator_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction decorator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return decorator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return decorator_arrayLikeToArray(o, minLen); }\n\nfunction decorator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction decorator_iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction decorator_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nvar styles = new Map();\nvar groups = new Map();\nvar lastGroupId = 0;\n/**\n * Registers a list of additional supported Decoration Templates.\n *\n * Each template object is indexed by the style ID.\n */\n\nfunction registerTemplates(newStyles) {\n var stylesheet = "";\n\n for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = decorator_slicedToArray(_Object$entries[_i], 2),\n id = _Object$entries$_i[0],\n style = _Object$entries$_i[1];\n\n styles.set(id, style);\n\n if (style.stylesheet) {\n stylesheet += style.stylesheet + "\\n";\n }\n }\n\n if (stylesheet) {\n var styleElement = document.createElement("style");\n styleElement.innerHTML = stylesheet;\n document.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n}\n/**\n * Returns an instance of DecorationGroup for the given group name.\n */\n\nfunction getDecorations(groupName) {\n var group = groups.get(groupName);\n\n if (!group) {\n var id = "r2-decoration-" + lastGroupId++;\n group = DecorationGroup(id, groupName);\n groups.set(groupName, group);\n }\n\n return group;\n}\n/**\n * Handles click events on a Decoration.\n * Returns whether a decoration matched this event.\n */\n\nfunction handleDecorationClickEvent(event, clickEvent) {\n if (groups.size === 0) {\n return false;\n }\n\n function findTarget() {\n var _iterator = decorator_createForOfIteratorHelper(groups),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = decorator_slicedToArray(_step.value, 2),\n group = _step$value[0],\n groupContent = _step$value[1];\n\n var _iterator2 = decorator_createForOfIteratorHelper(groupContent.items.reverse()),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var item = _step2.value;\n\n if (!item.clickableElements) {\n continue;\n }\n\n var _iterator3 = decorator_createForOfIteratorHelper(item.clickableElements),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var element = _step3.value;\n var rect = element.getBoundingClientRect().toJSON();\n\n if (rectContainsPoint(rect, event.clientX, event.clientY, 1)) {\n return {\n group: group,\n item: item,\n element: element,\n rect: rect\n };\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var target = findTarget();\n\n if (!target) {\n return false;\n }\n\n return Android.onDecorationActivated(JSON.stringify({\n id: target.item.decoration.id,\n group: target.group,\n rect: toNativeRect(target.item.range.getBoundingClientRect()),\n click: clickEvent\n }));\n}\n/**\n * Creates a DecorationGroup object from a unique HTML ID and its name.\n */\n\nfunction DecorationGroup(groupId, groupName) {\n var items = [];\n var lastItemId = 0;\n var container = null;\n /**\n * Adds a new decoration to the group.\n */\n\n function add(decoration) {\n var id = groupId + "-" + lastItemId++;\n var range = rangeFromLocator(decoration.locator);\n\n if (!range) {\n log("Can\'t locate DOM range for decoration", decoration);\n return;\n }\n\n var item = {\n id: id,\n decoration: decoration,\n range: range\n };\n items.push(item);\n layout(item);\n }\n /**\n * Removes the decoration with given ID from the group.\n */\n\n\n function remove(decorationId) {\n var index = items.findIndex(function (i) {\n return i.decoration.id === decorationId;\n });\n\n if (index === -1) {\n return;\n }\n\n var item = items[index];\n items.splice(index, 1);\n item.clickableElements = null;\n\n if (item.container) {\n item.container.remove();\n item.container = null;\n }\n }\n /**\n * Notifies that the given decoration was modified and needs to be updated.\n */\n\n\n function update(decoration) {\n remove(decoration.id);\n add(decoration);\n }\n /**\n * Removes all decorations from this group.\n */\n\n\n function clear() {\n clearContainer();\n items.length = 0;\n }\n /**\n * Recreates the decoration elements.\n *\n * To be called after reflowing the resource, for example.\n */\n\n\n function requestLayout() {\n clearContainer();\n items.forEach(function (item) {\n return layout(item);\n });\n }\n /**\n * Layouts a single Decoration item.\n */\n\n\n function layout(item) {\n var groupContainer = requireContainer();\n var style = styles.get(item.decoration.style);\n\n if (!style) {\n logError("Unknown decoration style: ".concat(item.decoration.style));\n return;\n }\n\n var itemContainer = document.createElement("div");\n itemContainer.setAttribute("id", item.id);\n itemContainer.setAttribute("data-style", item.decoration.style);\n itemContainer.style.setProperty("pointer-events", "none");\n var viewportWidth = window.innerWidth;\n var columnCount = parseInt(getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n var pageWidth = viewportWidth / (columnCount || 1);\n var scrollingElement = document.scrollingElement;\n var xOffset = scrollingElement.scrollLeft;\n var yOffset = scrollingElement.scrollTop;\n\n function positionElement(element, rect, boundingRect) {\n element.style.position = "absolute";\n\n if (style.width === "wrap") {\n element.style.width = "".concat(rect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(rect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "viewport") {\n element.style.width = "".concat(viewportWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n var left = Math.floor(rect.left / viewportWidth) * viewportWidth;\n element.style.left = "".concat(left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "bounds") {\n element.style.width = "".concat(boundingRect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(boundingRect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "page") {\n element.style.width = "".concat(pageWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n\n var _left = Math.floor(rect.left / pageWidth) * pageWidth;\n\n element.style.left = "".concat(_left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n }\n }\n\n var boundingRect = item.range.getBoundingClientRect();\n var elementTemplate;\n\n try {\n var template = document.createElement("template");\n template.innerHTML = item.decoration.element.trim();\n elementTemplate = template.content.firstElementChild;\n } catch (error) {\n logError("Invalid decoration element \\"".concat(item.decoration.element, "\\": ").concat(error.message));\n return;\n }\n\n if (style.layout === "boxes") {\n var doNotMergeHorizontallyAlignedRects = true;\n var clientRects = getClientRectsNoOverlap(item.range, doNotMergeHorizontallyAlignedRects);\n clientRects = clientRects.sort(function (r1, r2) {\n if (r1.top < r2.top) {\n return -1;\n } else if (r1.top > r2.top) {\n return 1;\n } else {\n return 0;\n }\n });\n\n var _iterator4 = decorator_createForOfIteratorHelper(clientRects),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var clientRect = _step4.value;\n var line = elementTemplate.cloneNode(true);\n line.style.setProperty("pointer-events", "none");\n positionElement(line, clientRect, boundingRect);\n itemContainer.append(line);\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n } else if (style.layout === "bounds") {\n var bounds = elementTemplate.cloneNode(true);\n bounds.style.setProperty("pointer-events", "none");\n positionElement(bounds, boundingRect, boundingRect);\n itemContainer.append(bounds);\n }\n\n groupContainer.append(itemContainer);\n item.container = itemContainer;\n item.clickableElements = Array.from(itemContainer.querySelectorAll("[data-activable=\'1\']"));\n\n if (item.clickableElements.length === 0) {\n item.clickableElements = Array.from(itemContainer.children);\n }\n }\n /**\n * Returns the group container element, after making sure it exists.\n */\n\n\n function requireContainer() {\n if (!container) {\n container = document.createElement("div");\n container.setAttribute("id", groupId);\n container.setAttribute("data-group", groupName);\n container.style.setProperty("pointer-events", "none");\n document.body.append(container);\n }\n\n return container;\n }\n /**\n * Removes the group container.\n */\n\n\n function clearContainer() {\n if (container) {\n container.remove();\n container = null;\n }\n }\n\n return {\n add: add,\n remove: remove,\n update: update,\n clear: clear,\n items: items,\n requestLayout: requestLayout\n };\n}\nwindow.addEventListener("load", function () {\n // Will relayout all the decorations when the document body is resized.\n var body = document.body;\n var lastSize = {\n width: 0,\n height: 0\n };\n var observer = new ResizeObserver(function () {\n if (lastSize.width === body.clientWidth && lastSize.height === body.clientHeight) {\n return;\n }\n\n lastSize = {\n width: body.clientWidth,\n height: body.clientHeight\n };\n groups.forEach(function (group) {\n group.requestLayout();\n });\n });\n observer.observe(body);\n}, false);\n// EXTERNAL MODULE: ./node_modules/css-selector-generator/build/index.js\nvar build = __webpack_require__(4766);\n;// CONCATENATED MODULE: ./src/dom.js\n//\n// Copyright 2022 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n // See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling\n\nfunction nearestInteractiveElement(element) {\n if (element == null) {\n return null;\n }\n\n var interactiveTags = ["a", "audio", "button", "canvas", "details", "input", "label", "option", "select", "submit", "textarea", "video"];\n\n if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) {\n return element.outerHTML;\n } // Checks whether the element is editable by the user.\n\n\n if (element.hasAttribute("contenteditable") && element.getAttribute("contenteditable").toLowerCase() != "false") {\n return element.outerHTML;\n } // Checks parents recursively because the touch might be for example on an inside a .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n}\n;// CONCATENATED MODULE: ./src/keyboard.js\n//\n// Copyright 2023 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nwindow.addEventListener("keydown", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "down");\n});\nwindow.addEventListener("keyup", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "up");\n});\n\nfunction shouldIgnoreEvent(event) {\n return event.defaultPrevented || nearestInteractiveElement(document.activeElement) != null;\n} // We prevent the default behavior for keyboard events, otherwise the web view\n// might scroll.\n\n\nfunction preventDefault(event) {\n event.stopPropagation();\n event.preventDefault();\n}\n\nfunction sendPressKeyMessage(event, type) {\n if (event.repeat) return;\n var keyEvent = {\n type: type,\n code: event.code,\n characters: String.fromCharCode(event.keyCode),\n alt: event.altKey,\n control: event.ctrlKey,\n shift: event.shiftKey,\n meta: event.metaKey\n };\n Android.onKey(JSON.stringify(keyEvent));\n}\n;// CONCATENATED MODULE: ./src/highlight.js\nfunction highlight_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { highlight_typeof = function _typeof(obj) { return typeof obj; }; } else { highlight_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return highlight_typeof(obj); }\n\nfunction highlight_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = highlight_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction highlight_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return highlight_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return highlight_arrayLikeToArray(o, minLen); }\n\nfunction highlight_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/* eslint-disable */\n//\n// highlight.js\n// r2-navigator-kotlin\n//\n// Organized by Taehyun Kim on 6/27/19 from r2-navigator-js.\n//\n// Copyright 2019 Readium Foundation. All rights reserved.\n// Use of this source code is governed by a BSD-style license which is detailed\n// in the LICENSE file present in the project repository where this source code is maintained.\n//\nvar ROOT_CLASS_REDUCE_MOTION = "r2-reduce-motion";\nvar ROOT_CLASS_NO_FOOTNOTES = "r2-no-popup-foonotes";\nvar POPUP_DIALOG_CLASS = "r2-popup-dialog";\nvar FOOTNOTES_CONTAINER_CLASS = "r2-footnote-container";\nvar FOOTNOTES_CLOSE_BUTTON_CLASS = "r2-footnote-close";\nvar FOOTNOTE_FORCE_SHOW = "r2-footnote-force-show";\nvar TTS_ID_PREVIOUS = "r2-tts-previous";\nvar TTS_ID_NEXT = "r2-tts-next";\nvar TTS_ID_SLIDER = "r2-tts-slider";\nvar TTS_ID_ACTIVE_WORD = "r2-tts-active-word";\nvar TTS_ID_CONTAINER = "r2-tts-txt";\nvar TTS_ID_INFO = "r2-tts-info";\nvar TTS_NAV_BUTTON_CLASS = "r2-tts-button";\nvar TTS_ID_SPEAKING_DOC_ELEMENT = "r2-tts-speaking-el";\nvar TTS_CLASS_INJECTED_SPAN = "r2-tts-speaking-txt";\nvar TTS_CLASS_INJECTED_SUBSPAN = "r2-tts-speaking-word";\nvar TTS_ID_INJECTED_PARENT = "r2-tts-speaking-txt-parent";\nvar ID_HIGHLIGHTS_CONTAINER = "R2_ID_HIGHLIGHTS_CONTAINER";\nvar ID_ANNOTATION_CONTAINER = "R2_ID_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_CONTAINER = "R2_CLASS_HIGHLIGHT_CONTAINER";\nvar CLASS_ANNOTATION_CONTAINER = "R2_CLASS_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_AREA = "R2_CLASS_HIGHLIGHT_AREA";\nvar CLASS_ANNOTATION_AREA = "R2_CLASS_ANNOTATION_AREA";\nvar CLASS_HIGHLIGHT_BOUNDING_AREA = "R2_CLASS_HIGHLIGHT_BOUNDING_AREA";\nvar CLASS_ANNOTATION_BOUNDING_AREA = "R2_CLASS_ANNOTATION_BOUNDING_AREA"; // tslint:disable-next-line:max-line-length\n\nvar _blacklistIdClassForCFI = [POPUP_DIALOG_CLASS, TTS_CLASS_INJECTED_SPAN, TTS_CLASS_INJECTED_SUBSPAN, ID_HIGHLIGHTS_CONTAINER, CLASS_HIGHLIGHT_CONTAINER, CLASS_HIGHLIGHT_AREA, CLASS_HIGHLIGHT_BOUNDING_AREA, "resize-sensor"];\nvar CLASS_PAGINATED = "r2-css-paginated"; //const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");\n\nvar IS_DEV = false;\nvar _highlights = [];\n\nvar _highlightsContainer;\n\nvar _annotationContainer;\n\nvar lastMouseDownX = -1;\nvar lastMouseDownY = -1;\nvar bodyEventListenersSet = false;\nvar USE_SVG = false;\nvar DEFAULT_BACKGROUND_COLOR_OPACITY = 0.3;\nvar ALT_BACKGROUND_COLOR_OPACITY = 0.45; //const DEBUG_VISUALS = false;\n\nvar DEBUG_VISUALS = false;\nvar DEFAULT_BACKGROUND_COLOR = {\n blue: 100,\n green: 50,\n red: 230\n};\nvar ANNOTATION_WIDTH = 15;\n\nfunction resetHighlightBoundingStyle(_win, highlightBounding) {\n if (highlightBounding.getAttribute("class") == CLASS_ANNOTATION_BOUNDING_AREA) {\n return;\n }\n\n highlightBounding.style.outline = "none";\n highlightBounding.style.setProperty("background-color", "transparent", "important");\n}\n\nfunction setHighlightAreaStyle(win, highlightAreas, highlight) {\n var useSVG = !DEBUG_VISUALS && USE_SVG;\n\n var _iterator = highlight_createForOfIteratorHelper(highlightAreas),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var highlightArea = _step.value;\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var opacity = ALT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n}\n\nfunction resetHighlightAreaStyle(win, highlightArea) {\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var id = isSVG ? highlightArea.parentNode && highlightArea.parentNode.parentNode && highlightArea.parentNode.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.parentNode.getAttribute ? highlightArea.parentNode.parentNode.getAttribute("id") : undefined : highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.getAttribute ? highlightArea.parentNode.getAttribute("id") : undefined;\n\n if (id) {\n var highlight = _highlights.find(function (h) {\n return h.id === id;\n });\n\n if (highlight) {\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n }\n}\n\nfunction processTouchEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.changedTouches[0].clientX;\n var y = ev.changedTouches[0].clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect; // _highlights.sort(function(a, b) {\n // console.log(JSON.stringify(a.selectionInfo))\n // return a.selectionInfo.cleanText.length < b.selectionInfo.cleanText.length\n // })\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator2 = highlight_createForOfIteratorHelper(highlightFragments),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var highlightFragment = _step2.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator3 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var highlightBounding = _step3.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i = 0, _allHighlightAreas = allHighlightAreas; _i < _allHighlightAreas.length; _i++) {\n var highlightArea = _allHighlightAreas[_i];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas2 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator4 = highlight_createForOfIteratorHelper(_allHighlightAreas2),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var _highlightArea = _step4.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea) < 0) {\n resetHighlightAreaStyle(win, _highlightArea);\n }\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator5 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step5;\n\n try {\n for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {\n var _highlightBounding = _step5.value;\n\n if (!foundElementHighlightBounding || _highlightBounding !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding);\n }\n }\n } catch (err) {\n _iterator5.e(err);\n } finally {\n _iterator5.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "touchstart" || ev.type === "touchend") {\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight.id,\n size: size\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n console.log(foundHighlight.id.includes("R2_ANNOTATION_"));\n\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n}\n\nfunction processMouseEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.clientX;\n var y = ev.clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect;\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator6 = highlight_createForOfIteratorHelper(highlightFragments),\n _step6;\n\n try {\n for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {\n var highlightFragment = _step6.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator6.e(err);\n } finally {\n _iterator6.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator7 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step7;\n\n try {\n for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {\n var highlightBounding = _step7.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator7.e(err);\n } finally {\n _iterator7.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i2 = 0, _allHighlightAreas3 = allHighlightAreas; _i2 < _allHighlightAreas3.length; _i2++) {\n var highlightArea = _allHighlightAreas3[_i2];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas4 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator8 = highlight_createForOfIteratorHelper(_allHighlightAreas4),\n _step8;\n\n try {\n for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {\n var _highlightArea2 = _step8.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea2) < 0) {\n resetHighlightAreaStyle(win, _highlightArea2);\n }\n }\n } catch (err) {\n _iterator8.e(err);\n } finally {\n _iterator8.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator9 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step9;\n\n try {\n for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {\n var _highlightBounding2 = _step9.value;\n\n if (!foundElementHighlightBounding || _highlightBounding2 !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding2);\n }\n }\n } catch (err) {\n _iterator9.e(err);\n } finally {\n _iterator9.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "mouseup" || ev.type === "touchend") {\n var touchedPosition = {\n screenWidth: window.outerWidth,\n screenHeight: window.innerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight,\n position: touchedPosition\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n }\n }\n}\n\nfunction highlight_rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && highlight_almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && highlight_almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && highlight_almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && highlight_almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction highlight_replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("replaceOverlapingRects rect1 === rect2 ??!");\n }\n\n continue;\n }\n\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret = function () {\n var toAdd = [];\n var toRemove = void 0;\n var toPreserve = void 0;\n var subtractRects1 = highlight_rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n var subtractRects2 = highlight_rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n toPreserve = rect1;\n }\n }\n\n if (IS_DEV) {\n var toCheck = [];\n toCheck.push(toPreserve);\n Array.prototype.push.apply(toCheck, toAdd);\n checkOverlaps(toCheck);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: highlight_replaceOverlapingRects(newRects)\n };\n }();\n\n if (highlight_typeof(_ret) === "object") return _ret.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction checkOverlaps(rects) {\n var stillOverlapingRects = [];\n\n var _iterator10 = highlight_createForOfIteratorHelper(rects),\n _step10;\n\n try {\n for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {\n var rect1 = _step10.value;\n\n var _iterator11 = highlight_createForOfIteratorHelper(rects),\n _step11;\n\n try {\n for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {\n var rect2 = _step11.value;\n\n if (rect1 === rect2) {\n continue;\n }\n\n var has1 = stillOverlapingRects.indexOf(rect1) >= 0;\n var has2 = stillOverlapingRects.indexOf(rect2) >= 0;\n\n if (!has1 || !has2) {\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n if (!has1) {\n stillOverlapingRects.push(rect1);\n }\n\n if (!has2) {\n stillOverlapingRects.push(rect2);\n }\n\n console.log("CLIENT RECT: overlap ---");\n console.log("#1 TOP:".concat(rect1.top, " BOTTOM:").concat(rect1.bottom, " LEFT:").concat(rect1.left, " RIGHT:").concat(rect1.right, " WIDTH:").concat(rect1.width, " HEIGHT:").concat(rect1.height));\n console.log("#2 TOP:".concat(rect2.top, " BOTTOM:").concat(rect2.bottom, " LEFT:").concat(rect2.left, " RIGHT:").concat(rect2.right, " WIDTH:").concat(rect2.width, " HEIGHT:").concat(rect2.height));\n var xOverlap = getRectOverlapX(rect1, rect2);\n console.log("xOverlap: ".concat(xOverlap));\n var yOverlap = getRectOverlapY(rect1, rect2);\n console.log("yOverlap: ".concat(yOverlap));\n }\n }\n }\n } catch (err) {\n _iterator11.e(err);\n } finally {\n _iterator11.f();\n }\n }\n } catch (err) {\n _iterator10.e(err);\n } finally {\n _iterator10.f();\n }\n\n if (stillOverlapingRects.length) {\n console.log("CLIENT RECT: overlaps ".concat(stillOverlapingRects.length));\n }\n}\n\nfunction highlight_removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator12 = highlight_createForOfIteratorHelper(rects),\n _step12;\n\n try {\n for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {\n var rect = _step12.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove tiny");\n }\n\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator13 = highlight_createForOfIteratorHelper(rects),\n _step13;\n\n try {\n for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {\n var possiblyContainingRect = _step13.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (highlight_rectContains(possiblyContainingRect, rect, tolerance)) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove contained");\n }\n\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator13.e(err);\n } finally {\n _iterator13.f();\n }\n }\n } catch (err) {\n _iterator12.e(err);\n } finally {\n _iterator12.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction highlight_almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction highlight_rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n var rect = {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n return rect;\n}\n\nfunction highlight_rectSubtract(rect1, rect2) {\n var rectIntersected = highlight_rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction highlight_rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || highlight_almostEqual(rect.left, x, tolerance)) && (rect.right > x || highlight_almostEqual(rect.right, x, tolerance)) && (rect.top < y || highlight_almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || highlight_almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction highlight_rectContains(rect1, rect2, tolerance) {\n return highlight_rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction highlight_getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction highlight_mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("mergeTouchingRects rect1 === rect2 ??!");\n }\n\n return "continue";\n }\n\n var rectsLineUpVertically = highlight_almostEqual(rect1.top, rect2.top, tolerance) && highlight_almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = highlight_almostEqual(rect1.left, rect2.left, tolerance) && highlight_almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && highlight_rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n if (IS_DEV) {\n console.log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = highlight_getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: highlight_mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret2 = _loop(j);\n\n if (_ret2 === "continue") continue;\n if (highlight_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n\n return rects;\n}\n\nfunction highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var rangeClientRects = range.getClientRects();\n return getClientRectsNoOverlap_(rangeClientRects, doNotMergeHorizontallyAlignedRects);\n}\n\nfunction getClientRectsNoOverlap_(clientRects, doNotMergeHorizontallyAlignedRects) {\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator14 = highlight_createForOfIteratorHelper(clientRects),\n _step14;\n\n try {\n for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {\n var rangeClientRect = _step14.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator14.e(err);\n } finally {\n _iterator14.f();\n }\n\n var mergedRects = highlight_mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = highlight_removeContainedRects(mergedRects, tolerance);\n var newRects = highlight_replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small");\n }\n\n newRects.splice(j, 1);\n } else {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small, but keep otherwise empty!");\n }\n\n break;\n }\n }\n }\n\n if (IS_DEV) {\n checkOverlaps(newRects);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n }\n\n return newRects;\n}\n\nfunction isPaginated(document) {\n return document && document.documentElement && document.documentElement.classList.contains(CLASS_PAGINATED);\n}\n\nfunction getScrollingElement(document) {\n if (document.scrollingElement) {\n return document.scrollingElement;\n }\n\n return document.body;\n}\n\nfunction ensureContainer(win, annotationFlag) {\n var document = win.document;\n\n if (!_highlightsContainer) {\n if (!bodyEventListenersSet) {\n bodyEventListenersSet = true;\n document.body.addEventListener("mousedown", function (ev) {\n lastMouseDownX = ev.clientX;\n lastMouseDownY = ev.clientY;\n }, false);\n document.body.addEventListener("mouseup", function (ev) {\n if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {\n processMouseEvent(win, ev);\n }\n }, false);\n document.body.addEventListener("mousemove", function (ev) {\n processMouseEvent(win, ev);\n }, false);\n document.body.addEventListener("touchend", function touchEnd(e) {\n processTouchEvent(win, e);\n }, false);\n }\n\n _highlightsContainer = document.createElement("div");\n\n _highlightsContainer.setAttribute("id", ID_HIGHLIGHTS_CONTAINER);\n\n _highlightsContainer.style.setProperty("pointer-events", "none");\n\n document.body.append(_highlightsContainer);\n }\n\n return _highlightsContainer;\n}\n\nfunction hideAllhighlights() {\n if (_highlightsContainer) {\n _highlightsContainer.remove();\n\n _highlightsContainer = null;\n }\n}\n\nfunction destroyAllhighlights() {\n hideAllhighlights();\n\n _highlights.splice(0, _highlights.length);\n}\n\nfunction destroyHighlight(id) {\n var i = -1;\n var _document = window.document;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (highlight && i >= 0 && i < _highlights.length) {\n _highlights.splice(i, 1);\n }\n\n var highlightContainer = _document.getElementById(id);\n\n if (highlightContainer) {\n highlightContainer.remove();\n }\n}\n\nfunction isCfiTextNode(node) {\n return node.nodeType !== Node.ELEMENT_NODE;\n}\n\nfunction getChildTextNodeCfiIndex(element, child) {\n var found = -1;\n var textNodeIndex = -1;\n var previousWasElement = false;\n\n for (var i = 0; i < element.childNodes.length; i++) {\n var childNode = element.childNodes[i];\n var isText = isCfiTextNode(childNode);\n\n if (isText || previousWasElement) {\n textNodeIndex += 2;\n }\n\n if (isText) {\n if (childNode === child) {\n found = textNodeIndex;\n break;\n }\n }\n\n previousWasElement = childNode.nodeType === Node.ELEMENT_NODE;\n }\n\n return found;\n}\n\nfunction getCommonAncestorElement(node1, node2) {\n if (node1.nodeType === Node.ELEMENT_NODE && node1 === node2) {\n return node1;\n }\n\n if (node1.nodeType === Node.ELEMENT_NODE && node1.contains(node2)) {\n return node1;\n }\n\n if (node2.nodeType === Node.ELEMENT_NODE && node2.contains(node1)) {\n return node2;\n }\n\n var node1ElementAncestorChain = [];\n var parent = node1.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node1ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var node2ElementAncestorChain = [];\n parent = node2.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node2ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var commonAncestor = node1ElementAncestorChain.find(function (node1ElementAncestor) {\n return node2ElementAncestorChain.indexOf(node1ElementAncestor) >= 0;\n });\n\n if (!commonAncestor) {\n commonAncestor = node2ElementAncestorChain.find(function (node2ElementAncestor) {\n return node1ElementAncestorChain.indexOf(node2ElementAncestor) >= 0;\n });\n }\n\n return commonAncestor;\n}\n\nfunction fullQualifiedSelector(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n return lowerCaseName;\n } //return cssPath(node, justSelector);\n\n\n return cssPath(node, true);\n}\n\nfunction getCurrentSelectionInfo() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n console.log("^^^ SELECTION COLLAPSED.");\n return undefined;\n }\n\n var rawText = selection.toString();\n var cleanText = rawText.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanText.length === 0) {\n console.log("^^^ SELECTION TEXT EMPTY.");\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n console.log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var rangeInfo = convertRange(range, fullQualifiedSelector, computeCFI);\n\n if (!rangeInfo) {\n console.log("^^^ SELECTION RANGE INFO FAIL?!");\n return undefined;\n }\n\n if (IS_DEV && DEBUG_VISUALS) {\n var restoredRange = convertRangeInfo(win.document, rangeInfo);\n\n if (restoredRange) {\n if (restoredRange.startOffset === range.startOffset && restoredRange.endOffset === range.endOffset && restoredRange.startContainer === range.startContainer && restoredRange.endContainer === range.endContainer) {\n console.log("SELECTION RANGE RESTORED OKAY (dev check).");\n } else {\n console.log("SELECTION RANGE RESTORE FAIL (dev check).");\n dumpDebug("SELECTION", selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset, getCssSelector);\n dumpDebug("ORDERED RANGE FROM SELECTION", range.startContainer, range.startOffset, range.endContainer, range.endOffset, getCssSelector);\n dumpDebug("RESTORED RANGE", restoredRange.startContainer, restoredRange.startOffset, restoredRange.endContainer, restoredRange.endOffset, getCssSelector);\n }\n } else {\n console.log("CANNOT RESTORE SELECTION RANGE ??!");\n }\n } else {}\n\n return {\n locations: rangeInfo2Location(rangeInfo),\n text: {\n highlight: rawText\n }\n };\n}\n\nfunction checkBlacklisted(el) {\n var blacklistedId;\n var id = el.getAttribute("id");\n\n if (id && _blacklistIdClassForCFI.indexOf(id) >= 0) {\n console.log("checkBlacklisted ID: " + id);\n blacklistedId = id;\n }\n\n var blacklistedClass;\n\n var _iterator15 = highlight_createForOfIteratorHelper(_blacklistIdClassForCFI),\n _step15;\n\n try {\n for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {\n var item = _step15.value;\n\n if (el.classList.contains(item)) {\n console.log("checkBlacklisted CLASS: " + item);\n blacklistedClass = item;\n break;\n }\n }\n } catch (err) {\n _iterator15.e(err);\n } finally {\n _iterator15.f();\n }\n\n if (blacklistedId || blacklistedClass) {\n return true;\n }\n\n return false;\n}\n\nfunction cssPath(node, optimized) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return "";\n }\n\n var steps = [];\n var contextNode = node;\n\n while (contextNode) {\n var step = _cssPathStep(contextNode, !!optimized, contextNode === node);\n\n if (!step) {\n break; // Error - bail out early.\n }\n\n steps.push(step.value);\n\n if (step.optimized) {\n break;\n }\n\n contextNode = contextNode.parentNode;\n }\n\n steps.reverse();\n return steps.join(" > ");\n} // tslint:disable-next-line:max-line-length\n// https://chromium.googlesource.com/chromium/blink/+/master/Source/devtools/front_end/components/DOMPresentationUtils.js#316\n\n\nfunction _cssPathStep(node, optimized, isTargetNode) {\n function prefixedElementClassNames(nd) {\n var classAttribute = nd.getAttribute("class");\n\n if (!classAttribute) {\n return [];\n }\n\n return classAttribute.split(/\\s+/g).filter(Boolean).map(function (nm) {\n // The prefix is required to store "__proto__" in a object-based map.\n return "$" + nm;\n });\n }\n\n function idSelector(idd) {\n return "#" + escapeIdentifierIfNeeded(idd);\n }\n\n function escapeIdentifierIfNeeded(ident) {\n if (isCSSIdentifier(ident)) {\n return ident;\n }\n\n var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);\n var lastIndex = ident.length - 1;\n return ident.replace(/./g, function (c, ii) {\n return shouldEscapeFirst && ii === 0 || !isCSSIdentChar(c) ? escapeAsciiChar(c, ii === lastIndex) : c;\n });\n }\n\n function escapeAsciiChar(c, isLast) {\n return "\\\\" + toHexByte(c) + (isLast ? "" : " ");\n }\n\n function toHexByte(c) {\n var hexByte = c.charCodeAt(0).toString(16);\n\n if (hexByte.length === 1) {\n hexByte = "0" + hexByte;\n }\n\n return hexByte;\n }\n\n function isCSSIdentChar(c) {\n if (/[a-zA-Z0-9_-]/.test(c)) {\n return true;\n }\n\n return c.charCodeAt(0) >= 0xa0;\n }\n\n function isCSSIdentifier(value) {\n return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n var element = node;\n var id = element.getAttribute("id");\n\n if (optimized) {\n if (id) {\n return {\n optimized: true,\n value: idSelector(id)\n };\n }\n\n if (lowerCaseName === "body" || lowerCaseName === "head" || lowerCaseName === "html") {\n return {\n optimized: true,\n value: lowerCaseName // node.nodeNameInCorrectCase(),\n\n };\n }\n }\n\n var nodeName = lowerCaseName; // node.nodeNameInCorrectCase();\n\n if (id) {\n return {\n optimized: true,\n value: nodeName + idSelector(id)\n };\n }\n\n var parent = node.parentNode;\n\n if (!parent || parent.nodeType === Node.DOCUMENT_NODE) {\n return {\n optimized: true,\n value: nodeName\n };\n }\n\n var prefixedOwnClassNamesArray_ = prefixedElementClassNames(element);\n var prefixedOwnClassNamesArray = []; // .keySet()\n\n prefixedOwnClassNamesArray_.forEach(function (arrItem) {\n if (prefixedOwnClassNamesArray.indexOf(arrItem) < 0) {\n prefixedOwnClassNamesArray.push(arrItem);\n }\n });\n var needsClassNames = false;\n var needsNthChild = false;\n var ownIndex = -1;\n var elementIndex = -1;\n var siblings = parent.children;\n\n var _loop2 = function _loop2(i) {\n var sibling = siblings[i];\n\n if (sibling.nodeType !== Node.ELEMENT_NODE) {\n return "continue";\n }\n\n elementIndex += 1;\n\n if (sibling === node) {\n ownIndex = elementIndex;\n return "continue";\n }\n\n if (needsNthChild) {\n return "continue";\n } // sibling.nodeNameInCorrectCase()\n\n\n var siblingName = sibling.localName && sibling.localName.toLowerCase() || sibling.nodeName.toLowerCase();\n\n if (siblingName !== nodeName) {\n return "continue";\n }\n\n needsClassNames = true;\n var ownClassNames = [];\n prefixedOwnClassNamesArray.forEach(function (arrItem) {\n ownClassNames.push(arrItem);\n });\n var ownClassNameCount = ownClassNames.length;\n\n if (ownClassNameCount === 0) {\n needsNthChild = true;\n return "continue";\n }\n\n var siblingClassNamesArray_ = prefixedElementClassNames(sibling);\n var siblingClassNamesArray = []; // .keySet()\n\n siblingClassNamesArray_.forEach(function (arrItem) {\n if (siblingClassNamesArray.indexOf(arrItem) < 0) {\n siblingClassNamesArray.push(arrItem);\n }\n });\n\n for (var _i3 = 0, _siblingClassNamesArr = siblingClassNamesArray; _i3 < _siblingClassNamesArr.length; _i3++) {\n var siblingClass = _siblingClassNamesArr[_i3];\n var ind = ownClassNames.indexOf(siblingClass);\n\n if (ind < 0) {\n continue;\n }\n\n ownClassNames.splice(ind, 1); // delete ownClassNames[siblingClass];\n\n if (! --ownClassNameCount) {\n needsNthChild = true;\n break;\n }\n }\n };\n\n for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {\n var _ret3 = _loop2(i);\n\n if (_ret3 === "continue") continue;\n }\n\n var result = nodeName;\n\n if (isTargetNode && nodeName === "input" && element.getAttribute("type") && !element.getAttribute("id") && !element.getAttribute("class")) {\n result += \'[type="\' + element.getAttribute("type") + \'"]\';\n }\n\n if (needsNthChild) {\n result += ":nth-child(" + (ownIndex + 1) + ")";\n } else if (needsClassNames) {\n var _iterator16 = highlight_createForOfIteratorHelper(prefixedOwnClassNamesArray),\n _step16;\n\n try {\n for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {\n var prefixedName = _step16.value;\n result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));\n }\n } catch (err) {\n _iterator16.e(err);\n } finally {\n _iterator16.f();\n }\n }\n\n return {\n optimized: false,\n value: result\n };\n}\n\nfunction computeCFI(node) {\n // TODO: handle character position inside text node\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var cfi = "";\n var currentElement = node;\n\n while (currentElement.parentNode && currentElement.parentNode.nodeType === Node.ELEMENT_NODE) {\n var blacklisted = checkBlacklisted(currentElement);\n\n if (!blacklisted) {\n var currentElementParentChildren = currentElement.parentNode.children;\n var currentElementIndex = -1;\n\n for (var i = 0; i < currentElementParentChildren.length; i++) {\n if (currentElement === currentElementParentChildren[i]) {\n currentElementIndex = i;\n break;\n }\n }\n\n if (currentElementIndex >= 0) {\n var cfiIndex = (currentElementIndex + 1) * 2;\n cfi = cfiIndex + (currentElement.id ? "[" + currentElement.id + "]" : "") + (cfi.length ? "/" + cfi : "");\n }\n }\n\n currentElement = currentElement.parentNode;\n }\n\n return "/" + cfi;\n}\n\nfunction _createHighlight(locations, color, pointerInteraction, type) {\n var rangeInfo = location2RangeInfo(locations);\n var uniqueStr = "".concat(rangeInfo.cfi).concat(rangeInfo.startContainerElementCssSelector).concat(rangeInfo.startContainerChildTextNodeIndex).concat(rangeInfo.startOffset).concat(rangeInfo.endContainerElementCssSelector).concat(rangeInfo.endContainerChildTextNodeIndex).concat(rangeInfo.endOffset);\n\n var hash = __webpack_require__(3715);\n\n var sha256Hex = hash.sha256().update(uniqueStr).digest("hex");\n var id;\n\n if (type == ID_HIGHLIGHTS_CONTAINER) {\n id = "R2_HIGHLIGHT_" + sha256Hex;\n } else {\n id = "R2_ANNOTATION_" + sha256Hex;\n }\n\n destroyHighlight(id);\n var highlight = {\n color: color ? color : DEFAULT_BACKGROUND_COLOR,\n id: id,\n pointerInteraction: pointerInteraction,\n rangeInfo: rangeInfo\n };\n\n _highlights.push(highlight);\n\n createHighlightDom(window, highlight, type == ID_ANNOTATION_CONTAINER ? true : false);\n return highlight;\n}\n\nfunction createHighlight(selectionInfo, color, pointerInteraction) {\n return _createHighlight(selectionInfo, color, pointerInteraction, ID_HIGHLIGHTS_CONTAINER);\n}\nfunction createAnnotation(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (i == _highlights.length) return;\n var locations = {\n locations: rangeInfo2Location(highlight.rangeInfo)\n };\n return _createHighlight(locations, highlight.color, true, ID_ANNOTATION_CONTAINER);\n}\n\nfunction createHighlightDom(win, highlight, annotationFlag) {\n var document = win.document;\n var scale = 1 / (win.READIUM2 && win.READIUM2.isFixedLayout ? win.READIUM2.fxlViewportScale : 1);\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var paginated = isPaginated(document);\n var highlightsContainer = ensureContainer(win, annotationFlag);\n var highlightParent = document.createElement("div");\n highlightParent.setAttribute("id", highlight.id);\n highlightParent.setAttribute("class", CLASS_HIGHLIGHT_CONTAINER);\n document.body.style.position = "relative";\n highlightParent.style.setProperty("pointer-events", "none");\n\n if (highlight.pointerInteraction) {\n highlightParent.setAttribute("data-click", "1");\n }\n\n var bodyRect = document.body.getBoundingClientRect();\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var highlightAreaSVGDocFrag;\n var roundedCorner = 3;\n var underlineThickness = 2;\n var strikeThroughLineThickness = 3;\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n var extra = "";\n var rangeAnnotationBoundingClientRect = frameForHighlightAnnotationMarkWithID(win, highlight.id);\n var xOffset;\n var yOffset;\n var annotationOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n annotationOffset = parseInt((rangeAnnotationBoundingClientRect.right - xOffset) / window.innerWidth) + 1;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n annotationOffset = parseInt(rangeAnnotationBoundingClientRect.right / window.innerWidth + 1);\n }\n\n var _iterator17 = highlight_createForOfIteratorHelper(clientRects),\n _step17;\n\n try {\n for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {\n var clientRect = _step17.value;\n\n if (useSVG) {\n var borderThickness = 0;\n\n if (!highlightAreaSVGDocFrag) {\n highlightAreaSVGDocFrag = document.createDocumentFragment();\n }\n\n var highlightAreaSVGRect = document.createElementNS(SVG_XML_NAMESPACE, "rect");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGRect.setAttribute("style", "fill: rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; fill-opacity: ").concat(opacity, " !important; stroke-width: 0;"));\n highlightAreaSVGRect.scale = scale;\n /*\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGRect.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaSVGRect.setAttribute("rx", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("ry", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("x", "".concat((highlightAreaSVGRect.rect.left - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("y", "".concat((highlightAreaSVGRect.rect.top - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("height", "".concat((highlightAreaSVGRect.rect.height + borderThickness * 2) * scale));\n highlightAreaSVGRect.setAttribute("width", "".concat((highlightAreaSVGRect.rect.width + borderThickness * 2) * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGRect);\n\n if (drawUnderline) {\n var highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGLine.setAttribute("style", "stroke-linecap: round; stroke-width: ".concat(underlineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n var lineOffset = highlightAreaSVGLine.rect.width > roundedCorner ? roundedCorner : 0;\n highlightAreaSVGLine.setAttribute("x1", "".concat((highlightAreaSVGLine.rect.left + lineOffset) * scale));\n highlightAreaSVGLine.setAttribute("x2", "".concat((highlightAreaSVGLine.rect.left + highlightAreaSVGLine.rect.width - lineOffset) * scale));\n var y = (highlightAreaSVGLine.rect.top + highlightAreaSVGLine.rect.height - underlineThickness / 2) * scale;\n highlightAreaSVGLine.setAttribute("y1", "".concat(y));\n highlightAreaSVGLine.setAttribute("y2", "".concat(y));\n highlightAreaSVGLine.setAttribute("height", "".concat(highlightAreaSVGLine.rect.height * scale));\n highlightAreaSVGLine.setAttribute("width", "".concat(highlightAreaSVGLine.rect.width * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGLine);\n }\n\n if (drawStrikeThrough) {\n var _highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n _highlightAreaSVGLine.setAttribute("style", "stroke-linecap: butt; stroke-width: ".concat(strikeThroughLineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n\n _highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n _highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n _highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n _highlightAreaSVGLine.setAttribute("x1", "".concat(_highlightAreaSVGLine.rect.left * scale));\n\n _highlightAreaSVGLine.setAttribute("x2", "".concat((_highlightAreaSVGLine.rect.left + _highlightAreaSVGLine.rect.width) * scale));\n\n var _lineOffset = _highlightAreaSVGLine.rect.height / 2;\n\n var _y = (_highlightAreaSVGLine.rect.top + _lineOffset) * scale;\n\n _highlightAreaSVGLine.setAttribute("y1", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("y2", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("height", "".concat(_highlightAreaSVGLine.rect.height * scale));\n\n _highlightAreaSVGLine.setAttribute("width", "".concat(_highlightAreaSVGLine.rect.width * scale));\n\n highlightAreaSVGDocFrag.appendChild(_highlightAreaSVGLine);\n }\n } else {\n var highlightArea = document.createElement("div");\n highlightArea.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n if (DEBUG_VISUALS) {\n var rgb = Math.round(0xffffff * Math.random());\n var r = rgb >> 16;\n var g = rgb >> 8 & 255;\n var b = rgb & 255;\n extra = "outline-color: rgb(".concat(r, ", ").concat(g, ", ").concat(b, "); outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n } else {\n if (drawUnderline) {\n extra += "border-bottom: ".concat(underlineThickness * scale, "px solid rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important");\n }\n }\n\n highlightArea.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n highlightArea.style.setProperty("pointer-events", "none");\n highlightArea.style.position = paginated ? "fixed" : "absolute";\n highlightArea.scale = scale;\n /*\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightArea.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightArea.style.width = "".concat(highlightArea.rect.width * scale, "px");\n highlightArea.style.height = "".concat(highlightArea.rect.height * scale, "px");\n highlightArea.style.left = "".concat(highlightArea.rect.left * scale, "px");\n highlightArea.style.top = "".concat(highlightArea.rect.top * scale, "px");\n highlightParent.append(highlightArea);\n\n if (!DEBUG_VISUALS && drawStrikeThrough) {\n //if (drawStrikeThrough) {\n var highlightAreaLine = document.createElement("div");\n highlightAreaLine.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaLine.setAttribute("style", "background-color: rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important;"));\n highlightAreaLine.style.setProperty("pointer-events", "none");\n highlightAreaLine.style.position = paginated ? "fixed" : "absolute";\n highlightAreaLine.scale = scale;\n /*\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaLine.style.width = "".concat(highlightAreaLine.rect.width * scale, "px");\n highlightAreaLine.style.height = "".concat(strikeThroughLineThickness * scale, "px");\n highlightAreaLine.style.left = "".concat(highlightAreaLine.rect.left * scale, "px");\n highlightAreaLine.style.top = "".concat((highlightAreaLine.rect.top + highlightAreaLine.rect.height / 2 - strikeThroughLineThickness / 2) * scale, "px");\n highlightParent.append(highlightAreaLine);\n }\n }\n\n if (annotationFlag) {\n break;\n }\n }\n } catch (err) {\n _iterator17.e(err);\n } finally {\n _iterator17.f();\n }\n\n if (useSVG && highlightAreaSVGDocFrag) {\n var highlightAreaSVG = document.createElementNS(SVG_XML_NAMESPACE, "svg");\n highlightAreaSVG.setAttribute("pointer-events", "none");\n highlightAreaSVG.style.position = paginated ? "fixed" : "absolute";\n highlightAreaSVG.style.overflow = "visible";\n highlightAreaSVG.style.left = "0";\n highlightAreaSVG.style.top = "0";\n highlightAreaSVG.append(highlightAreaSVGDocFrag);\n highlightParent.append(highlightAreaSVG);\n }\n\n var highlightBounding = document.createElement("div");\n\n if (annotationFlag) {\n highlightBounding.setAttribute("class", CLASS_ANNOTATION_BOUNDING_AREA);\n highlightBounding.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n } else {\n highlightBounding.setAttribute("class", CLASS_HIGHLIGHT_BOUNDING_AREA);\n }\n\n highlightBounding.style.setProperty("pointer-events", "none");\n highlightBounding.style.position = paginated ? "fixed" : "absolute";\n highlightBounding.scale = scale;\n\n if (DEBUG_VISUALS) {\n highlightBounding.setAttribute("style", "outline-color: magenta; outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n }\n\n if (annotationFlag) {\n highlightBounding.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n var rangeBoundingClientRect = range.getBoundingClientRect();\n highlightBounding.rect = {\n height: rangeBoundingClientRect.height,\n left: rangeBoundingClientRect.left - xOffset,\n top: rangeBoundingClientRect.top - yOffset,\n width: rangeBoundingClientRect.width\n };\n }\n\n highlightBounding.style.width = "".concat(highlightBounding.rect.width * scale, "px");\n highlightBounding.style.height = "".concat(highlightBounding.rect.height * scale, "px");\n highlightBounding.style.left = "".concat(highlightBounding.rect.left * scale, "px");\n highlightBounding.style.top = "".concat(highlightBounding.rect.top * scale, "px");\n highlightParent.append(highlightBounding);\n highlightsContainer.append(highlightParent);\n return highlightParent;\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n console.log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n console.log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n console.log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRange(range, getCssSelector, computeElementCFI) {\n var startIsElement = range.startContainer.nodeType === Node.ELEMENT_NODE;\n var startContainerElement = startIsElement ? range.startContainer : range.startContainer.parentNode && range.startContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.startContainer.parentNode : undefined;\n\n if (!startContainerElement) {\n return undefined;\n }\n\n var startContainerChildTextNodeIndex = startIsElement ? -1 : Array.from(startContainerElement.childNodes).indexOf(range.startContainer);\n\n if (startContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var startContainerElementCssSelector = getCssSelector(startContainerElement);\n var endIsElement = range.endContainer.nodeType === Node.ELEMENT_NODE;\n var endContainerElement = endIsElement ? range.endContainer : range.endContainer.parentNode && range.endContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.endContainer.parentNode : undefined;\n\n if (!endContainerElement) {\n return undefined;\n }\n\n var endContainerChildTextNodeIndex = endIsElement ? -1 : Array.from(endContainerElement.childNodes).indexOf(range.endContainer);\n\n if (endContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var endContainerElementCssSelector = getCssSelector(endContainerElement);\n var commonElementAncestor = getCommonAncestorElement(range.startContainer, range.endContainer);\n\n if (!commonElementAncestor) {\n console.log("^^^ NO RANGE COMMON ANCESTOR?!");\n return undefined;\n }\n\n if (range.commonAncestorContainer) {\n var rangeCommonAncestorElement = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? range.commonAncestorContainer : range.commonAncestorContainer.parentNode;\n\n if (rangeCommonAncestorElement && rangeCommonAncestorElement.nodeType === Node.ELEMENT_NODE) {\n if (commonElementAncestor !== rangeCommonAncestorElement) {\n console.log(">>>>>> COMMON ANCESTOR CONTAINER DIFF??!");\n console.log(getCssSelector(commonElementAncestor));\n console.log(getCssSelector(rangeCommonAncestorElement));\n }\n }\n }\n\n var rootElementCfi = computeElementCFI(commonElementAncestor);\n var startElementCfi = computeElementCFI(startContainerElement);\n var endElementCfi = computeElementCFI(endContainerElement);\n var cfi;\n\n if (rootElementCfi && startElementCfi && endElementCfi) {\n var startElementOrTextCfi = startElementCfi;\n\n if (!startIsElement) {\n var startContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(startContainerElement, range.startContainer);\n startElementOrTextCfi = startElementCfi + "/" + startContainerChildTextNodeIndexForCfi + ":" + range.startOffset;\n } else {\n if (range.startOffset >= 0 && range.startOffset < startContainerElement.childNodes.length) {\n var childNode = startContainerElement.childNodes[range.startOffset];\n\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (range.startOffset + 1) * 2;\n } else {\n var cfiTextNodeIndex = getChildTextNodeCfiIndex(startContainerElement, childNode);\n startElementOrTextCfi = startElementCfi + "/" + cfiTextNodeIndex;\n }\n } else {\n var cfiIndexOfLastElement = startContainerElement.childElementCount * 2;\n var lastChildNode = startContainerElement.childNodes[startContainerElement.childNodes.length - 1];\n\n if (lastChildNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 1);\n } else {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 2);\n }\n }\n }\n\n var endElementOrTextCfi = endElementCfi;\n\n if (!endIsElement) {\n var endContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(endContainerElement, range.endContainer);\n endElementOrTextCfi = endElementCfi + "/" + endContainerChildTextNodeIndexForCfi + ":" + range.endOffset;\n } else {\n if (range.endOffset >= 0 && range.endOffset < endContainerElement.childNodes.length) {\n var _childNode = endContainerElement.childNodes[range.endOffset];\n\n if (_childNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (range.endOffset + 1) * 2;\n } else {\n var _cfiTextNodeIndex = getChildTextNodeCfiIndex(endContainerElement, _childNode);\n\n endElementOrTextCfi = endElementCfi + "/" + _cfiTextNodeIndex;\n }\n } else {\n var _cfiIndexOfLastElement = endContainerElement.childElementCount * 2;\n\n var _lastChildNode = endContainerElement.childNodes[endContainerElement.childNodes.length - 1];\n\n if (_lastChildNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 1);\n } else {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 2);\n }\n }\n }\n\n cfi = rootElementCfi + "," + startElementOrTextCfi.replace(rootElementCfi, "") + "," + endElementOrTextCfi.replace(rootElementCfi, "");\n }\n\n return {\n cfi: cfi,\n endContainerChildTextNodeIndex: endContainerChildTextNodeIndex,\n endContainerElementCssSelector: endContainerElementCssSelector,\n endOffset: range.endOffset,\n startContainerChildTextNodeIndex: startContainerChildTextNodeIndex,\n startContainerElementCssSelector: startContainerElementCssSelector,\n startOffset: range.startOffset\n };\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n console.log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n console.log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\n\nfunction frameForHighlightAnnotationMarkWithID(win, id) {\n var clientRects = frameForHighlightWithID(id);\n if (!clientRects) return;\n var topClientRect = clientRects[0];\n var maxHeight = topClientRect.height;\n\n var _iterator18 = highlight_createForOfIteratorHelper(clientRects),\n _step18;\n\n try {\n for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {\n var clientRect = _step18.value;\n if (clientRect.top < topClientRect.top) topClientRect = clientRect;\n if (clientRect.height > maxHeight) maxHeight = clientRect.height;\n }\n } catch (err) {\n _iterator18.e(err);\n } finally {\n _iterator18.f();\n }\n\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var newTop = topClientRect.top;\n\n if (_highlightsContainer) {\n do {\n var boundingAreas = document.getElementsByClassName(CLASS_ANNOTATION_BOUNDING_AREA);\n var found = false; //for (let i = 0, length = boundingAreas.snapshotLength; i < length; ++i) {\n\n for (var i = 0, len = boundingAreas.length | 0; i < len; i = i + 1 | 0) {\n var boundingArea = boundingAreas[i];\n\n if (Math.abs(boundingArea.rect.top - (newTop - yOffset)) < 3) {\n newTop += boundingArea.rect.height;\n found = true;\n break;\n }\n }\n } while (found);\n }\n\n topClientRect.top = newTop;\n topClientRect.height = maxHeight;\n return topClientRect;\n}\n\nfunction highlightWithID(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n return highlight;\n}\n\nfunction frameForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n return clientRects;\n}\n\nfunction rangeInfo2Location(rangeInfo) {\n return {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n partialCfi: rangeInfo.cfi,\n domRange: {\n start: {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n textNodeIndex: rangeInfo.startContainerChildTextNodeIndex,\n offset: rangeInfo.startOffset\n },\n end: {\n cssSelector: rangeInfo.endContainerElementCssSelector,\n textNodeIndex: rangeInfo.endContainerChildTextNodeIndex,\n offset: rangeInfo.endOffset\n }\n }\n };\n}\n\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n cfi: location.partialCfi,\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction rectangleForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRects[0].left,\n width: clientRects[0].width,\n top: clientRects[0].top,\n height: clientRects[0].height\n };\n return size;\n}\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n var clientRect = range.getBoundingClientRect();\n var handleBounds = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRect.left,\n width: clientRect.width,\n top: clientRect.top,\n height: clientRect.height\n };\n return handleBounds;\n } catch (e) {\n return null;\n }\n}\nfunction setScrollMode(flag) {\n if (!flag) {\n document.documentElement.classList.add(CLASS_PAGINATED);\n } else {\n document.documentElement.classList.remove(CLASS_PAGINATED);\n }\n}\n/*\n if (document.addEventListener) { // IE >= 9; other browsers\n document.addEventListener(\'contextmenu\', function(e) {\n //alert("You\'ve tried to open context menu"); //here you draw your own menu\n //e.preventDefault();\n //let getCssSelector = fullQualifiedSelector;\n \n\t\t\tlet str = window.getSelection();\n\t\t\tlet selectionInfo = getCurrentSelectionInfo();\n\t\t\tlet pos = createHighlight(selectionInfo,{red:10,green:50,blue:230},true);\n\t\t\tlet ret2 = createAnnotation(pos.id);\n\t\t\t\n }, false);\n } else { // IE < 9\n document.attachEvent(\'oncontextmenu\', function() {\n alert("You\'ve tried to open context menu");\n window.event.returnValue = false;\n });\n }\n*/\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = selection_getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction selection_getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : selection_createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction selection_createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction selection_convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return selection_createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction selection_location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n}; // Legacy highlights API.\n\nwindow.createAnnotation = createAnnotation;\nwindow.createHighlight = createHighlight;\nwindow.destroyHighlight = destroyHighlight;\nwindow.getCurrentSelectionInfo = getCurrentSelectionInfo;\nwindow.getSelectionRect = getSelectionRect;\nwindow.rectangleForHighlightWithID = rectangleForHighlightWithID;\nwindow.setScrollMode = setScrollMode;\n;// CONCATENATED MODULE: ./src/index-fixed.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for fixed layouts resources.\n\nwindow.readium.isFixedLayout = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFlBQVksRUFBRUEsWUFKQztBQUtmRixFQUFBQSxVQUFVLEVBQUVBLFVBTEc7QUFNZmdCLEVBQUFBLFdBQVcsRUFBRUEsV0FORTtBQU9mTCxFQUFBQSxhQUFhLEVBQUVBLGFBUEE7QUFRZkUsRUFBQUEsV0FBVyxFQUFFQSxXQVJFO0FBU2Z1QixFQUFBQSxnQkFBZ0IsRUFBRUEsZ0JBVEg7QUFVZnJELEVBQUFBLFdBQVcsRUFBRUEsV0FWRTtBQVdmeUQsRUFBQUEsY0FBYyxFQUFFQSxjQVhEO0FBYWY7QUFDQTJnQixFQUFBQSxtQkFBbUIsRUFBRUEsbUJBZE47QUFnQmY7QUFDQU8sRUFBQUEsMkJBQTJCLEVBQUV4YyxpQkFqQmQ7QUFrQmZRLEVBQUFBLGNBQWMsRUFBRUEsY0FsQkQ7QUFvQmY7QUFDQXVFLEVBQUFBLHVCQUF1QixFQUFFQSx1QkFBdUJBO0FBckJqQyxDQUFqQixFQXdCQTs7QUFDQXZQLE1BQU0sQ0FBQzZoQixnQkFBUCxHQUEwQkEsZ0JBQTFCO0FBQ0E3aEIsTUFBTSxDQUFDMmhCLGVBQVAsR0FBeUJBLGVBQXpCO0FBQ0EzaEIsTUFBTSxDQUFDMGEsZ0JBQVAsR0FBMEJBLGdCQUExQjtBQUNBMWEsTUFBTSxDQUFDZ2MsdUJBQVAsR0FBaUNBLHVCQUFqQztBQUNBaGMsTUFBTSxDQUFDK2xCLGdCQUFQLEdBQTBCQSxnQkFBMUI7QUFDQS9sQixNQUFNLENBQUM4bEIsMkJBQVAsR0FBcUNBLDJCQUFyQztBQUNBOWxCLE1BQU0sQ0FBQ2ttQixhQUFQLEdBQXVCQSxhQUF2QixDOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBbG1CLE1BQU0sQ0FBQzhQLE9BQVAsQ0FBZUMsYUFBZixHQUErQixJQUEvQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL21hdGNoLXF1b3RlLmpzP2RkNmEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZS5qcz9mZGVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzLmpzPzQwMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy91dGlscy5qcz8wMjVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvcmVjdC5qcz80ZDVhIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZGVjb3JhdG9yLmpzPzFiMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kb20uanM/Y2JmMCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2dlc3R1cmVzLmpzPzE0YzIiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9rZXlib2FyZC5qcz8xOGUzIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaGlnaGxpZ2h0LmpzPzhkYTgiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9zZWxlY3Rpb24uanM/NTlhYyIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LmpzP2I2MzUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9pbmRleC1maXhlZC5qcz9kOTlmIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhcHByb3hTZWFyY2ggZnJvbSAnYXBwcm94LXN0cmluZy1tYXRjaCc7XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnYXBwcm94LXN0cmluZy1tYXRjaCcpLk1hdGNofSBTdHJpbmdNYXRjaFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgTWF0Y2hcbiAqIEBwcm9wIHtudW1iZXJ9IHN0YXJ0IC0gU3RhcnQgb2Zmc2V0IG9mIG1hdGNoIGluIHRleHRcbiAqIEBwcm9wIHtudW1iZXJ9IGVuZCAtIEVuZCBvZmZzZXQgb2YgbWF0Y2ggaW4gdGV4dFxuICogQHByb3Age251bWJlcn0gc2NvcmUgLVxuICogICBTY29yZSBmb3IgdGhlIG1hdGNoIGJldHdlZW4gMCBhbmQgMS4wLCB3aGVyZSAxLjAgaW5kaWNhdGVzIGEgcGVyZmVjdCBtYXRjaFxuICogICBmb3IgdGhlIHF1b3RlIGFuZCBjb250ZXh0LlxuICovXG5cbi8qKlxuICogRmluZCB0aGUgYmVzdCBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgc3RyYCBpbiBgdGV4dGAgYWxsb3dpbmcgdXAgdG8gYG1heEVycm9yc2AgZXJyb3JzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4RXJyb3JzXG4gKiBAcmV0dXJuIHtTdHJpbmdNYXRjaFtdfVxuICovXG5mdW5jdGlvbiBzZWFyY2godGV4dCwgc3RyLCBtYXhFcnJvcnMpIHtcbiAgLy8gRG8gYSBmYXN0IHNlYXJjaCBmb3IgZXhhY3QgbWF0Y2hlcy4gVGhlIGBhcHByb3gtc3RyaW5nLW1hdGNoYCBsaWJyYXJ5XG4gIC8vIGRvZXNuJ3QgY3VycmVudGx5IGluY29ycG9yYXRlIHRoaXMgb3B0aW1pemF0aW9uIGl0c2VsZi5cbiAgbGV0IG1hdGNoUG9zID0gMDtcbiAgbGV0IGV4YWN0TWF0Y2hlcyA9IFtdO1xuICB3aGlsZSAobWF0Y2hQb3MgIT09IC0xKSB7XG4gICAgbWF0Y2hQb3MgPSB0ZXh0LmluZGV4T2Yoc3RyLCBtYXRjaFBvcyk7XG4gICAgaWYgKG1hdGNoUG9zICE9PSAtMSkge1xuICAgICAgZXhhY3RNYXRjaGVzLnB1c2goe1xuICAgICAgICBzdGFydDogbWF0Y2hQb3MsXG4gICAgICAgIGVuZDogbWF0Y2hQb3MgKyBzdHIubGVuZ3RoLFxuICAgICAgICBlcnJvcnM6IDAsXG4gICAgICB9KTtcbiAgICAgIG1hdGNoUG9zICs9IDE7XG4gICAgfVxuICB9XG4gIGlmIChleGFjdE1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBleGFjdE1hdGNoZXM7XG4gIH1cblxuICAvLyBJZiB0aGVyZSBhcmUgbm8gZXhhY3QgbWF0Y2hlcywgZG8gYSBtb3JlIGV4cGVuc2l2ZSBzZWFyY2ggZm9yIG1hdGNoZXNcbiAgLy8gd2l0aCBlcnJvcnMuXG4gIHJldHVybiBhcHByb3hTZWFyY2godGV4dCwgc3RyLCBtYXhFcnJvcnMpO1xufVxuXG4vKipcbiAqIENvbXB1dGUgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEuMCBmb3IgdGhlIHNpbWlsYXJpdHkgYmV0d2VlbiBgdGV4dGAgYW5kIGBzdHJgLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKi9cbmZ1bmN0aW9uIHRleHRNYXRjaFNjb3JlKHRleHQsIHN0cikge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAtIGBzY29yZU1hdGNoYCB3aWxsIG5ldmVyIHBhc3MgYW4gZW1wdHkgc3RyaW5nICovXG4gIGlmIChzdHIubGVuZ3RoID09PSAwIHx8IHRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIDAuMDtcbiAgfVxuICBjb25zdCBtYXRjaGVzID0gc2VhcmNoKHRleHQsIHN0ciwgc3RyLmxlbmd0aCk7XG5cbiAgLy8gcHJldHRpZXItaWdub3JlXG4gIHJldHVybiAxIC0gKG1hdGNoZXNbMF0uZXJyb3JzIC8gc3RyLmxlbmd0aCk7XG59XG5cbi8qKlxuICogRmluZCB0aGUgYmVzdCBhcHByb3hpbWF0ZSBtYXRjaCBmb3IgYHF1b3RlYCBpbiBgdGV4dGAuXG4gKlxuICogUmV0dXJucyBgbnVsbGAgaWYgbm8gbWF0Y2ggZXhjZWVkaW5nIHRoZSBtaW5pbXVtIHF1YWxpdHkgdGhyZXNob2xkIHdhcyBmb3VuZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIERvY3VtZW50IHRleHQgdG8gc2VhcmNoXG4gKiBAcGFyYW0ge3N0cmluZ30gcXVvdGUgLSBTdHJpbmcgdG8gZmluZCB3aXRoaW4gYHRleHRgXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCAtXG4gKiAgIENvbnRleHQgaW4gd2hpY2ggdGhlIHF1b3RlIG9yaWdpbmFsbHkgYXBwZWFyZWQuIFRoaXMgaXMgdXNlZCB0byBjaG9vc2UgdGhlXG4gKiAgIGJlc3QgbWF0Y2guXG4gKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5wcmVmaXhdIC0gRXhwZWN0ZWQgdGV4dCBiZWZvcmUgdGhlIHF1b3RlXG4gKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5zdWZmaXhdIC0gRXhwZWN0ZWQgdGV4dCBhZnRlciB0aGUgcXVvdGVcbiAqICAgQHBhcmFtIHtudW1iZXJ9IFtjb250ZXh0LmhpbnRdIC0gRXhwZWN0ZWQgb2Zmc2V0IG9mIG1hdGNoIHdpdGhpbiB0ZXh0XG4gKiBAcmV0dXJuIHtNYXRjaHxudWxsfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hRdW90ZSh0ZXh0LCBxdW90ZSwgY29udGV4dCA9IHt9KSB7XG4gIGlmIChxdW90ZS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIENob29zZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIHRvIGFsbG93IGZvciB0aGUgaW5pdGlhbCBzZWFyY2guXG4gIC8vIFRoaXMgY2hvaWNlIGludm9sdmVzIGEgdHJhZGVvZmYgYmV0d2VlbjpcbiAgLy9cbiAgLy8gIC0gUmVjYWxsIChwcm9wb3J0aW9uIG9mIFwiZ29vZFwiIG1hdGNoZXMgZm91bmQpXG4gIC8vICAtIFByZWNpc2lvbiAocHJvcG9ydGlvbiBvZiBtYXRjaGVzIGZvdW5kIHdoaWNoIGFyZSBcImdvb2RcIilcbiAgLy8gIC0gQ29zdCBvZiB0aGUgaW5pdGlhbCBzZWFyY2ggYW5kIG9mIHByb2Nlc3NpbmcgdGhlIGNhbmRpZGF0ZSBtYXRjaGVzIFsxXVxuICAvL1xuICAvLyBbMV0gU3BlY2lmaWNhbGx5LCB0aGUgZXhwZWN0ZWQtdGltZSBjb21wbGV4aXR5IG9mIHRoZSBpbml0aWFsIHNlYXJjaCBpc1xuICAvLyAgICAgYE8oKG1heEVycm9ycyAvIDMyKSAqIHRleHQubGVuZ3RoKWAuIFNlZSBgYXBwcm94LXN0cmluZy1tYXRjaGAgZG9jcy5cbiAgY29uc3QgbWF4RXJyb3JzID0gTWF0aC5taW4oMjU2LCBxdW90ZS5sZW5ndGggLyAyKTtcblxuICAvLyBGaW5kIGNsb3Nlc3QgbWF0Y2hlcyBmb3IgYHF1b3RlYCBpbiBgdGV4dGAgYmFzZWQgb24gZWRpdCBkaXN0YW5jZS5cbiAgY29uc3QgbWF0Y2hlcyA9IHNlYXJjaCh0ZXh0LCBxdW90ZSwgbWF4RXJyb3JzKTtcblxuICBpZiAobWF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGEgc2NvcmUgYmV0d2VlbiAwIGFuZCAxLjAgZm9yIGEgbWF0Y2ggY2FuZGlkYXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ01hdGNofSBtYXRjaFxuICAgKi9cbiAgY29uc3Qgc2NvcmVNYXRjaCA9IG1hdGNoID0+IHtcbiAgICBjb25zdCBxdW90ZVdlaWdodCA9IDUwOyAvLyBTaW1pbGFyaXR5IG9mIG1hdGNoZWQgdGV4dCB0byBxdW90ZS5cbiAgICBjb25zdCBwcmVmaXhXZWlnaHQgPSAyMDsgLy8gU2ltaWxhcml0eSBvZiB0ZXh0IGJlZm9yZSBtYXRjaGVkIHRleHQgdG8gYGNvbnRleHQucHJlZml4YC5cbiAgICBjb25zdCBzdWZmaXhXZWlnaHQgPSAyMDsgLy8gU2ltaWxhcml0eSBvZiB0ZXh0IGFmdGVyIG1hdGNoZWQgdGV4dCB0byBgY29udGV4dC5zdWZmaXhgLlxuICAgIGNvbnN0IHBvc1dlaWdodCA9IDI7IC8vIFByb3hpbWl0eSB0byBleHBlY3RlZCBsb2NhdGlvbi4gVXNlZCBhcyBhIHRpZS1icmVha2VyLlxuXG4gICAgY29uc3QgcXVvdGVTY29yZSA9IDEgLSBtYXRjaC5lcnJvcnMgLyBxdW90ZS5sZW5ndGg7XG5cbiAgICBjb25zdCBwcmVmaXhTY29yZSA9IGNvbnRleHQucHJlZml4XG4gICAgICA/IHRleHRNYXRjaFNjb3JlKFxuICAgICAgICAgIHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgbWF0Y2guc3RhcnQgLSBjb250ZXh0LnByZWZpeC5sZW5ndGgpLCBtYXRjaC5zdGFydCksXG4gICAgICAgICAgY29udGV4dC5wcmVmaXhcbiAgICAgICAgKVxuICAgICAgOiAxLjA7XG4gICAgY29uc3Qgc3VmZml4U2NvcmUgPSBjb250ZXh0LnN1ZmZpeFxuICAgICAgPyB0ZXh0TWF0Y2hTY29yZShcbiAgICAgICAgICB0ZXh0LnNsaWNlKG1hdGNoLmVuZCwgbWF0Y2guZW5kICsgY29udGV4dC5zdWZmaXgubGVuZ3RoKSxcbiAgICAgICAgICBjb250ZXh0LnN1ZmZpeFxuICAgICAgICApXG4gICAgICA6IDEuMDtcblxuICAgIGxldCBwb3NTY29yZSA9IDEuMDtcbiAgICBpZiAodHlwZW9mIGNvbnRleHQuaGludCA9PT0gJ251bWJlcicpIHtcbiAgICAgIGNvbnN0IG9mZnNldCA9IE1hdGguYWJzKG1hdGNoLnN0YXJ0IC0gY29udGV4dC5oaW50KTtcbiAgICAgIHBvc1Njb3JlID0gMS4wIC0gb2Zmc2V0IC8gdGV4dC5sZW5ndGg7XG4gICAgfVxuXG4gICAgY29uc3QgcmF3U2NvcmUgPVxuICAgICAgcXVvdGVXZWlnaHQgKiBxdW90ZVNjb3JlICtcbiAgICAgIHByZWZpeFdlaWdodCAqIHByZWZpeFNjb3JlICtcbiAgICAgIHN1ZmZpeFdlaWdodCAqIHN1ZmZpeFNjb3JlICtcbiAgICAgIHBvc1dlaWdodCAqIHBvc1Njb3JlO1xuICAgIGNvbnN0IG1heFNjb3JlID0gcXVvdGVXZWlnaHQgKyBwcmVmaXhXZWlnaHQgKyBzdWZmaXhXZWlnaHQgKyBwb3NXZWlnaHQ7XG4gICAgY29uc3Qgbm9ybWFsaXplZFNjb3JlID0gcmF3U2NvcmUgLyBtYXhTY29yZTtcblxuICAgIHJldHVybiBub3JtYWxpemVkU2NvcmU7XG4gIH07XG5cbiAgLy8gUmFuayBtYXRjaGVzIGJhc2VkIG9uIHNpbWlsYXJpdHkgb2YgYWN0dWFsIGFuZCBleHBlY3RlZCBzdXJyb3VuZGluZyB0ZXh0XG4gIC8vIGFuZCBhY3R1YWwvZXhwZWN0ZWQgb2Zmc2V0IGluIHRoZSBkb2N1bWVudCB0ZXh0LlxuICBjb25zdCBzY29yZWRNYXRjaGVzID0gbWF0Y2hlcy5tYXAobSA9PiAoe1xuICAgIHN0YXJ0OiBtLnN0YXJ0LFxuICAgIGVuZDogbS5lbmQsXG4gICAgc2NvcmU6IHNjb3JlTWF0Y2gobSksXG4gIH0pKTtcblxuICAvLyBDaG9vc2UgbWF0Y2ggd2l0aCBoaWdoZXN0IHNjb3JlLlxuICBzY29yZWRNYXRjaGVzLnNvcnQoKGEsIGIpID0+IGIuc2NvcmUgLSBhLnNjb3JlKTtcbiAgcmV0dXJuIHNjb3JlZE1hdGNoZXNbMF07XG59XG4iLCIvKipcbiAqIFJldHVybiB0aGUgY29tYmluZWQgbGVuZ3RoIG9mIHRleHQgbm9kZXMgY29udGFpbmVkIGluIGBub2RlYC5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqL1xuZnVuY3Rpb24gbm9kZVRleHRMZW5ndGgobm9kZSkge1xuICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOlxuICAgIGNhc2UgTm9kZS5URVhUX05PREU6XG4gICAgICAvLyBuYi4gYHRleHRDb250ZW50YCBleGNsdWRlcyB0ZXh0IGluIGNvbW1lbnRzIGFuZCBwcm9jZXNzaW5nIGluc3RydWN0aW9uc1xuICAgICAgLy8gd2hlbiBjYWxsZWQgb24gYSBwYXJlbnQgZWxlbWVudCwgc28gd2UgZG9uJ3QgbmVlZCB0byBzdWJ0cmFjdCB0aGF0IGhlcmUuXG5cbiAgICAgIHJldHVybiAvKiogQHR5cGUge3N0cmluZ30gKi8gKG5vZGUudGV4dENvbnRlbnQpLmxlbmd0aDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgdGV4dCBvZiBhbGwgcHJldmlvdXMgc2libGluZ3Mgb2YgYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICovXG5mdW5jdGlvbiBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChub2RlKSB7XG4gIGxldCBzaWJsaW5nID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gIGxldCBsZW5ndGggPSAwO1xuICB3aGlsZSAoc2libGluZykge1xuICAgIGxlbmd0aCArPSBub2RlVGV4dExlbmd0aChzaWJsaW5nKTtcbiAgICBzaWJsaW5nID0gc2libGluZy5wcmV2aW91c1NpYmxpbmc7XG4gIH1cbiAgcmV0dXJuIGxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIG9uZSBvciBtb3JlIGNoYXJhY3RlciBvZmZzZXRzIHdpdGhpbiBhbiBlbGVtZW50IHRvICh0ZXh0IG5vZGUsIHBvc2l0aW9uKVxuICogcGFpcnMuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge251bWJlcltdfSBvZmZzZXRzIC0gT2Zmc2V0cywgd2hpY2ggbXVzdCBiZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyXG4gKiBAcmV0dXJuIHt7IG5vZGU6IFRleHQsIG9mZnNldDogbnVtYmVyIH1bXX1cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZU9mZnNldHMoZWxlbWVudCwgLi4ub2Zmc2V0cykge1xuICBsZXQgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgY29uc3Qgbm9kZUl0ZXIgPSAvKiogQHR5cGUge0RvY3VtZW50fSAqLyAoXG4gICAgZWxlbWVudC5vd25lckRvY3VtZW50XG4gICkuY3JlYXRlTm9kZUl0ZXJhdG9yKGVsZW1lbnQsIE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gIGxldCBjdXJyZW50Tm9kZSA9IG5vZGVJdGVyLm5leHROb2RlKCk7XG4gIGxldCB0ZXh0Tm9kZTtcbiAgbGV0IGxlbmd0aCA9IDA7XG5cbiAgLy8gRmluZCB0aGUgdGV4dCBub2RlIGNvbnRhaW5pbmcgdGhlIGBuZXh0T2Zmc2V0YHRoIGNoYXJhY3RlciBmcm9tIHRoZSBzdGFydFxuICAvLyBvZiBgZWxlbWVudGAuXG4gIHdoaWxlIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgY3VycmVudE5vZGUpIHtcbiAgICB0ZXh0Tm9kZSA9IC8qKiBAdHlwZSB7VGV4dH0gKi8gKGN1cnJlbnROb2RlKTtcbiAgICBpZiAobGVuZ3RoICsgdGV4dE5vZGUuZGF0YS5sZW5ndGggPiBuZXh0T2Zmc2V0KSB7XG4gICAgICByZXN1bHRzLnB1c2goeyBub2RlOiB0ZXh0Tm9kZSwgb2Zmc2V0OiBuZXh0T2Zmc2V0IC0gbGVuZ3RoIH0pO1xuICAgICAgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudE5vZGUgPSBub2RlSXRlci5uZXh0Tm9kZSgpO1xuICAgICAgbGVuZ3RoICs9IHRleHROb2RlLmRhdGEubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJvdW5kYXJ5IGNhc2UuXG4gIHdoaWxlIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgdGV4dE5vZGUgJiYgbGVuZ3RoID09PSBuZXh0T2Zmc2V0KSB7XG4gICAgcmVzdWx0cy5wdXNoKHsgbm9kZTogdGV4dE5vZGUsIG9mZnNldDogdGV4dE5vZGUuZGF0YS5sZW5ndGggfSk7XG4gICAgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgfVxuXG4gIGlmIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT2Zmc2V0IGV4Y2VlZHMgdGV4dCBsZW5ndGgnKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5leHBvcnQgbGV0IFJFU09MVkVfRk9SV0FSRFMgPSAxO1xuZXhwb3J0IGxldCBSRVNPTFZFX0JBQ0tXQVJEUyA9IDI7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBvZmZzZXQgd2l0aGluIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYW4gZWxlbWVudC5cbiAqXG4gKiBUaGlzIHBvc2l0aW9uIGNhbiBiZSByZXNvbHZlZCB0byBhIHNwZWNpZmljIGRlc2NlbmRhbnQgbm9kZSBpbiB0aGUgY3VycmVudFxuICogRE9NIHN1YnRyZWUgb2YgdGhlIGVsZW1lbnQgdXNpbmcgdGhlIGByZXNvbHZlYCBtZXRob2QuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UG9zaXRpb24ge1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgdGhhdCByZWZlcnMgdG8gdGhlIHRleHQgcG9zaXRpb24gYG9mZnNldGAgd2l0aGluXG4gICAqIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYGVsZW1lbnRgLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKi9cbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb2Zmc2V0KSB7XG4gICAgaWYgKG9mZnNldCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT2Zmc2V0IGlzIGludmFsaWQnKTtcbiAgICB9XG5cbiAgICAvKiogRWxlbWVudCB0aGF0IGBvZmZzZXRgIGlzIHJlbGF0aXZlIHRvLiAqL1xuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgICAvKiogQ2hhcmFjdGVyIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgZWxlbWVudCdzIGB0ZXh0Q29udGVudGAuICovXG4gICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGlzIHBvc2l0aW9uIHdpdGggb2Zmc2V0IHJlbGF0aXZlIHRvIGEgZ2l2ZW4gYW5jZXN0b3JcbiAgICogZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSBwYXJlbnQgLSBBbmNlc3RvciBvZiBgdGhpcy5lbGVtZW50YFxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb259XG4gICAqL1xuICByZWxhdGl2ZVRvKHBhcmVudCkge1xuICAgIGlmICghcGFyZW50LmNvbnRhaW5zKHRoaXMuZWxlbWVudCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyZW50IGlzIG5vdCBhbiBhbmNlc3RvciBvZiBjdXJyZW50IGVsZW1lbnQnKTtcbiAgICB9XG5cbiAgICBsZXQgZWwgPSB0aGlzLmVsZW1lbnQ7XG4gICAgbGV0IG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgIHdoaWxlIChlbCAhPT0gcGFyZW50KSB7XG4gICAgICBvZmZzZXQgKz0gcHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgoZWwpO1xuICAgICAgZWwgPSAvKiogQHR5cGUge0VsZW1lbnR9ICovIChlbC5wYXJlbnRFbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbihlbCwgb2Zmc2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBwb3NpdGlvbiB0byBhIHNwZWNpZmljIHRleHQgbm9kZSBhbmQgb2Zmc2V0IHdpdGhpbiB0aGF0IG5vZGUuXG4gICAqXG4gICAqIFRocm93cyBpZiBgdGhpcy5vZmZzZXRgIGV4Y2VlZHMgdGhlIGxlbmd0aCBvZiB0aGUgZWxlbWVudCdzIHRleHQuIEluIHRoZVxuICAgKiBjYXNlIHdoZXJlIHRoZSBlbGVtZW50IGhhcyBubyB0ZXh0IGFuZCBgdGhpcy5vZmZzZXRgIGlzIDAsIHRoZSBgZGlyZWN0aW9uYFxuICAgKiBvcHRpb24gZGV0ZXJtaW5lcyB3aGF0IGhhcHBlbnMuXG4gICAqXG4gICAqIE9mZnNldHMgYXQgdGhlIGJvdW5kYXJ5IGJldHdlZW4gdHdvIG5vZGVzIGFyZSByZXNvbHZlZCB0byB0aGUgc3RhcnQgb2YgdGhlXG4gICAqIG5vZGUgdGhhdCBiZWdpbnMgYXQgdGhlIGJvdW5kYXJ5LlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgQHBhcmFtIHtSRVNPTFZFX0ZPUldBUkRTfFJFU09MVkVfQkFDS1dBUkRTfSBbb3B0aW9ucy5kaXJlY3Rpb25dIC1cbiAgICogICAgIFNwZWNpZmllcyBpbiB3aGljaCBkaXJlY3Rpb24gdG8gc2VhcmNoIGZvciB0aGUgbmVhcmVzdCB0ZXh0IG5vZGUgaWZcbiAgICogICAgIGB0aGlzLm9mZnNldGAgaXMgYDBgIGFuZCBgdGhpcy5lbGVtZW50YCBoYXMgbm8gdGV4dC4gSWYgbm90IHNwZWNpZmllZFxuICAgKiAgICAgYW4gZXJyb3IgaXMgdGhyb3duLlxuICAgKiBAcmV0dXJuIHt7IG5vZGU6IFRleHQsIG9mZnNldDogbnVtYmVyIH19XG4gICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9XG4gICAqL1xuICByZXNvbHZlKG9wdGlvbnMgPSB7fSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZU9mZnNldHModGhpcy5lbGVtZW50LCB0aGlzLm9mZnNldClbMF07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAodGhpcy5vZmZzZXQgPT09IDAgJiYgb3B0aW9ucy5kaXJlY3Rpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB0dyA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIoXG4gICAgICAgICAgdGhpcy5lbGVtZW50LmdldFJvb3ROb2RlKCksXG4gICAgICAgICAgTm9kZUZpbHRlci5TSE9XX1RFWFRcbiAgICAgICAgKTtcbiAgICAgICAgdHcuY3VycmVudE5vZGUgPSB0aGlzLmVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGZvcndhcmRzID0gb3B0aW9ucy5kaXJlY3Rpb24gPT09IFJFU09MVkVfRk9SV0FSRFM7XG4gICAgICAgIGNvbnN0IHRleHQgPSAvKiogQHR5cGUge1RleHR8bnVsbH0gKi8gKFxuICAgICAgICAgIGZvcndhcmRzID8gdHcubmV4dE5vZGUoKSA6IHR3LnByZXZpb3VzTm9kZSgpXG4gICAgICAgICk7XG4gICAgICAgIGlmICghdGV4dCkge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBub2RlOiB0ZXh0LCBvZmZzZXQ6IGZvcndhcmRzID8gMCA6IHRleHQuZGF0YS5sZW5ndGggfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgdGhhdCByZWZlcnMgdG8gdGhlIGBvZmZzZXRgdGggY2hhcmFjdGVyIHdpdGhpblxuICAgKiBgbm9kZWAuXG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tQ2hhck9mZnNldChub2RlLCBvZmZzZXQpIHtcbiAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6XG4gICAgICAgIHJldHVybiBUZXh0UG9zaXRpb24uZnJvbVBvaW50KG5vZGUsIG9mZnNldCk7XG4gICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOlxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbigvKiogQHR5cGUge0VsZW1lbnR9ICovIChub2RlKSwgb2Zmc2V0KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm9kZSBpcyBub3QgYW4gZWxlbWVudCBvciB0ZXh0IG5vZGUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgcmVwcmVzZW50aW5nIHRoZSByYW5nZSBzdGFydCBvciBlbmQgcG9pbnQgKG5vZGUsIG9mZnNldCkuXG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSAtIFRleHQgb3IgRWxlbWVudCBub2RlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgLSBPZmZzZXQgd2l0aGluIHRoZSBub2RlLlxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb259XG4gICAqL1xuICBzdGF0aWMgZnJvbVBvaW50KG5vZGUsIG9mZnNldCkge1xuICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERToge1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiAvKiogQHR5cGUge1RleHR9ICovIChub2RlKS5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGV4dCBub2RlIG9mZnNldCBpcyBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbm9kZS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IG5vZGUgaGFzIG5vIHBhcmVudCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHRoZSBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHBhcmVudCBlbGVtZW50LlxuICAgICAgICBjb25zdCB0ZXh0T2Zmc2V0ID0gcHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgobm9kZSkgKyBvZmZzZXQ7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb24obm9kZS5wYXJlbnRFbGVtZW50LCB0ZXh0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6IHtcbiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hpbGQgbm9kZSBvZmZzZXQgaXMgb3V0IG9mIHJhbmdlJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIHRleHQgbGVuZ3RoIGJlZm9yZSB0aGUgYG9mZnNldGB0aCBjaGlsZCBvZiBlbGVtZW50LlxuICAgICAgICBsZXQgdGV4dE9mZnNldCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2Zmc2V0OyBpKyspIHtcbiAgICAgICAgICB0ZXh0T2Zmc2V0ICs9IG5vZGVUZXh0TGVuZ3RoKG5vZGUuY2hpbGROb2Rlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbigvKiogQHR5cGUge0VsZW1lbnR9ICovIChub2RlKSwgdGV4dE9mZnNldCk7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvaW50IGlzIG5vdCBpbiBhbiBlbGVtZW50IG9yIHRleHQgbm9kZScpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSByZWdpb24gb2YgYSBkb2N1bWVudCBhcyBhIChzdGFydCwgZW5kKSBwYWlyIG9mIGBUZXh0UG9zaXRpb25gIHBvaW50cy5cbiAqXG4gKiBSZXByZXNlbnRpbmcgYSByYW5nZSBpbiB0aGlzIHdheSBhbGxvd3MgZm9yIGNoYW5nZXMgaW4gdGhlIERPTSBjb250ZW50IG9mIHRoZVxuICogcmFuZ2Ugd2hpY2ggZG9uJ3QgYWZmZWN0IGl0cyB0ZXh0IGNvbnRlbnQsIHdpdGhvdXQgYWZmZWN0aW5nIHRoZSB0ZXh0IGNvbnRlbnRcbiAqIG9mIHRoZSByYW5nZSBpdHNlbGYuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UmFuZ2Uge1xuICAvKipcbiAgICogQ29uc3RydWN0IGFuIGltbXV0YWJsZSBgVGV4dFJhbmdlYCBmcm9tIGEgYHN0YXJ0YCBhbmQgYGVuZGAgcG9pbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9ufSBzdGFydFxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvbn0gZW5kXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzdGFydCwgZW5kKSB7XG4gICAgdGhpcy5zdGFydCA9IHN0YXJ0O1xuICAgIHRoaXMuZW5kID0gZW5kO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGNvcHkgb2YgdGhpcyByYW5nZSB3aXRoIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIHJlbGF0aXZlIHRvIGFcbiAgICogZ2l2ZW4gYW5jZXN0b3IuIFNlZSBgVGV4dFBvc2l0aW9uLnJlbGF0aXZlVG9gLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgICovXG4gIHJlbGF0aXZlVG8oZWxlbWVudCkge1xuICAgIHJldHVybiBuZXcgVGV4dFJhbmdlKFxuICAgICAgdGhpcy5zdGFydC5yZWxhdGl2ZVRvKGVsZW1lbnQpLFxuICAgICAgdGhpcy5lbmQucmVsYXRpdmVUbyhlbGVtZW50KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGUgYFRleHRSYW5nZWAgdG8gYSBET00gcmFuZ2UuXG4gICAqXG4gICAqIFRoZSByZXN1bHRpbmcgRE9NIFJhbmdlIHdpbGwgYWx3YXlzIHN0YXJ0IGFuZCBlbmQgaW4gYSBgVGV4dGAgbm9kZS5cbiAgICogSGVuY2UgYFRleHRSYW5nZS5mcm9tUmFuZ2UocmFuZ2UpLnRvUmFuZ2UoKWAgY2FuIGJlIHVzZWQgdG8gXCJzaHJpbmtcIiBhXG4gICAqIHJhbmdlIHRvIHRoZSB0ZXh0IGl0IGNvbnRhaW5zLlxuICAgKlxuICAgKiBNYXkgdGhyb3cgaWYgdGhlIGBzdGFydGAgb3IgYGVuZGAgcG9zaXRpb25zIGNhbm5vdCBiZSByZXNvbHZlZCB0byBhIHJhbmdlLlxuICAgKlxuICAgKiBAcmV0dXJuIHtSYW5nZX1cbiAgICovXG4gIHRvUmFuZ2UoKSB7XG4gICAgbGV0IHN0YXJ0O1xuICAgIGxldCBlbmQ7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXJ0LmVsZW1lbnQgPT09IHRoaXMuZW5kLmVsZW1lbnQgJiZcbiAgICAgIHRoaXMuc3RhcnQub2Zmc2V0IDw9IHRoaXMuZW5kLm9mZnNldFxuICAgICkge1xuICAgICAgLy8gRmFzdCBwYXRoIGZvciBzdGFydCBhbmQgZW5kIHBvaW50cyBpbiBzYW1lIGVsZW1lbnQuXG4gICAgICBbc3RhcnQsIGVuZF0gPSByZXNvbHZlT2Zmc2V0cyhcbiAgICAgICAgdGhpcy5zdGFydC5lbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXJ0Lm9mZnNldCxcbiAgICAgICAgdGhpcy5lbmQub2Zmc2V0XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGFydCA9IHRoaXMuc3RhcnQucmVzb2x2ZSh7IGRpcmVjdGlvbjogUkVTT0xWRV9GT1JXQVJEUyB9KTtcbiAgICAgIGVuZCA9IHRoaXMuZW5kLnJlc29sdmUoeyBkaXJlY3Rpb246IFJFU09MVkVfQkFDS1dBUkRTIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnQubm9kZSwgc3RhcnQub2Zmc2V0KTtcbiAgICByYW5nZS5zZXRFbmQoZW5kLm5vZGUsIGVuZC5vZmZzZXQpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGV4aXN0aW5nIERPTSBgUmFuZ2VgIHRvIGEgYFRleHRSYW5nZWBcbiAgICpcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICogQHJldHVybiB7VGV4dFJhbmdlfVxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyYW5nZSkge1xuICAgIGNvbnN0IHN0YXJ0ID0gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXRcbiAgICApO1xuICAgIGNvbnN0IGVuZCA9IFRleHRQb3NpdGlvbi5mcm9tUG9pbnQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpO1xuICAgIHJldHVybiBuZXcgVGV4dFJhbmdlKHN0YXJ0LCBlbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGBUZXh0UmFuZ2VgIGZyb20gdGhlIGBzdGFydGB0aCB0byBgZW5kYHRoIGNoYXJhY3RlcnMgaW4gYHJvb3RgLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRcbiAgICovXG4gIHN0YXRpYyBmcm9tT2Zmc2V0cyhyb290LCBzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2UoXG4gICAgICBuZXcgVGV4dFBvc2l0aW9uKHJvb3QsIHN0YXJ0KSxcbiAgICAgIG5ldyBUZXh0UG9zaXRpb24ocm9vdCwgZW5kKVxuICAgICk7XG4gIH1cbn1cbiIsIi8qKlxuICogVGhpcyBtb2R1bGUgZXhwb3J0cyBhIHNldCBvZiBjbGFzc2VzIGZvciBjb252ZXJ0aW5nIGJldHdlZW4gRE9NIGBSYW5nZWBcbiAqIG9iamVjdHMgYW5kIGRpZmZlcmVudCB0eXBlcyBvZiBzZWxlY3RvcnMuIEl0IGlzIG1vc3RseSBhIHRoaW4gd3JhcHBlciBhcm91bmQgYVxuICogc2V0IG9mIGFuY2hvcmluZyBsaWJyYXJpZXMuIEl0IHNlcnZlcyB0d28gbWFpbiBwdXJwb3NlczpcbiAqXG4gKiAgMS4gUHJvdmlkaW5nIGEgY29uc2lzdGVudCBpbnRlcmZhY2UgYWNyb3NzIGRpZmZlcmVudCB0eXBlcyBvZiBhbmNob3JzLlxuICogIDIuIEluc3VsYXRpbmcgdGhlIHJlc3Qgb2YgdGhlIGNvZGUgZnJvbSBBUEkgY2hhbmdlcyBpbiB0aGUgdW5kZXJseWluZyBhbmNob3JpbmdcbiAqICAgICBsaWJyYXJpZXMuXG4gKi9cblxuaW1wb3J0IHsgbWF0Y2hRdW90ZSB9IGZyb20gJy4vbWF0Y2gtcXVvdGUnO1xuaW1wb3J0IHsgVGV4dFJhbmdlLCBUZXh0UG9zaXRpb24gfSBmcm9tICcuL3RleHQtcmFuZ2UnO1xuaW1wb3J0IHsgbm9kZUZyb21YUGF0aCwgeHBhdGhGcm9tTm9kZSB9IGZyb20gJy4veHBhdGgnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uLy4uL3R5cGVzL2FwaScpLlJhbmdlU2VsZWN0b3J9IFJhbmdlU2VsZWN0b3JcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uLy4uL3R5cGVzL2FwaScpLlRleHRQb3NpdGlvblNlbGVjdG9yfSBUZXh0UG9zaXRpb25TZWxlY3RvclxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuVGV4dFF1b3RlU2VsZWN0b3J9IFRleHRRdW90ZVNlbGVjdG9yXG4gKi9cblxuLyoqXG4gKiBDb252ZXJ0cyBiZXR3ZWVuIGBSYW5nZVNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFJhbmdlQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Tm9kZX0gcm9vdCAtIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtICBBIHJhbmdlIGRlc2NyaWJpbmcgdGhlIGFuY2hvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIHJhbmdlKSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLnJhbmdlID0gcmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtOb2RlfSByb290IC0gIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtICBBIHJhbmdlIGRlc2NyaWJpbmcgdGhlIGFuY2hvci5cbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlQW5jaG9yKHJvb3QsIHJhbmdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gYW5jaG9yIGZyb20gYSBzZXJpYWxpemVkIGBSYW5nZVNlbGVjdG9yYCBzZWxlY3Rvci5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290IC0gIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlU2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBzdGF0aWMgZnJvbVNlbGVjdG9yKHJvb3QsIHNlbGVjdG9yKSB7XG4gICAgY29uc3Qgc3RhcnRDb250YWluZXIgPSBub2RlRnJvbVhQYXRoKHNlbGVjdG9yLnN0YXJ0Q29udGFpbmVyLCByb290KTtcbiAgICBpZiAoIXN0YXJ0Q29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIHN0YXJ0Q29udGFpbmVyIFhQYXRoJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZW5kQ29udGFpbmVyID0gbm9kZUZyb21YUGF0aChzZWxlY3Rvci5lbmRDb250YWluZXIsIHJvb3QpO1xuICAgIGlmICghZW5kQ29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIGVuZENvbnRhaW5lciBYUGF0aCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0UG9zID0gVGV4dFBvc2l0aW9uLmZyb21DaGFyT2Zmc2V0KFxuICAgICAgc3RhcnRDb250YWluZXIsXG4gICAgICBzZWxlY3Rvci5zdGFydE9mZnNldFxuICAgICk7XG4gICAgY29uc3QgZW5kUG9zID0gVGV4dFBvc2l0aW9uLmZyb21DaGFyT2Zmc2V0KFxuICAgICAgZW5kQ29udGFpbmVyLFxuICAgICAgc2VsZWN0b3IuZW5kT2Zmc2V0XG4gICAgKTtcblxuICAgIGNvbnN0IHJhbmdlID0gbmV3IFRleHRSYW5nZShzdGFydFBvcywgZW5kUG9zKS50b1JhbmdlKCk7XG4gICAgcmV0dXJuIG5ldyBSYW5nZUFuY2hvcihyb290LCByYW5nZSk7XG4gIH1cblxuICB0b1JhbmdlKCkge1xuICAgIHJldHVybiB0aGlzLnJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1JhbmdlU2VsZWN0b3J9XG4gICAqL1xuICB0b1NlbGVjdG9yKCkge1xuICAgIC8vIFwiU2hyaW5rXCIgdGhlIHJhbmdlIHNvIHRoYXQgaXQgdGlnaHRseSB3cmFwcyBpdHMgdGV4dC4gVGhpcyBlbnN1cmVzIG1vcmVcbiAgICAvLyBwcmVkaWN0YWJsZSBvdXRwdXQgZm9yIGEgZ2l2ZW4gdGV4dCBzZWxlY3Rpb24uXG4gICAgY29uc3Qgbm9ybWFsaXplZFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZSh0aGlzLnJhbmdlKS50b1JhbmdlKCk7XG5cbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKG5vcm1hbGl6ZWRSYW5nZSk7XG4gICAgY29uc3Qgc3RhcnRDb250YWluZXIgPSB4cGF0aEZyb21Ob2RlKHRleHRSYW5nZS5zdGFydC5lbGVtZW50LCB0aGlzLnJvb3QpO1xuICAgIGNvbnN0IGVuZENvbnRhaW5lciA9IHhwYXRoRnJvbU5vZGUodGV4dFJhbmdlLmVuZC5lbGVtZW50LCB0aGlzLnJvb3QpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdSYW5nZVNlbGVjdG9yJyxcbiAgICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgICAgc3RhcnRPZmZzZXQ6IHRleHRSYW5nZS5zdGFydC5vZmZzZXQsXG4gICAgICBlbmRDb250YWluZXIsXG4gICAgICBlbmRPZmZzZXQ6IHRleHRSYW5nZS5lbmQub2Zmc2V0LFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBiZXR3ZWVuIGBUZXh0UG9zaXRpb25TZWxlY3RvcmAgc2VsZWN0b3JzIGFuZCBgUmFuZ2VgIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UG9zaXRpb25BbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydFxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCBzdGFydCwgZW5kKSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5lbmQgPSBlbmQ7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJvb3QsIHJhbmdlKSB7XG4gICAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhyb290KTtcbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbkFuY2hvcihcbiAgICAgIHJvb3QsXG4gICAgICB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0LFxuICAgICAgdGV4dFJhbmdlLmVuZC5vZmZzZXRcbiAgICApO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb25TZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbkFuY2hvcihyb290LCBzZWxlY3Rvci5zdGFydCwgc2VsZWN0b3IuZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb25TZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdUZXh0UG9zaXRpb25TZWxlY3RvcicsXG4gICAgICBzdGFydDogdGhpcy5zdGFydCxcbiAgICAgIGVuZDogdGhpcy5lbmQsXG4gICAgfTtcbiAgfVxuXG4gIHRvUmFuZ2UoKSB7XG4gICAgcmV0dXJuIFRleHRSYW5nZS5mcm9tT2Zmc2V0cyh0aGlzLnJvb3QsIHRoaXMuc3RhcnQsIHRoaXMuZW5kKS50b1JhbmdlKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAdHlwZWRlZiBRdW90ZU1hdGNoT3B0aW9uc1xuICogQHByb3Age251bWJlcn0gW2hpbnRdIC0gRXhwZWN0ZWQgcG9zaXRpb24gb2YgbWF0Y2ggaW4gdGV4dC4gU2VlIGBtYXRjaFF1b3RlYC5cbiAqL1xuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFRleHRRdW90ZVNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRRdW90ZUFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3QgLSBBIHJvb3QgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGFuY2hvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGV4YWN0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gICAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnByZWZpeF1cbiAgICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQuc3VmZml4XVxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgZXhhY3QsIGNvbnRleHQgPSB7fSkge1xuICAgIHRoaXMucm9vdCA9IHJvb3Q7XG4gICAgdGhpcy5leGFjdCA9IGV4YWN0O1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgYFRleHRRdW90ZUFuY2hvcmAgZnJvbSBhIHJhbmdlLlxuICAgKlxuICAgKiBXaWxsIHRocm93IGlmIGByYW5nZWAgZG9lcyBub3QgY29udGFpbiBhbnkgdGV4dCBub2Rlcy5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJvb3QsIHJhbmdlKSB7XG4gICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocm9vdC50ZXh0Q29udGVudCk7XG4gICAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhyb290KTtcblxuICAgIGNvbnN0IHN0YXJ0ID0gdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldDtcbiAgICBjb25zdCBlbmQgPSB0ZXh0UmFuZ2UuZW5kLm9mZnNldDtcblxuICAgIC8vIE51bWJlciBvZiBjaGFyYWN0ZXJzIGFyb3VuZCB0aGUgcXVvdGUgdG8gY2FwdHVyZSBhcyBjb250ZXh0LiBXZSBjdXJyZW50bHlcbiAgICAvLyBhbHdheXMgdXNlIGEgZml4ZWQgYW1vdW50LCBidXQgaXQgd291bGQgYmUgYmV0dGVyIGlmIHRoaXMgY29kZSB3YXMgYXdhcmVcbiAgICAvLyBvZiBsb2dpY2FsIGJvdW5kYXJpZXMgaW4gdGhlIGRvY3VtZW50IChwYXJhZ3JhcGgsIGFydGljbGUgZXRjLikgdG8gYXZvaWRcbiAgICAvLyBjYXB0dXJpbmcgdGV4dCB1bnJlbGF0ZWQgdG8gdGhlIHF1b3RlLlxuICAgIC8vXG4gICAgLy8gSW4gcmVndWxhciBwcm9zZSB0aGUgaWRlYWwgY29udGVudCB3b3VsZCBvZnRlbiBiZSB0aGUgc3Vycm91bmRpbmcgc2VudGVuY2UuXG4gICAgLy8gVGhpcyBpcyBhIG5hdHVyYWwgdW5pdCBvZiBtZWFuaW5nIHdoaWNoIGVuYWJsZXMgZGlzcGxheWluZyBxdW90ZXMgaW5cbiAgICAvLyBjb250ZXh0IGV2ZW4gd2hlbiB0aGUgZG9jdW1lbnQgaXMgbm90IGF2YWlsYWJsZS4gV2UgY291bGQgdXNlIGBJbnRsLlNlZ21lbnRlcmBcbiAgICAvLyBmb3IgdGhpcyB3aGVuIGF2YWlsYWJsZS5cbiAgICBjb25zdCBjb250ZXh0TGVuID0gMzI7XG5cbiAgICByZXR1cm4gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCB0ZXh0LnNsaWNlKHN0YXJ0LCBlbmQpLCB7XG4gICAgICBwcmVmaXg6IHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgc3RhcnQgLSBjb250ZXh0TGVuKSwgc3RhcnQpLFxuICAgICAgc3VmZml4OiB0ZXh0LnNsaWNlKGVuZCwgTWF0aC5taW4odGV4dC5sZW5ndGgsIGVuZCArIGNvbnRleHRMZW4pKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtUZXh0UXVvdGVTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCB7IHByZWZpeCwgc3VmZml4IH0gPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCBzZWxlY3Rvci5leGFjdCwgeyBwcmVmaXgsIHN1ZmZpeCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUZXh0UXVvdGVTZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdUZXh0UXVvdGVTZWxlY3RvcicsXG4gICAgICBleGFjdDogdGhpcy5leGFjdCxcbiAgICAgIHByZWZpeDogdGhpcy5jb250ZXh0LnByZWZpeCxcbiAgICAgIHN1ZmZpeDogdGhpcy5jb250ZXh0LnN1ZmZpeCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVvdGVNYXRjaE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKi9cbiAgdG9SYW5nZShvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy50b1Bvc2l0aW9uQW5jaG9yKG9wdGlvbnMpLnRvUmFuZ2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1b3RlTWF0Y2hPcHRpb25zfSBbb3B0aW9uc11cbiAgICovXG4gIHRvUG9zaXRpb25BbmNob3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAodGhpcy5yb290LnRleHRDb250ZW50KTtcbiAgICBjb25zdCBtYXRjaCA9IG1hdGNoUXVvdGUodGV4dCwgdGhpcy5leGFjdCwge1xuICAgICAgLi4udGhpcy5jb250ZXh0LFxuICAgICAgaGludDogb3B0aW9ucy5oaW50LFxuICAgIH0pO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUXVvdGUgbm90IGZvdW5kJyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKHRoaXMucm9vdCwgbWF0Y2guc3RhcnQsIG1hdGNoLmVuZCk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IFRleHRRdW90ZUFuY2hvciB9IGZyb20gXCIuL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90eXBlc1wiO1xuXG4vLyBDYXRjaCBKUyBlcnJvcnMgdG8gbG9nIHRoZW0gaW4gdGhlIGFwcC5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImVycm9yXCIsXG4gIGZ1bmN0aW9uIChldmVudCkge1xuICAgIEFuZHJvaWQubG9nRXJyb3IoZXZlbnQubWVzc2FnZSwgZXZlbnQuZmlsZW5hbWUsIGV2ZW50LmxpbmVubyk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICBvblZpZXdwb3J0V2lkdGhDaGFuZ2VkKCk7XG4gICAgICBzbmFwQ3VycmVudE9mZnNldCgpO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuYm9keSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG4vKipcbiAqIEhhdmluZyBhbiBvZGQgbnVtYmVyIG9mIGNvbHVtbnMgd2hlbiBkaXNwbGF5aW5nIHR3byBjb2x1bW5zIHBlciBzY3JlZW4gY2F1c2VzIHNuYXBwaW5nIGFuZCBwYWdlXG4gKiB0dXJuaW5nIGlzc3Vlcy4gVG8gZml4IHRoaXMsIHdlIGluc2VydCBhIGJsYW5rIHZpcnR1YWwgY29sdW1uIGF0IHRoZSBlbmQgb2YgdGhlIHJlc291cmNlLlxuICovXG5mdW5jdGlvbiBhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQoKSB7XG4gIGNvbnN0IGlkID0gXCJyZWFkaXVtLXZpcnR1YWwtcGFnZVwiO1xuICB2YXIgdmlydHVhbENvbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSB8fCBnZXRDb2x1bW5Db3VudFBlclNjcmVlbigpICE9IDIpIHtcbiAgICBpZiAodmlydHVhbENvbCkge1xuICAgICAgdmlydHVhbENvbC5yZW1vdmUoKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICAgIHZhciBjb2xDb3VudCA9IGRvY3VtZW50V2lkdGggLyBwYWdlV2lkdGg7XG4gICAgdmFyIGhhc09kZENvbENvdW50ID0gKE1hdGgucm91bmQoY29sQ291bnQgKiAyKSAvIDIpICUgMSA+IDAuMTtcbiAgICBpZiAoaGFzT2RkQ29sQ291bnQpIHtcbiAgICAgIGlmICh2aXJ0dWFsQ29sKSB7XG4gICAgICAgIHZpcnR1YWxDb2wucmVtb3ZlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aXJ0dWFsQ29sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgdmlydHVhbENvbC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBpZCk7XG4gICAgICAgIHZpcnR1YWxDb2wuc3R5bGUuYnJlYWtCZWZvcmUgPSBcImNvbHVtblwiO1xuICAgICAgICB2aXJ0dWFsQ29sLmlubmVySFRNTCA9IFwiJiM4MjAzO1wiOyAvLyB6ZXJvLXdpZHRoIHNwYWNlXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodmlydHVhbENvbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB2YXIgcGFnZVdpZHRoID0gMTtcblxuZnVuY3Rpb24gb25WaWV3cG9ydFdpZHRoQ2hhbmdlZCgpIHtcbiAgLy8gV2UgY2FuJ3QgcmVseSBvbiB3aW5kb3cuaW5uZXJXaWR0aCBmb3IgdGhlIHBhZ2VXaWR0aCBvbiBBbmRyb2lkLCBiZWNhdXNlIGlmIHRoZVxuICAvLyBkZXZpY2UgcGl4ZWwgcmF0aW8gaXMgbm90IGFuIGludGVnZXIsIHdlIGdldCByb3VuZGluZyBpc3N1ZXMgb2Zmc2V0dGluZyB0aGUgcGFnZXMuXG4gIC8vXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vcmVhZGl1bS9yZWFkaXVtLWNzcy9pc3N1ZXMvOTdcbiAgLy8gYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFkaXVtL3IyLW5hdmlnYXRvci1rb3RsaW4vaXNzdWVzLzE0NlxuICB2YXIgd2lkdGggPSBBbmRyb2lkLmdldFZpZXdwb3J0V2lkdGgoKTtcbiAgcGFnZVdpZHRoID0gd2lkdGggLyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgc2V0UHJvcGVydHkoXG4gICAgXCItLVJTX192aWV3cG9ydFdpZHRoXCIsXG4gICAgXCJjYWxjKFwiICsgd2lkdGggKyBcInB4IC8gXCIgKyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyArIFwiKVwiXG4gICk7XG5cbiAgYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2x1bW5Db3VudFBlclNjcmVlbigpIHtcbiAgcmV0dXJuIHBhcnNlSW50KFxuICAgIHdpbmRvd1xuICAgICAgLmdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KVxuICAgICAgLmdldFByb3BlcnR5VmFsdWUoXCJjb2x1bW4tY291bnRcIilcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSB7XG4gIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlO1xuICByZXR1cm4gKFxuICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLVVTRVJfX3ZpZXdcIikudHJpbSgpID09IFwicmVhZGl1bS1zY3JvbGwtb25cIiB8fFxuICAgIC8vIEZJWE1FOiBXaWxsIG5lZWQgdG8gYmUgcmVtb3ZlZCBpbiBSZWFkaXVtIDMuMCwgLS1VU0VSX19zY3JvbGwgd2FzIGluY29ycmVjdC5cbiAgICBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1VU0VSX19zY3JvbGxcIikudHJpbSgpID09IFwicmVhZGl1bS1zY3JvbGwtb25cIlxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSVEwoKSB7XG4gIHJldHVybiBkb2N1bWVudC5ib2R5LmRpci50b0xvd2VyQ2FzZSgpID09IFwicnRsXCI7XG59XG5cbi8vIFNjcm9sbCB0byB0aGUgZ2l2ZW4gVGFnSWQgaW4gZG9jdW1lbnQgYW5kIHNuYXAuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9JZChpZCkge1xuICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHNjcm9sbFRvUmVjdChlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbn1cblxuLy8gUG9zaXRpb24gbXVzdCBiZSBpbiB0aGUgcmFuZ2UgWzAgLSAxXSwgMC0xMDAlLlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvUG9zaXRpb24ocG9zaXRpb24pIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9Qb3NpdGlvbiBcIiArIHBvc2l0aW9uKTtcbiAgaWYgKHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+IDEpIHtcbiAgICB0aHJvdyBcInNjcm9sbFRvUG9zaXRpb24oKSBtdXN0IGJlIGdpdmVuIGEgcG9zaXRpb24gZnJvbSAwLjAgdG8gIDEuMFwiO1xuICB9XG5cbiAgbGV0IG9mZnNldDtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIG9mZnNldCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsSGVpZ2h0ICogcG9zaXRpb247XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSBvZmZzZXQ7XG4gICAgLy8gd2luZG93LnNjcm9sbFRvKDAsIG9mZnNldCk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICAgIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICAgIG9mZnNldCA9IGRvY3VtZW50V2lkdGggKiBwb3NpdGlvbiAqIGZhY3RvcjtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KG9mZnNldCk7XG4gIH1cbn1cblxuLy8gU2Nyb2xscyB0byB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgZ2l2ZW4gdGV4dCBzbmlwcGV0LlxuLy9cbi8vIFRoZSBleHBlY3RlZCB0ZXh0IGFyZ3VtZW50IGlzIGEgTG9jYXRvciBUZXh0IG9iamVjdCwgYXMgZGVmaW5lZCBoZXJlOlxuLy8gaHR0cHM6Ly9yZWFkaXVtLm9yZy9hcmNoaXRlY3R1cmUvbW9kZWxzL2xvY2F0b3JzL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvVGV4dCh0ZXh0KSB7XG4gIGxldCByYW5nZSA9IHJhbmdlRnJvbUxvY2F0b3IoeyB0ZXh0IH0pO1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHNjcm9sbFRvUmFuZ2UocmFuZ2UpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gc2Nyb2xsVG9SYW5nZShyYW5nZSkge1xuICByZXR1cm4gc2Nyb2xsVG9SZWN0KHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbn1cblxuZnVuY3Rpb24gc2Nyb2xsVG9SZWN0KHJlY3QpIHtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID1cbiAgICAgIHJlY3QudG9wICsgd2luZG93LnNjcm9sbFkgLSB3aW5kb3cuaW5uZXJIZWlnaHQgLyAyO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoXG4gICAgICByZWN0LmxlZnQgKyB3aW5kb3cuc2Nyb2xsWFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvU3RhcnQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvU3RhcnRcIik7XG4gIGlmICghaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IDA7XG4gICAgd2luZG93LnNjcm9sbFRvKDAsIDApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb0VuZCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9FbmRcIik7XG4gIGlmICghaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChcbiAgICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGggKiBmYWN0b3JcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQ7XG4gICAgd2luZG93LnNjcm9sbFRvKDAsIGRvY3VtZW50LmJvZHkuc2Nyb2xsSGVpZ2h0KTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIGlzIGFscmVhZHkgYXQgdGhlIGxlZnQtbW9zdCBzY3JvbGwgb2Zmc2V0LlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbExlZnQoKSB7XG4gIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgdmFyIG9mZnNldCA9IHdpbmRvdy5zY3JvbGxYIC0gcGFnZVdpZHRoO1xuICB2YXIgbWluT2Zmc2V0ID0gaXNSVEwoKSA/IC0oZG9jdW1lbnRXaWR0aCAtIHBhZ2VXaWR0aCkgOiAwO1xuICByZXR1cm4gc2Nyb2xsVG9PZmZzZXQoTWF0aC5tYXgob2Zmc2V0LCBtaW5PZmZzZXQpKTtcbn1cblxuLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgcGFnZSBpcyBhbHJlYWR5IGF0IHRoZSByaWdodC1tb3N0IHNjcm9sbCBvZmZzZXQuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsUmlnaHQoKSB7XG4gIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgdmFyIG9mZnNldCA9IHdpbmRvdy5zY3JvbGxYICsgcGFnZVdpZHRoO1xuICB2YXIgbWF4T2Zmc2V0ID0gaXNSVEwoKSA/IDAgOiBkb2N1bWVudFdpZHRoIC0gcGFnZVdpZHRoO1xuICByZXR1cm4gc2Nyb2xsVG9PZmZzZXQoTWF0aC5taW4ob2Zmc2V0LCBtYXhPZmZzZXQpKTtcbn1cblxuLy8gU2Nyb2xscyB0byB0aGUgZ2l2ZW4gbGVmdCBvZmZzZXQuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIHNjcm9sbCBwb3NpdGlvbiBpcyBhbHJlYWR5IGNsb3NlIGVub3VnaCB0byB0aGUgZ2l2ZW4gb2Zmc2V0LlxuZnVuY3Rpb24gc2Nyb2xsVG9PZmZzZXQob2Zmc2V0KSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvT2Zmc2V0IFwiICsgb2Zmc2V0KTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHRocm93IFwiQ2FsbGVkIHNjcm9sbFRvT2Zmc2V0KCkgd2l0aCBzY3JvbGwgbW9kZSBlbmFibGVkLiBUaGlzIGNhbiBvbmx5IGJlIHVzZWQgaW4gcGFnaW5hdGVkIG1vZGUuXCI7XG4gIH1cblxuICB2YXIgY3VycmVudE9mZnNldCA9IHdpbmRvdy5zY3JvbGxYO1xuICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KG9mZnNldCk7XG4gIC8vIEluIHNvbWUgY2FzZSB0aGUgc2Nyb2xsWCBjYW5ub3QgcmVhY2ggdGhlIHBvc2l0aW9uIHJlc3BlY3RpbmcgdG8gaW5uZXJXaWR0aFxuICB2YXIgZGlmZiA9IE1hdGguYWJzKGN1cnJlbnRPZmZzZXQgLSBvZmZzZXQpIC8gcGFnZVdpZHRoO1xuICByZXR1cm4gZGlmZiA+IDAuMDE7XG59XG5cbi8vIFNuYXAgdGhlIG9mZnNldCB0byB0aGUgc2NyZWVuIHdpZHRoIChwYWdlIHdpZHRoKS5cbmZ1bmN0aW9uIHNuYXBPZmZzZXQob2Zmc2V0KSB7XG4gIHZhciB2YWx1ZSA9IG9mZnNldCArIChpc1JUTCgpID8gLTEgOiAxKTtcbiAgcmV0dXJuIHZhbHVlIC0gKHZhbHVlICUgcGFnZVdpZHRoKTtcbn1cblxuLy8gU25hcHMgdGhlIGN1cnJlbnQgb2Zmc2V0IHRvIHRoZSBwYWdlIHdpZHRoLlxuZXhwb3J0IGZ1bmN0aW9uIHNuYXBDdXJyZW50T2Zmc2V0KCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzbmFwQ3VycmVudE9mZnNldFwiKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgY3VycmVudE9mZnNldCA9IHdpbmRvdy5zY3JvbGxYO1xuICAvLyBBZGRzIGhhbGYgYSBwYWdlIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndCBzbmFwIHRvIHRoZSBwcmV2aW91cyBwYWdlLlxuICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgdmFyIGRlbHRhID0gZmFjdG9yICogKHBhZ2VXaWR0aCAvIDIpO1xuICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KGN1cnJlbnRPZmZzZXQgKyBkZWx0YSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByYW5nZUZyb21Mb2NhdG9yKGxvY2F0b3IpIHtcbiAgdHJ5IHtcbiAgICBsZXQgbG9jYXRpb25zID0gbG9jYXRvci5sb2NhdGlvbnM7XG4gICAgbGV0IHRleHQgPSBsb2NhdG9yLnRleHQ7XG4gICAgaWYgKHRleHQgJiYgdGV4dC5oaWdobGlnaHQpIHtcbiAgICAgIHZhciByb290O1xuICAgICAgaWYgKGxvY2F0aW9ucyAmJiBsb2NhdGlvbnMuY3NzU2VsZWN0b3IpIHtcbiAgICAgICAgcm9vdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobG9jYXRpb25zLmNzc1NlbGVjdG9yKTtcbiAgICAgIH1cbiAgICAgIGlmICghcm9vdCkge1xuICAgICAgICByb290ID0gZG9jdW1lbnQuYm9keTtcbiAgICAgIH1cblxuICAgICAgbGV0IGFuY2hvciA9IG5ldyBUZXh0UXVvdGVBbmNob3Iocm9vdCwgdGV4dC5oaWdobGlnaHQsIHtcbiAgICAgICAgcHJlZml4OiB0ZXh0LmJlZm9yZSxcbiAgICAgICAgc3VmZml4OiB0ZXh0LmFmdGVyLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gYW5jaG9yLnRvUmFuZ2UoKTtcbiAgICB9XG5cbiAgICBpZiAobG9jYXRpb25zKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IG51bGw7XG5cbiAgICAgIGlmICghZWxlbWVudCAmJiBsb2NhdGlvbnMuY3NzU2VsZWN0b3IpIHtcbiAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobG9jYXRpb25zLmNzc1NlbGVjdG9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50ICYmIGxvY2F0aW9ucy5mcmFnbWVudHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBodG1sSWQgb2YgbG9jYXRpb25zLmZyYWdtZW50cykge1xuICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChodG1sSWQpO1xuICAgICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgbGV0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnRCZWZvcmUoZWxlbWVudCk7XG4gICAgICAgIHJhbmdlLnNldEVuZEFmdGVyKGVsZW1lbnQpO1xuICAgICAgICByZXR1cm4gcmFuZ2U7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nRXJyb3IoZSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8vIFVzZXIgU2V0dGluZ3MuXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDU1NQcm9wZXJ0aWVzKHByb3BlcnRpZXMpIHtcbiAgZm9yIChjb25zdCBuYW1lIGluIHByb3BlcnRpZXMpIHtcbiAgICBzZXRQcm9wZXJ0eShuYW1lLCBwcm9wZXJ0aWVzW25hbWVdKTtcbiAgfVxufVxuXG4vLyBGb3Igc2V0dGluZyB1c2VyIHNldHRpbmcuXG5leHBvcnQgZnVuY3Rpb24gc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCIpIHtcbiAgICByZW1vdmVQcm9wZXJ0eShrZXkpO1xuICB9IGVsc2Uge1xuICAgIHZhciByb290ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgIC8vIFRoZSBgIWltcG9ydGFudGAgYW5ub3RhdGlvbiBpcyBhZGRlZCB3aXRoIGBzZXRQcm9wZXJ0eSgpYCBiZWNhdXNlIGlmIGl0J3MgcGFydCBvZiB0aGVcbiAgICAvLyBgdmFsdWVgLCBpdCB3aWxsIGJlIGlnbm9yZWQgYnkgdGhlIFdlYiBWaWV3LlxuICAgIHJvb3Quc3R5bGUuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSwgXCJpbXBvcnRhbnRcIik7XG4gIH1cbn1cblxuLy8gRm9yIHJlbW92aW5nIHVzZXIgc2V0dGluZy5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVQcm9wZXJ0eShrZXkpIHtcbiAgdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cbiAgcm9vdC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShrZXkpO1xufVxuXG4vLy8gVG9vbGtpdFxuXG5leHBvcnQgZnVuY3Rpb24gbG9nKCkge1xuICB2YXIgbWVzc2FnZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykuam9pbihcIiBcIik7XG4gIEFuZHJvaWQubG9nKG1lc3NhZ2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9nRXJyb3IobWVzc2FnZSkge1xuICBBbmRyb2lkLmxvZ0Vycm9yKG1lc3NhZ2UsIFwiXCIsIDApO1xufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgbG9nIGFzIGxvZ05hdGl2ZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmNvbnN0IGRlYnVnID0gZmFsc2U7XG5cbi8qKlxuICogQ29udmVydHMgYSBET01SZWN0IGludG8gYSBKU09OIG9iamVjdCB1bmRlcnN0YW5kYWJsZSBieSB0aGUgbmF0aXZlIHNpZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b05hdGl2ZVJlY3QocmVjdCkge1xuICBjb25zdCBwaXhlbFJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gIGNvbnN0IHdpZHRoID0gcmVjdC53aWR0aCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IGhlaWdodCA9IHJlY3QuaGVpZ2h0ICogcGl4ZWxSYXRpbztcbiAgY29uc3QgbGVmdCA9IHJlY3QubGVmdCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IHRvcCA9IHJlY3QudG9wICogcGl4ZWxSYXRpbztcbiAgY29uc3QgcmlnaHQgPSBsZWZ0ICsgd2lkdGg7XG4gIGNvbnN0IGJvdHRvbSA9IHRvcCArIGhlaWdodDtcbiAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCwgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgcmFuZ2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBsZXQgY2xpZW50UmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xuXG4gIGNvbnN0IHRvbGVyYW5jZSA9IDE7XG4gIGNvbnN0IG9yaWdpbmFsUmVjdHMgPSBbXTtcbiAgZm9yIChjb25zdCByYW5nZUNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBvcmlnaW5hbFJlY3RzLnB1c2goe1xuICAgICAgYm90dG9tOiByYW5nZUNsaWVudFJlY3QuYm90dG9tLFxuICAgICAgaGVpZ2h0OiByYW5nZUNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgbGVmdDogcmFuZ2VDbGllbnRSZWN0LmxlZnQsXG4gICAgICByaWdodDogcmFuZ2VDbGllbnRSZWN0LnJpZ2h0LFxuICAgICAgdG9wOiByYW5nZUNsaWVudFJlY3QudG9wLFxuICAgICAgd2lkdGg6IHJhbmdlQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9KTtcbiAgfVxuICBjb25zdCBtZXJnZWRSZWN0cyA9IG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICBvcmlnaW5hbFJlY3RzLFxuICAgIHRvbGVyYW5jZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG4gIGNvbnN0IG5vQ29udGFpbmVkUmVjdHMgPSByZW1vdmVDb250YWluZWRSZWN0cyhtZXJnZWRSZWN0cywgdG9sZXJhbmNlKTtcbiAgY29uc3QgbmV3UmVjdHMgPSByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5vQ29udGFpbmVkUmVjdHMpO1xuICBjb25zdCBtaW5BcmVhID0gMiAqIDI7XG4gIGZvciAobGV0IGogPSBuZXdSZWN0cy5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgIGNvbnN0IHJlY3QgPSBuZXdSZWN0c1tqXTtcbiAgICBjb25zdCBiaWdFbm91Z2ggPSByZWN0LndpZHRoICogcmVjdC5oZWlnaHQgPiBtaW5BcmVhO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBpZiAobmV3UmVjdHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsXCIpO1xuICAgICAgICBuZXdSZWN0cy5zcGxpY2UoaiwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsLCBidXQga2VlcCBvdGhlcndpc2UgZW1wdHkhXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgbG9nKGBDTElFTlQgUkVDVDogcmVkdWNlZCAke29yaWdpbmFsUmVjdHMubGVuZ3RofSAtLT4gJHtuZXdSZWN0cy5sZW5ndGh9YCk7XG4gIHJldHVybiBuZXdSZWN0cztcbn1cblxuZnVuY3Rpb24gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICByZWN0cyxcbiAgdG9sZXJhbmNlLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgbG9nKFwibWVyZ2VUb3VjaGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVjdHNMaW5lVXBWZXJ0aWNhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCByZWN0c0xpbmVVcEhvcml6b250YWxseSA9XG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpO1xuICAgICAgY29uc3QgaG9yaXpvbnRhbEFsbG93ZWQgPSAhZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cztcbiAgICAgIGNvbnN0IGFsaWduZWQgPVxuICAgICAgICAocmVjdHNMaW5lVXBIb3Jpem9udGFsbHkgJiYgaG9yaXpvbnRhbEFsbG93ZWQpIHx8XG4gICAgICAgIChyZWN0c0xpbmVVcFZlcnRpY2FsbHkgJiYgIXJlY3RzTGluZVVwSG9yaXpvbnRhbGx5KTtcbiAgICAgIGNvbnN0IGNhbk1lcmdlID0gYWxpZ25lZCAmJiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKTtcbiAgICAgIGlmIChjYW5NZXJnZSkge1xuICAgICAgICBsb2coXG4gICAgICAgICAgYENMSUVOVCBSRUNUOiBtZXJnaW5nIHR3byBpbnRvIG9uZSwgVkVSVElDQUw6ICR7cmVjdHNMaW5lVXBWZXJ0aWNhbGx5fSBIT1JJWk9OVEFMOiAke3JlY3RzTGluZVVwSG9yaXpvbnRhbGx5fSAoJHtkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzfSlgXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHJlY3QxICYmIHJlY3QgIT09IHJlY3QyO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVwbGFjZW1lbnRDbGllbnRSZWN0ID0gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIG5ld1JlY3RzLnB1c2gocmVwbGFjZW1lbnRDbGllbnRSZWN0KTtcbiAgICAgICAgcmV0dXJuIG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICAgICAgICBuZXdSZWN0cyxcbiAgICAgICAgICB0b2xlcmFuY2UsXG4gICAgICAgICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbGVmdCA9IE1hdGgubWluKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCByaWdodCA9IE1hdGgubWF4KHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IHRvcCA9IE1hdGgubWluKHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgYm90dG9tID0gTWF0aC5tYXgocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbSxcbiAgICBoZWlnaHQ6IGJvdHRvbSAtIHRvcCxcbiAgICBsZWZ0LFxuICAgIHJpZ2h0LFxuICAgIHRvcCxcbiAgICB3aWR0aDogcmlnaHQgLSBsZWZ0LFxuICB9O1xufVxuXG5mdW5jdGlvbiByZW1vdmVDb250YWluZWRSZWN0cyhyZWN0cywgdG9sZXJhbmNlKSB7XG4gIGNvbnN0IHJlY3RzVG9LZWVwID0gbmV3IFNldChyZWN0cyk7XG4gIGZvciAoY29uc3QgcmVjdCBvZiByZWN0cykge1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggPiAxICYmIHJlY3QuaGVpZ2h0ID4gMTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgbG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSB0aW55XCIpO1xuICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcG9zc2libHlDb250YWluaW5nUmVjdCBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QgPT09IHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIXJlY3RzVG9LZWVwLmhhcyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0Q29udGFpbnMocG9zc2libHlDb250YWluaW5nUmVjdCwgcmVjdCwgdG9sZXJhbmNlKSkge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIGNvbnRhaW5lZFwiKTtcbiAgICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20ocmVjdHNUb0tlZXApO1xufVxuXG5mdW5jdGlvbiByZWN0Q29udGFpbnMocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY3RDb250YWluc1BvaW50KHJlY3QsIHgsIHksIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0LmxlZnQgPCB4IHx8IGFsbW9zdEVxdWFsKHJlY3QubGVmdCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5yaWdodCA+IHggfHwgYWxtb3N0RXF1YWwocmVjdC5yaWdodCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC50b3AgPCB5IHx8IGFsbW9zdEVxdWFsKHJlY3QudG9wLCB5LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LmJvdHRvbSA+IHkgfHwgYWxtb3N0RXF1YWwocmVjdC5ib3R0b20sIHksIHRvbGVyYW5jZSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMocmVjdHMpIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgbG9nKFwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyByZWN0MSA9PT0gcmVjdDIgPz8hXCIpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgLTEpKSB7XG4gICAgICAgIGxldCB0b0FkZCA9IFtdO1xuICAgICAgICBsZXQgdG9SZW1vdmU7XG4gICAgICAgIGNvbnN0IHN1YnRyYWN0UmVjdHMxID0gcmVjdFN1YnRyYWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czIgPSByZWN0U3VidHJhY3QocmVjdDIsIHJlY3QxKTtcbiAgICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoIDwgc3VidHJhY3RSZWN0czIubGVuZ3RoKSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMjtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxvZyhgQ0xJRU5UIFJFQ1Q6IG92ZXJsYXAsIGN1dCBvbmUgcmVjdCBpbnRvICR7dG9BZGQubGVuZ3RofWApO1xuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSB0b1JlbW92ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KG5ld1JlY3RzLCB0b0FkZCk7XG4gICAgICAgIHJldHVybiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5ld1JlY3RzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IHJlY3RJbnRlcnNlY3RlZCA9IHJlY3RJbnRlcnNlY3QocmVjdDIsIHJlY3QxKTtcbiAgaWYgKHJlY3RJbnRlcnNlY3RlZC5oZWlnaHQgPT09IDAgfHwgcmVjdEludGVyc2VjdGVkLndpZHRoID09PSAwKSB7XG4gICAgcmV0dXJuIFtyZWN0MV07XG4gIH1cbiAgY29uc3QgcmVjdHMgPSBbXTtcbiAge1xuICAgIGNvbnN0IHJlY3RBID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0MS5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RBLndpZHRoID0gcmVjdEEucmlnaHQgLSByZWN0QS5sZWZ0O1xuICAgIHJlY3RBLmhlaWdodCA9IHJlY3RBLmJvdHRvbSAtIHJlY3RBLnRvcDtcbiAgICBpZiAocmVjdEEuaGVpZ2h0ICE9PSAwICYmIHJlY3RBLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RBKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RCID0ge1xuICAgICAgYm90dG9tOiByZWN0SW50ZXJzZWN0ZWQudG9wLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RCLndpZHRoID0gcmVjdEIucmlnaHQgLSByZWN0Qi5sZWZ0O1xuICAgIHJlY3RCLmhlaWdodCA9IHJlY3RCLmJvdHRvbSAtIHJlY3RCLnRvcDtcbiAgICBpZiAocmVjdEIuaGVpZ2h0ICE9PSAwICYmIHJlY3RCLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RCKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RDID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3RJbnRlcnNlY3RlZC5ib3R0b20sXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RDLndpZHRoID0gcmVjdEMucmlnaHQgLSByZWN0Qy5sZWZ0O1xuICAgIHJlY3RDLmhlaWdodCA9IHJlY3RDLmJvdHRvbSAtIHJlY3RDLnRvcDtcbiAgICBpZiAocmVjdEMuaGVpZ2h0ICE9PSAwICYmIHJlY3RDLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RDKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3REID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICByaWdodDogcmVjdDEucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEQud2lkdGggPSByZWN0RC5yaWdodCAtIHJlY3RELmxlZnQ7XG4gICAgcmVjdEQuaGVpZ2h0ID0gcmVjdEQuYm90dG9tIC0gcmVjdEQudG9wO1xuICAgIGlmIChyZWN0RC5oZWlnaHQgIT09IDAgJiYgcmVjdEQud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RJbnRlcnNlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IG1heExlZnQgPSBNYXRoLm1heChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgbWluUmlnaHQgPSBNYXRoLm1pbihyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCBtYXhUb3AgPSBNYXRoLm1heChyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IG1pbkJvdHRvbSA9IE1hdGgubWluKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgcmV0dXJuIHtcbiAgICBib3R0b206IG1pbkJvdHRvbSxcbiAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIG1pbkJvdHRvbSAtIG1heFRvcCksXG4gICAgbGVmdDogbWF4TGVmdCxcbiAgICByaWdodDogbWluUmlnaHQsXG4gICAgdG9wOiBtYXhUb3AsXG4gICAgd2lkdGg6IE1hdGgubWF4KDAsIG1pblJpZ2h0IC0gbWF4TGVmdCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICAocmVjdDEubGVmdCA8IHJlY3QyLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi5sZWZ0IDwgcmVjdDEucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi5sZWZ0LCByZWN0MS5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QxLnRvcCA8IHJlY3QyLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIudG9wIDwgcmVjdDEuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIudG9wLCByZWN0MS5ib3R0b20sIHRvbGVyYW5jZSkpKVxuICApO1xufVxuXG5mdW5jdGlvbiBhbG1vc3RFcXVhbChhLCBiLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8PSB0b2xlcmFuY2U7XG59XG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgbG9nTmF0aXZlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7XG4gIGdldENsaWVudFJlY3RzTm9PdmVybGFwLFxuICByZWN0Q29udGFpbnNQb2ludCxcbiAgdG9OYXRpdmVSZWN0LFxufSBmcm9tIFwiLi9yZWN0XCI7XG5pbXBvcnQgeyBsb2csIGxvZ0Vycm9yLCByYW5nZUZyb21Mb2NhdG9yIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxubGV0IHN0eWxlcyA9IG5ldyBNYXAoKTtcbmxldCBncm91cHMgPSBuZXcgTWFwKCk7XG52YXIgbGFzdEdyb3VwSWQgPSAwO1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGxpc3Qgb2YgYWRkaXRpb25hbCBzdXBwb3J0ZWQgRGVjb3JhdGlvbiBUZW1wbGF0ZXMuXG4gKlxuICogRWFjaCB0ZW1wbGF0ZSBvYmplY3QgaXMgaW5kZXhlZCBieSB0aGUgc3R5bGUgSUQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclRlbXBsYXRlcyhuZXdTdHlsZXMpIHtcbiAgdmFyIHN0eWxlc2hlZXQgPSBcIlwiO1xuXG4gIGZvciAoY29uc3QgW2lkLCBzdHlsZV0gb2YgT2JqZWN0LmVudHJpZXMobmV3U3R5bGVzKSkge1xuICAgIHN0eWxlcy5zZXQoaWQsIHN0eWxlKTtcbiAgICBpZiAoc3R5bGUuc3R5bGVzaGVldCkge1xuICAgICAgc3R5bGVzaGVldCArPSBzdHlsZS5zdHlsZXNoZWV0ICsgXCJcXG5cIjtcbiAgICB9XG4gIH1cblxuICBpZiAoc3R5bGVzaGVldCkge1xuICAgIGxldCBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG4gICAgc3R5bGVFbGVtZW50LmlubmVySFRNTCA9IHN0eWxlc2hlZXQ7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIERlY29yYXRpb25Hcm91cCBmb3IgdGhlIGdpdmVuIGdyb3VwIG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWNvcmF0aW9ucyhncm91cE5hbWUpIHtcbiAgdmFyIGdyb3VwID0gZ3JvdXBzLmdldChncm91cE5hbWUpO1xuICBpZiAoIWdyb3VwKSB7XG4gICAgbGV0IGlkID0gXCJyMi1kZWNvcmF0aW9uLVwiICsgbGFzdEdyb3VwSWQrKztcbiAgICBncm91cCA9IERlY29yYXRpb25Hcm91cChpZCwgZ3JvdXBOYW1lKTtcbiAgICBncm91cHMuc2V0KGdyb3VwTmFtZSwgZ3JvdXApO1xuICB9XG4gIHJldHVybiBncm91cDtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGNsaWNrIGV2ZW50cyBvbiBhIERlY29yYXRpb24uXG4gKiBSZXR1cm5zIHdoZXRoZXIgYSBkZWNvcmF0aW9uIG1hdGNoZWQgdGhpcyBldmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50KGV2ZW50LCBjbGlja0V2ZW50KSB7XG4gIGlmIChncm91cHMuc2l6ZSA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbmRUYXJnZXQoKSB7XG4gICAgZm9yIChjb25zdCBbZ3JvdXAsIGdyb3VwQ29udGVudF0gb2YgZ3JvdXBzKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZ3JvdXBDb250ZW50Lml0ZW1zLnJldmVyc2UoKSkge1xuICAgICAgICBpZiAoIWl0ZW0uY2xpY2thYmxlRWxlbWVudHMpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgaXRlbS5jbGlja2FibGVFbGVtZW50cykge1xuICAgICAgICAgIGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b0pTT04oKTtcbiAgICAgICAgICBpZiAocmVjdENvbnRhaW5zUG9pbnQocmVjdCwgZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgMSkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGdyb3VwLCBpdGVtLCBlbGVtZW50LCByZWN0IH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHRhcmdldCA9IGZpbmRUYXJnZXQoKTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gQW5kcm9pZC5vbkRlY29yYXRpb25BY3RpdmF0ZWQoXG4gICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgaWQ6IHRhcmdldC5pdGVtLmRlY29yYXRpb24uaWQsXG4gICAgICBncm91cDogdGFyZ2V0Lmdyb3VwLFxuICAgICAgcmVjdDogdG9OYXRpdmVSZWN0KHRhcmdldC5pdGVtLnJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxcbiAgICAgIGNsaWNrOiBjbGlja0V2ZW50LFxuICAgIH0pXG4gICk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIERlY29yYXRpb25Hcm91cCBvYmplY3QgZnJvbSBhIHVuaXF1ZSBIVE1MIElEIGFuZCBpdHMgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIERlY29yYXRpb25Hcm91cChncm91cElkLCBncm91cE5hbWUpIHtcbiAgdmFyIGl0ZW1zID0gW107XG4gIHZhciBsYXN0SXRlbUlkID0gMDtcbiAgdmFyIGNvbnRhaW5lciA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBuZXcgZGVjb3JhdGlvbiB0byB0aGUgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiBhZGQoZGVjb3JhdGlvbikge1xuICAgIGxldCBpZCA9IGdyb3VwSWQgKyBcIi1cIiArIGxhc3RJdGVtSWQrKztcblxuICAgIGxldCByYW5nZSA9IHJhbmdlRnJvbUxvY2F0b3IoZGVjb3JhdGlvbi5sb2NhdG9yKTtcbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICBsb2coXCJDYW4ndCBsb2NhdGUgRE9NIHJhbmdlIGZvciBkZWNvcmF0aW9uXCIsIGRlY29yYXRpb24pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtID0geyBpZCwgZGVjb3JhdGlvbiwgcmFuZ2UgfTtcbiAgICBpdGVtcy5wdXNoKGl0ZW0pO1xuICAgIGxheW91dChpdGVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBkZWNvcmF0aW9uIHdpdGggZ2l2ZW4gSUQgZnJvbSB0aGUgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiByZW1vdmUoZGVjb3JhdGlvbklkKSB7XG4gICAgbGV0IGluZGV4ID0gaXRlbXMuZmluZEluZGV4KChpKSA9PiBpLmRlY29yYXRpb24uaWQgPT09IGRlY29yYXRpb25JZCk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtID0gaXRlbXNbaW5kZXhdO1xuICAgIGl0ZW1zLnNwbGljZShpbmRleCwgMSk7XG4gICAgaXRlbS5jbGlja2FibGVFbGVtZW50cyA9IG51bGw7XG4gICAgaWYgKGl0ZW0uY29udGFpbmVyKSB7XG4gICAgICBpdGVtLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGl0ZW0uY29udGFpbmVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTm90aWZpZXMgdGhhdCB0aGUgZ2l2ZW4gZGVjb3JhdGlvbiB3YXMgbW9kaWZpZWQgYW5kIG5lZWRzIHRvIGJlIHVwZGF0ZWQuXG4gICAqL1xuICBmdW5jdGlvbiB1cGRhdGUoZGVjb3JhdGlvbikge1xuICAgIHJlbW92ZShkZWNvcmF0aW9uLmlkKTtcbiAgICBhZGQoZGVjb3JhdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgZGVjb3JhdGlvbnMgZnJvbSB0aGlzIGdyb3VwLlxuICAgKi9cbiAgZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgY2xlYXJDb250YWluZXIoKTtcbiAgICBpdGVtcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY3JlYXRlcyB0aGUgZGVjb3JhdGlvbiBlbGVtZW50cy5cbiAgICpcbiAgICogVG8gYmUgY2FsbGVkIGFmdGVyIHJlZmxvd2luZyB0aGUgcmVzb3VyY2UsIGZvciBleGFtcGxlLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVxdWVzdExheW91dCgpIHtcbiAgICBjbGVhckNvbnRhaW5lcigpO1xuICAgIGl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IGxheW91dChpdGVtKSk7XG4gIH1cblxuICAvKipcbiAgICogTGF5b3V0cyBhIHNpbmdsZSBEZWNvcmF0aW9uIGl0ZW0uXG4gICAqL1xuICBmdW5jdGlvbiBsYXlvdXQoaXRlbSkge1xuICAgIGxldCBncm91cENvbnRhaW5lciA9IHJlcXVpcmVDb250YWluZXIoKTtcblxuICAgIGxldCBzdHlsZSA9IHN0eWxlcy5nZXQoaXRlbS5kZWNvcmF0aW9uLnN0eWxlKTtcbiAgICBpZiAoIXN0eWxlKSB7XG4gICAgICBsb2dFcnJvcihgVW5rbm93biBkZWNvcmF0aW9uIHN0eWxlOiAke2l0ZW0uZGVjb3JhdGlvbi5zdHlsZX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgaXRlbUNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgaXRlbUNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBpdGVtLmlkKTtcbiAgICBpdGVtQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImRhdGEtc3R5bGVcIiwgaXRlbS5kZWNvcmF0aW9uLnN0eWxlKTtcbiAgICBpdGVtQ29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuXG4gICAgbGV0IHZpZXdwb3J0V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICBsZXQgY29sdW1uQ291bnQgPSBwYXJzZUludChcbiAgICAgIGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKFxuICAgICAgICBcImNvbHVtbi1jb3VudFwiXG4gICAgICApXG4gICAgKTtcbiAgICBsZXQgcGFnZVdpZHRoID0gdmlld3BvcnRXaWR0aCAvIChjb2x1bW5Db3VudCB8fCAxKTtcbiAgICBsZXQgc2Nyb2xsaW5nRWxlbWVudCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQ7XG4gICAgbGV0IHhPZmZzZXQgPSBzY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgbGV0IHlPZmZzZXQgPSBzY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcDtcblxuICAgIGZ1bmN0aW9uIHBvc2l0aW9uRWxlbWVudChlbGVtZW50LCByZWN0LCBib3VuZGluZ1JlY3QpIHtcbiAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG5cbiAgICAgIGlmIChzdHlsZS53aWR0aCA9PT0gXCJ3cmFwXCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke3JlY3Qud2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7cmVjdC5sZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwidmlld3BvcnRcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7dmlld3BvcnRXaWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBsZXQgbGVmdCA9IE1hdGguZmxvb3IocmVjdC5sZWZ0IC8gdmlld3BvcnRXaWR0aCkgKiB2aWV3cG9ydFdpZHRoO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtsZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwiYm91bmRzXCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke2JvdW5kaW5nUmVjdC53aWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtib3VuZGluZ1JlY3QubGVmdCArIHhPZmZzZXR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3JlY3QudG9wICsgeU9mZnNldH1weGA7XG4gICAgICB9IGVsc2UgaWYgKHN0eWxlLndpZHRoID09PSBcInBhZ2VcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7cGFnZVdpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGxldCBsZWZ0ID0gTWF0aC5mbG9vcihyZWN0LmxlZnQgLyBwYWdlV2lkdGgpICogcGFnZVdpZHRoO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtsZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgYm91bmRpbmdSZWN0ID0gaXRlbS5yYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGxldCBlbGVtZW50VGVtcGxhdGU7XG4gICAgdHJ5IHtcbiAgICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtcbiAgICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGl0ZW0uZGVjb3JhdGlvbi5lbGVtZW50LnRyaW0oKTtcbiAgICAgIGVsZW1lbnRUZW1wbGF0ZSA9IHRlbXBsYXRlLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ0Vycm9yKFxuICAgICAgICBgSW52YWxpZCBkZWNvcmF0aW9uIGVsZW1lbnQgXCIke2l0ZW0uZGVjb3JhdGlvbi5lbGVtZW50fVwiOiAke2Vycm9yLm1lc3NhZ2V9YFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc3R5bGUubGF5b3V0ID09PSBcImJveGVzXCIpIHtcbiAgICAgIGxldCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gdHJ1ZTtcbiAgICAgIGxldCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgICAgICBpdGVtLnJhbmdlLFxuICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICApO1xuXG4gICAgICBjbGllbnRSZWN0cyA9IGNsaWVudFJlY3RzLnNvcnQoKHIxLCByMikgPT4ge1xuICAgICAgICBpZiAocjEudG9wIDwgcjIudG9wKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9IGVsc2UgaWYgKHIxLnRvcCA+IHIyLnRvcCkge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZm9yIChsZXQgY2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgICAgICBjb25zdCBsaW5lID0gZWxlbWVudFRlbXBsYXRlLmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgbGluZS5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgICAgcG9zaXRpb25FbGVtZW50KGxpbmUsIGNsaWVudFJlY3QsIGJvdW5kaW5nUmVjdCk7XG4gICAgICAgIGl0ZW1Db250YWluZXIuYXBwZW5kKGxpbmUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc3R5bGUubGF5b3V0ID09PSBcImJvdW5kc1wiKSB7XG4gICAgICBjb25zdCBib3VuZHMgPSBlbGVtZW50VGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgYm91bmRzLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgcG9zaXRpb25FbGVtZW50KGJvdW5kcywgYm91bmRpbmdSZWN0LCBib3VuZGluZ1JlY3QpO1xuXG4gICAgICBpdGVtQ29udGFpbmVyLmFwcGVuZChib3VuZHMpO1xuICAgIH1cblxuICAgIGdyb3VwQ29udGFpbmVyLmFwcGVuZChpdGVtQ29udGFpbmVyKTtcbiAgICBpdGVtLmNvbnRhaW5lciA9IGl0ZW1Db250YWluZXI7XG4gICAgaXRlbS5jbGlja2FibGVFbGVtZW50cyA9IEFycmF5LmZyb20oXG4gICAgICBpdGVtQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1hY3RpdmFibGU9JzEnXVwiKVxuICAgICk7XG4gICAgaWYgKGl0ZW0uY2xpY2thYmxlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gQXJyYXkuZnJvbShpdGVtQ29udGFpbmVyLmNoaWxkcmVuKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZ3JvdXAgY29udGFpbmVyIGVsZW1lbnQsIGFmdGVyIG1ha2luZyBzdXJlIGl0IGV4aXN0cy5cbiAgICovXG4gIGZ1bmN0aW9uIHJlcXVpcmVDb250YWluZXIoKSB7XG4gICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgZ3JvdXBJZCk7XG4gICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKFwiZGF0YS1ncm91cFwiLCBncm91cE5hbWUpO1xuICAgICAgY29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoY29udGFpbmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRhaW5lcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBncm91cCBjb250YWluZXIuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhckNvbnRhaW5lcigpIHtcbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIucmVtb3ZlKCk7XG4gICAgICBjb250YWluZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGFkZCwgcmVtb3ZlLCB1cGRhdGUsIGNsZWFyLCBpdGVtcywgcmVxdWVzdExheW91dCB9O1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBXaWxsIHJlbGF5b3V0IGFsbCB0aGUgZGVjb3JhdGlvbnMgd2hlbiB0aGUgZG9jdW1lbnQgYm9keSBpcyByZXNpemVkLlxuICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgIHZhciBsYXN0U2l6ZSA9IHsgd2lkdGg6IDAsIGhlaWdodDogMCB9O1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgbGFzdFNpemUud2lkdGggPT09IGJvZHkuY2xpZW50V2lkdGggJiZcbiAgICAgICAgbGFzdFNpemUuaGVpZ2h0ID09PSBib2R5LmNsaWVudEhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxhc3RTaXplID0ge1xuICAgICAgICB3aWR0aDogYm9keS5jbGllbnRXaWR0aCxcbiAgICAgICAgaGVpZ2h0OiBib2R5LmNsaWVudEhlaWdodCxcbiAgICAgIH07XG5cbiAgICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICBncm91cC5yZXF1ZXN0TGF5b3V0KCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGJvZHkpO1xuICB9LFxuICBmYWxzZVxuKTtcbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjIgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IGlzU2Nyb2xsTW9kZUVuYWJsZWQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgZ2V0Q3NzU2VsZWN0b3IgfSBmcm9tIFwiY3NzLXNlbGVjdG9yLWdlbmVyYXRvclwiO1xuXG4vLyBTZWUuIGh0dHBzOi8vZ2l0aHViLmNvbS9KYXlQYW5vei9hcmNoaXRlY3R1cmUvdHJlZS90b3VjaC1oYW5kbGluZy9taXNjL3RvdWNoLWhhbmRsaW5nXG5leHBvcnQgZnVuY3Rpb24gbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChlbGVtZW50KSB7XG4gIGlmIChlbGVtZW50ID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2YXIgaW50ZXJhY3RpdmVUYWdzID0gW1xuICAgIFwiYVwiLFxuICAgIFwiYXVkaW9cIixcbiAgICBcImJ1dHRvblwiLFxuICAgIFwiY2FudmFzXCIsXG4gICAgXCJkZXRhaWxzXCIsXG4gICAgXCJpbnB1dFwiLFxuICAgIFwibGFiZWxcIixcbiAgICBcIm9wdGlvblwiLFxuICAgIFwic2VsZWN0XCIsXG4gICAgXCJzdWJtaXRcIixcbiAgICBcInRleHRhcmVhXCIsXG4gICAgXCJ2aWRlb1wiLFxuICBdO1xuICBpZiAoaW50ZXJhY3RpdmVUYWdzLmluZGV4T2YoZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSAhPSAtMSkge1xuICAgIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgfVxuXG4gIC8vIENoZWNrcyB3aGV0aGVyIHRoZSBlbGVtZW50IGlzIGVkaXRhYmxlIGJ5IHRoZSB1c2VyLlxuICBpZiAoXG4gICAgZWxlbWVudC5oYXNBdHRyaWJ1dGUoXCJjb250ZW50ZWRpdGFibGVcIikgJiZcbiAgICBlbGVtZW50LmdldEF0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKS50b0xvd2VyQ2FzZSgpICE9IFwiZmFsc2VcIlxuICApIHtcbiAgICByZXR1cm4gZWxlbWVudC5vdXRlckhUTUw7XG4gIH1cblxuICAvLyBDaGVja3MgcGFyZW50cyByZWN1cnNpdmVseSBiZWNhdXNlIHRoZSB0b3VjaCBtaWdodCBiZSBmb3IgZXhhbXBsZSBvbiBhbiA8ZW0+IGluc2lkZSBhIDxhPi5cbiAgaWYgKGVsZW1lbnQucGFyZW50RWxlbWVudCkge1xuICAgIHJldHVybiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQucGFyZW50RWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRGaXJzdFZpc2libGVMb2NhdG9yKCkge1xuICBjb25zdCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gIHJldHVybiB7XG4gICAgaHJlZjogXCIjXCIsXG4gICAgdHlwZTogXCJhcHBsaWNhdGlvbi94aHRtbCt4bWxcIixcbiAgICBsb2NhdGlvbnM6IHtcbiAgICAgIGNzc1NlbGVjdG9yOiBnZXRDc3NTZWxlY3RvcihlbGVtZW50KSxcbiAgICB9LFxuICAgIHRleHQ6IHtcbiAgICAgIGhpZ2hsaWdodDogZWxlbWVudC50ZXh0Q29udGVudCxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBmaW5kRWxlbWVudChyb290RWxlbWVudCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJvb3RFbGVtZW50LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGQgPSByb290RWxlbWVudC5jaGlsZHJlbltpXTtcbiAgICBpZiAoIXNob3VsZElnbm9yZUVsZW1lbnQoY2hpbGQpICYmIGlzRWxlbWVudFZpc2libGUoY2hpbGQpKSB7XG4gICAgICByZXR1cm4gZmluZEVsZW1lbnQoY2hpbGQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcm9vdEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzRWxlbWVudFZpc2libGUoZWxlbWVudCkge1xuICBpZiAocmVhZGl1bS5pc0ZpeGVkTGF5b3V0KSByZXR1cm4gdHJ1ZTtcblxuICBpZiAoZWxlbWVudCA9PT0gZG9jdW1lbnQuYm9keSB8fCBlbGVtZW50ID09PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoIWRvY3VtZW50IHx8ICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgIWRvY3VtZW50LmJvZHkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHJldHVybiByZWN0LmJvdHRvbSA+IDAgJiYgcmVjdC50b3AgPCB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHJlY3QucmlnaHQgPiAwICYmIHJlY3QubGVmdCA8IHdpbmRvdy5pbm5lcldpZHRoO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNob3VsZElnbm9yZUVsZW1lbnQoZWxlbWVudCkge1xuICBjb25zdCBlbFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgaWYgKGVsU3R5bGUpIHtcbiAgICBjb25zdCBkaXNwbGF5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiZGlzcGxheVwiKTtcbiAgICBpZiAoZGlzcGxheSAhPSBcImJsb2NrXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDYW5ub3QgYmUgcmVsaWVkIHVwb24sIGJlY2F1c2Ugd2ViIGJyb3dzZXIgZW5naW5lIHJlcG9ydHMgaW52aXNpYmxlIHdoZW4gb3V0IG9mIHZpZXcgaW5cbiAgICAvLyBzY3JvbGxlZCBjb2x1bW5zIVxuICAgIC8vIGNvbnN0IHZpc2liaWxpdHkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJ2aXNpYmlsaXR5XCIpO1xuICAgIC8vIGlmICh2aXNpYmlsaXR5ID09PSBcImhpZGRlblwiKSB7XG4gICAgLy8gICAgIHJldHVybiBmYWxzZTtcbiAgICAvLyB9XG4gICAgY29uc3Qgb3BhY2l0eSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIm9wYWNpdHlcIik7XG4gICAgaWYgKG9wYWNpdHkgPT09IFwiMFwiKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcbmltcG9ydCB7IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQgfSBmcm9tIFwiLi9kb21cIjtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIG9uQ2xpY2ssIGZhbHNlKTtcbiAgYmluZERyYWdHZXN0dXJlKGRvY3VtZW50KTtcbn0pO1xuXG5mdW5jdGlvbiBvbkNsaWNrKGV2ZW50KSB7XG4gIGlmICghd2luZG93LmdldFNlbGVjdGlvbigpLmlzQ29sbGFwc2VkKSB7XG4gICAgLy8gVGhlcmUncyBhbiBvbi1nb2luZyBzZWxlY3Rpb24sIHRoZSB0YXAgd2lsbCBkaXNtaXNzIGl0IHNvIHdlIGRvbid0IGZvcndhcmQgaXQuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgbGV0IGNsaWNrRXZlbnQgPSB7XG4gICAgZGVmYXVsdFByZXZlbnRlZDogZXZlbnQuZGVmYXVsdFByZXZlbnRlZCxcbiAgICB4OiBldmVudC5jbGllbnRYICogcGl4ZWxSYXRpbyxcbiAgICB5OiBldmVudC5jbGllbnRZICogcGl4ZWxSYXRpbyxcbiAgICB0YXJnZXRFbGVtZW50OiBldmVudC50YXJnZXQub3V0ZXJIVE1MLFxuICAgIGludGVyYWN0aXZlRWxlbWVudDogbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChldmVudC50YXJnZXQpLFxuICB9O1xuXG4gIGlmIChoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudChldmVudCwgY2xpY2tFdmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBTZW5kIHRoZSB0YXAgZGF0YSBvdmVyIHRoZSBKUyBicmlkZ2UgZXZlbiBpZiBpdCdzIGJlZW4gaGFuZGxlZCB3aXRoaW4gdGhlIHdlYiB2aWV3LCBzbyB0aGF0XG4gIC8vIGl0IGNhbiBiZSBwcmVzZXJ2ZWQgYW5kIHVzZWQgYnkgdGhlIHRvb2xraXQgaWYgbmVlZGVkLlxuICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uVGFwKEpTT04uc3RyaW5naWZ5KGNsaWNrRXZlbnQpKTtcblxuICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJpbmREcmFnR2VzdHVyZShlbGVtZW50KSB7XG4gIC8vIHBhc3NpdmU6IGZhbHNlIGlzIG5lY2Vzc2FyeSB0byBiZSBhYmxlIHRvIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IuXG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIiwgb25TdGFydCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgb25FbmQsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCBvbk1vdmUsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG5cbiAgdmFyIHN0YXRlID0gdW5kZWZpbmVkO1xuICB2YXIgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgY29uc3QgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuXG4gIGZ1bmN0aW9uIG9uU3RhcnQoZXZlbnQpIHtcbiAgICBpc1N0YXJ0aW5nRHJhZyA9IHRydWU7XG5cbiAgICBjb25zdCBzdGFydFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIGNvbnN0IHN0YXJ0WSA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUgPSB7XG4gICAgICBkZWZhdWx0UHJldmVudGVkOiBldmVudC5kZWZhdWx0UHJldmVudGVkLFxuICAgICAgc3RhcnRYOiBzdGFydFgsXG4gICAgICBzdGFydFk6IHN0YXJ0WSxcbiAgICAgIGN1cnJlbnRYOiBzdGFydFgsXG4gICAgICBjdXJyZW50WTogc3RhcnRZLFxuICAgICAgb2Zmc2V0WDogMCxcbiAgICAgIG9mZnNldFk6IDAsXG4gICAgICBpbnRlcmFjdGl2ZUVsZW1lbnQ6IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSxcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gb25Nb3ZlKGV2ZW50KSB7XG4gICAgaWYgKCFzdGF0ZSkgcmV0dXJuO1xuXG4gICAgc3RhdGUuY3VycmVudFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlLmN1cnJlbnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZS5vZmZzZXRYID0gc3RhdGUuY3VycmVudFggLSBzdGF0ZS5zdGFydFg7XG4gICAgc3RhdGUub2Zmc2V0WSA9IHN0YXRlLmN1cnJlbnRZIC0gc3RhdGUuc3RhcnRZO1xuXG4gICAgdmFyIHNob3VsZFByZXZlbnREZWZhdWx0ID0gZmFsc2U7XG4gICAgLy8gV2FpdCBmb3IgYSBtb3ZlbWVudCBvZiBhdCBsZWFzdCA2IHBpeGVscyBiZWZvcmUgcmVwb3J0aW5nIGEgZHJhZy5cbiAgICBpZiAoaXNTdGFydGluZ0RyYWcpIHtcbiAgICAgIGlmIChNYXRoLmFicyhzdGF0ZS5vZmZzZXRYKSA+PSA2IHx8IE1hdGguYWJzKHN0YXRlLm9mZnNldFkpID49IDYpIHtcbiAgICAgICAgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgICAgICAgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ1N0YXJ0KEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdNb3ZlKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25FbmQoZXZlbnQpIHtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG5cbiAgICBjb25zdCBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnRW5kKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHN0YXRlID0gdW5kZWZpbmVkO1xuICB9XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIzIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50IH0gZnJvbSBcIi4vZG9tXCI7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCAoZXZlbnQpID0+IHtcbiAgaWYgKHNob3VsZElnbm9yZUV2ZW50KGV2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcbiAgc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgXCJkb3duXCIpO1xufSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5dXBcIiwgKGV2ZW50KSA9PiB7XG4gIGlmIChzaG91bGRJZ25vcmVFdmVudChldmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwcmV2ZW50RGVmYXVsdChldmVudCk7XG4gIHNlbmRQcmVzc0tleU1lc3NhZ2UoZXZlbnQsIFwidXBcIik7XG59KTtcblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlRXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIChcbiAgICBldmVudC5kZWZhdWx0UHJldmVudGVkIHx8XG4gICAgbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChkb2N1bWVudC5hY3RpdmVFbGVtZW50KSAhPSBudWxsXG4gICk7XG59XG5cbi8vIFdlIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIGtleWJvYXJkIGV2ZW50cywgb3RoZXJ3aXNlIHRoZSB3ZWIgdmlld1xuLy8gbWlnaHQgc2Nyb2xsLlxuZnVuY3Rpb24gcHJldmVudERlZmF1bHQoZXZlbnQpIHtcbiAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59XG5cbmZ1bmN0aW9uIHNlbmRQcmVzc0tleU1lc3NhZ2UoZXZlbnQsIHR5cGUpIHtcbiAgaWYgKGV2ZW50LnJlcGVhdCkgcmV0dXJuO1xuXG4gIGxldCBrZXlFdmVudCA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGNvZGU6IGV2ZW50LmNvZGUsXG4gICAgY2hhcmFjdGVyczogU3RyaW5nLmZyb21DaGFyQ29kZShldmVudC5rZXlDb2RlKSxcbiAgICBhbHQ6IGV2ZW50LmFsdEtleSxcbiAgICBjb250cm9sOiBldmVudC5jdHJsS2V5LFxuICAgIHNoaWZ0OiBldmVudC5zaGlmdEtleSxcbiAgICBtZXRhOiBldmVudC5tZXRhS2V5LFxuICB9O1xuXG4gIEFuZHJvaWQub25LZXkoSlNPTi5zdHJpbmdpZnkoa2V5RXZlbnQpKTtcbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlICovXG4vL1xuLy8gIGhpZ2hsaWdodC5qc1xuLy8gIHIyLW5hdmlnYXRvci1rb3RsaW5cbi8vXG4vLyAgT3JnYW5pemVkIGJ5IFRhZWh5dW4gS2ltIG9uIDYvMjcvMTkgZnJvbSByMi1uYXZpZ2F0b3ItanMuXG4vL1xuLy8gIENvcHlyaWdodCAyMDE5IFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHdoaWNoIGlzIGRldGFpbGVkXG4vLyAgaW4gdGhlIExJQ0VOU0UgZmlsZSBwcmVzZW50IGluIHRoZSBwcm9qZWN0IHJlcG9zaXRvcnkgd2hlcmUgdGhpcyBzb3VyY2UgY29kZSBpcyBtYWludGFpbmVkLlxuLy9cblxuY29uc3QgUk9PVF9DTEFTU19SRURVQ0VfTU9USU9OID0gXCJyMi1yZWR1Y2UtbW90aW9uXCI7XG5jb25zdCBST09UX0NMQVNTX05PX0ZPT1ROT1RFUyA9IFwicjItbm8tcG9wdXAtZm9vbm90ZXNcIjtcbmNvbnN0IFBPUFVQX0RJQUxPR19DTEFTUyA9IFwicjItcG9wdXAtZGlhbG9nXCI7XG5jb25zdCBGT09UTk9URVNfQ09OVEFJTkVSX0NMQVNTID0gXCJyMi1mb290bm90ZS1jb250YWluZXJcIjtcbmNvbnN0IEZPT1ROT1RFU19DTE9TRV9CVVRUT05fQ0xBU1MgPSBcInIyLWZvb3Rub3RlLWNsb3NlXCI7XG5jb25zdCBGT09UTk9URV9GT1JDRV9TSE9XID0gXCJyMi1mb290bm90ZS1mb3JjZS1zaG93XCI7XG5jb25zdCBUVFNfSURfUFJFVklPVVMgPSBcInIyLXR0cy1wcmV2aW91c1wiO1xuY29uc3QgVFRTX0lEX05FWFQgPSBcInIyLXR0cy1uZXh0XCI7XG5jb25zdCBUVFNfSURfU0xJREVSID0gXCJyMi10dHMtc2xpZGVyXCI7XG5jb25zdCBUVFNfSURfQUNUSVZFX1dPUkQgPSBcInIyLXR0cy1hY3RpdmUtd29yZFwiO1xuY29uc3QgVFRTX0lEX0NPTlRBSU5FUiA9IFwicjItdHRzLXR4dFwiO1xuY29uc3QgVFRTX0lEX0lORk8gPSBcInIyLXR0cy1pbmZvXCI7XG5jb25zdCBUVFNfTkFWX0JVVFRPTl9DTEFTUyA9IFwicjItdHRzLWJ1dHRvblwiO1xuY29uc3QgVFRTX0lEX1NQRUFLSU5HX0RPQ19FTEVNRU5UID0gXCJyMi10dHMtc3BlYWtpbmctZWxcIjtcbmNvbnN0IFRUU19DTEFTU19JTkpFQ1RFRF9TUEFOID0gXCJyMi10dHMtc3BlYWtpbmctdHh0XCI7XG5jb25zdCBUVFNfQ0xBU1NfSU5KRUNURURfU1VCU1BBTiA9IFwicjItdHRzLXNwZWFraW5nLXdvcmRcIjtcbmNvbnN0IFRUU19JRF9JTkpFQ1RFRF9QQVJFTlQgPSBcInIyLXR0cy1zcGVha2luZy10eHQtcGFyZW50XCI7XG5jb25zdCBJRF9ISUdITElHSFRTX0NPTlRBSU5FUiA9IFwiUjJfSURfSElHSExJR0hUU19DT05UQUlORVJcIjtcbmNvbnN0IElEX0FOTk9UQVRJT05fQ09OVEFJTkVSID0gXCJSMl9JRF9BTk5PVEFUSU9OX0NPTlRBSU5FUlwiO1xuY29uc3QgQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUiA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUlwiO1xuY29uc3QgQ0xBU1NfQU5OT1RBVElPTl9DT05UQUlORVIgPSBcIlIyX0NMQVNTX0FOTk9UQVRJT05fQ09OVEFJTkVSXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQVJFQSA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0FSRUFcIjtcbmNvbnN0IENMQVNTX0FOTk9UQVRJT05fQVJFQSA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9BUkVBXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUFcIjtcbmNvbnN0IENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQSA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBXCI7XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG5jb25zdCBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSA9IFtcbiAgUE9QVVBfRElBTE9HX0NMQVNTLFxuICBUVFNfQ0xBU1NfSU5KRUNURURfU1BBTixcbiAgVFRTX0NMQVNTX0lOSkVDVEVEX1NVQlNQQU4sXG4gIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSLFxuICBDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSLFxuICBDTEFTU19ISUdITElHSFRfQVJFQSxcbiAgQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEsXG4gIFwicmVzaXplLXNlbnNvclwiLFxuXTtcbmNvbnN0IENMQVNTX1BBR0lOQVRFRCA9IFwicjItY3NzLXBhZ2luYXRlZFwiO1xuXG4vL2NvbnN0IElTX0RFViA9IChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJkZXZlbG9wbWVudFwiIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcImRldlwiKTtcbmNvbnN0IElTX0RFViA9IGZhbHNlO1xuY29uc3QgX2hpZ2hsaWdodHMgPSBbXTtcblxubGV0IF9oaWdobGlnaHRzQ29udGFpbmVyO1xubGV0IF9hbm5vdGF0aW9uQ29udGFpbmVyO1xubGV0IGxhc3RNb3VzZURvd25YID0gLTE7XG5sZXQgbGFzdE1vdXNlRG93blkgPSAtMTtcbmxldCBib2R5RXZlbnRMaXN0ZW5lcnNTZXQgPSBmYWxzZTtcblxuY29uc3QgVVNFX1NWRyA9IGZhbHNlO1xuY29uc3QgREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkgPSAwLjM7XG5jb25zdCBBTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZID0gMC40NTtcblxuLy9jb25zdCBERUJVR19WSVNVQUxTID0gZmFsc2U7XG5jb25zdCBERUJVR19WSVNVQUxTID0gZmFsc2U7XG5jb25zdCBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IgPSB7XG4gIGJsdWU6IDEwMCxcbiAgZ3JlZW46IDUwLFxuICByZWQ6IDIzMCxcbn07XG5cbmNvbnN0IEFOTk9UQVRJT05fV0lEVEggPSAxNTtcblxuZnVuY3Rpb24gcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKF93aW4sIGhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gIGlmIChcbiAgICBoaWdobGlnaHRCb3VuZGluZy5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSA9PSBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcbiAgKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLm91dGxpbmUgPSBcIm5vbmVcIjtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCIsXG4gICAgXCJ0cmFuc3BhcmVudFwiLFxuICAgIFwiaW1wb3J0YW50XCJcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYXMsIGhpZ2hsaWdodCkge1xuICBjb25zdCB1c2VTVkcgPSAhREVCVUdfVklTVUFMUyAmJiBVU0VfU1ZHO1xuICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgaGlnaGxpZ2h0QXJlYXMpIHtcbiAgICBjb25zdCBpc1NWRyA9IHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhLm5hbWVzcGFjZVVSSSA9PT0gU1ZHX1hNTF9OQU1FU1BBQ0U7XG4gICAgY29uc3Qgb3BhY2l0eSA9IEFMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFk7XG4gICAgaWYgKGlzU1ZHKSB7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImZpbGxcIixcbiAgICAgICAgYHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImZpbGwtb3BhY2l0eVwiLFxuICAgICAgICBgJHtvcGFjaXR5fWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcInN0cm9rZVwiLFxuICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwic3Ryb2tlLW9wYWNpdHlcIixcbiAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIixcbiAgICAgICAgYHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSlgLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpIHtcbiAgY29uc3QgdXNlU1ZHID0gIURFQlVHX1ZJU1VBTFMgJiYgVVNFX1NWRztcbiAgLy9jb25zdCB1c2VTVkcgPSBVU0VfU1ZHO1xuICBjb25zdCBpc1NWRyA9IHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhLm5hbWVzcGFjZVVSSSA9PT0gU1ZHX1hNTF9OQU1FU1BBQ0U7XG4gIGNvbnN0IGlkID0gaXNTVkdcbiAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlXG4gICAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImlkXCIpXG4gICAgICA6IHVuZGVmaW5lZFxuICAgIDogaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlXG4gICAgPyBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKFwiaWRcIilcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKGlkKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCkgPT4ge1xuICAgICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICAgIH0pO1xuICAgIGlmIChoaWdobGlnaHQpIHtcbiAgICAgIGNvbnN0IG9wYWNpdHkgPSBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWTtcbiAgICAgIGlmIChpc1NWRykge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiZmlsbFwiLFxuICAgICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcImZpbGwtb3BhY2l0eVwiLFxuICAgICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJzdHJva2VcIixcbiAgICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiLFxuICAgICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiLFxuICAgICAgICAgIGByZ2JhKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0sICR7b3BhY2l0eX0pYCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwcm9jZXNzVG91Y2hFdmVudCh3aW4sIGV2KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHggPSBldi5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRYO1xuICBjb25zdCB5ID0gZXYuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WTtcbiAgaWYgKCFfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBwYWdpbmF0ZWQgPSBpc1BhZ2luYXRlZChkb2N1bWVudCk7XG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgbGV0IHhPZmZzZXQ7XG4gIGxldCB5T2Zmc2V0O1xuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0IDogYm9keVJlY3QubGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiBib2R5UmVjdC50b3A7XG4gIH1cbiAgbGV0IGZvdW5kSGlnaGxpZ2h0O1xuICBsZXQgZm91bmRFbGVtZW50O1xuICBsZXQgZm91bmRSZWN0O1xuICAvLyAgICBfaGlnaGxpZ2h0cy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgLy8gICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGEuc2VsZWN0aW9uSW5mbykpXG4gIC8vICAgICAgICByZXR1cm4gYS5zZWxlY3Rpb25JbmZvLmNsZWFuVGV4dC5sZW5ndGggPCBiLnNlbGVjdGlvbkluZm8uY2xlYW5UZXh0Lmxlbmd0aFxuICAvLyAgICB9KVxuICBmb3IgKGxldCBpID0gX2hpZ2hsaWdodHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0c1tpXTtcbiAgICBsZXQgaGlnaGxpZ2h0UGFyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYCR7aGlnaGxpZ2h0LmlkfWApO1xuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBoaWdobGlnaHRQYXJlbnQgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGAjJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgfVxuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbGV0IGhpdCA9IGZhbHNlO1xuICAgIGNvbnN0IGhpZ2hsaWdodEZyYWdtZW50cyA9IGhpZ2hsaWdodFBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnQgb2YgaGlnaGxpZ2h0RnJhZ21lbnRzKSB7XG4gICAgICBjb25zdCB3aXRoUmVjdCA9IGhpZ2hsaWdodEZyYWdtZW50O1xuICAgICAgY29uc3QgbGVmdCA9IHdpdGhSZWN0LnJlY3QubGVmdCArIHhPZmZzZXQ7XG4gICAgICBjb25zdCB0b3AgPSB3aXRoUmVjdC5yZWN0LnRvcCArIHlPZmZzZXQ7XG4gICAgICBmb3VuZFJlY3QgPSB3aXRoUmVjdC5yZWN0O1xuICAgICAgaWYgKFxuICAgICAgICB4ID49IGxlZnQgJiZcbiAgICAgICAgeCA8IGxlZnQgKyB3aXRoUmVjdC5yZWN0LndpZHRoICYmXG4gICAgICAgIHkgPj0gdG9wICYmXG4gICAgICAgIHkgPCB0b3AgKyB3aXRoUmVjdC5yZWN0LmhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIGhpdCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaGl0KSB7XG4gICAgICBmb3VuZEhpZ2hsaWdodCA9IGhpZ2hsaWdodDtcbiAgICAgIGZvdW5kRWxlbWVudCA9IGhpZ2hsaWdodFBhcmVudDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoIWZvdW5kSGlnaGxpZ2h0IHx8ICFmb3VuZEVsZW1lbnQpIHtcbiAgICBjb25zdCBoaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgaGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgfVxuICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmb3VuZEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jbGlja1wiKSkge1xuICAgIGlmIChldi50eXBlID09PSBcIm1vdXNlbW92ZVwiKSB7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICAgIGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLmluZGV4T2YoaGlnaGxpZ2h0QXJlYSkgPCAwKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMsIGZvdW5kSGlnaGxpZ2h0KTtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nID0gZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGFsbEhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIHx8XG4gICAgICAgICAgaGlnaGxpZ2h0Qm91bmRpbmcgIT09IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nXG4gICAgICAgICkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gICAgICAgIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgICAgICAgc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZShcbiAgICAgICAgICAgIHdpbixcbiAgICAgICAgICAgIGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nLFxuICAgICAgICAgICAgZm91bmRIaWdobGlnaHRcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChldi50eXBlID09PSBcInRvdWNoc3RhcnRcIiB8fCBldi50eXBlID09PSBcInRvdWNoZW5kXCIpIHtcbiAgICAgIGNvbnN0IHNpemUgPSB7XG4gICAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cub3V0ZXJIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGZvdW5kUmVjdC5sZWZ0LFxuICAgICAgICB3aWR0aDogZm91bmRSZWN0LndpZHRoLFxuICAgICAgICB0b3A6IGZvdW5kUmVjdC50b3AsXG4gICAgICAgIGhlaWdodDogZm91bmRSZWN0LmhlaWdodCxcbiAgICAgIH07XG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBoaWdobGlnaHQ6IGZvdW5kSGlnaGxpZ2h0LmlkLFxuICAgICAgICBzaXplOiBzaXplLFxuICAgICAgfTtcblxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgIHR5cGVvZiB3aW5kb3cucHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICB3aW5kb3cucHJvY2Vzcy50eXBlID09PSBcInJlbmRlcmVyXCJcbiAgICAgICkge1xuICAgICAgICBlbGVjdHJvbl8xLmlwY1JlbmRlcmVyLnNlbmRUb0hvc3QoUjJfRVZFTlRfSElHSExJR0hUX0NMSUNLLCBwYXlsb2FkKTtcbiAgICAgIH0gZWxzZSBpZiAod2luZG93LndlYmtpdFVSTCkge1xuICAgICAgICBjb25zb2xlLmxvZyhmb3VuZEhpZ2hsaWdodC5pZC5pbmNsdWRlcyhcIlIyX0FOTk9UQVRJT05fXCIpKTtcbiAgICAgICAgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0FOTk9UQVRJT05fXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfSElHSExJR0hUX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHggPSBldi5jbGllbnRYO1xuICBjb25zdCB5ID0gZXYuY2xpZW50WTtcbiAgaWYgKCFfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeE9mZnNldDtcbiAgbGV0IHlPZmZzZXQ7XG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBib2R5UmVjdC5sZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICBsZXQgZm91bmRIaWdobGlnaHQ7XG4gIGxldCBmb3VuZEVsZW1lbnQ7XG4gIGxldCBmb3VuZFJlY3Q7XG4gIGZvciAobGV0IGkgPSBfaGlnaGxpZ2h0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzW2ldO1xuICAgIGxldCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGhpZ2hsaWdodFBhcmVudCA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYCMke2hpZ2hsaWdodC5pZH1gKTtcbiAgICB9XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBsZXQgaGl0ID0gZmFsc2U7XG4gICAgY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnRzID0gaGlnaGxpZ2h0UGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRGcmFnbWVudCBvZiBoaWdobGlnaHRGcmFnbWVudHMpIHtcbiAgICAgIGNvbnN0IHdpdGhSZWN0ID0gaGlnaGxpZ2h0RnJhZ21lbnQ7XG4gICAgICBjb25zdCBsZWZ0ID0gd2l0aFJlY3QucmVjdC5sZWZ0ICsgeE9mZnNldDtcbiAgICAgIGNvbnN0IHRvcCA9IHdpdGhSZWN0LnJlY3QudG9wICsgeU9mZnNldDtcbiAgICAgIGZvdW5kUmVjdCA9IHdpdGhSZWN0LnJlY3Q7XG4gICAgICBpZiAoXG4gICAgICAgIHggPj0gbGVmdCAmJlxuICAgICAgICB4IDwgbGVmdCArIHdpdGhSZWN0LnJlY3Qud2lkdGggJiZcbiAgICAgICAgeSA+PSB0b3AgJiZcbiAgICAgICAgeSA8IHRvcCArIHdpdGhSZWN0LnJlY3QuaGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgaGl0ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChoaXQpIHtcbiAgICAgIGZvdW5kSGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgZm91bmRFbGVtZW50ID0gaGlnaGxpZ2h0UGFyZW50O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFmb3VuZEhpZ2hsaWdodCB8fCAhZm91bmRFbGVtZW50KSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKHdpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICAgIH1cbiAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoZm91bmRFbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtY2xpY2tcIikpIHtcbiAgICBpZiAoZXYudHlwZSA9PT0gXCJtb3VzZW1vdmVcIikge1xuICAgICAgY29uc3QgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBmb3VuZEVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YClcbiAgICAgICk7XG4gICAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcy5pbmRleE9mKGhpZ2hsaWdodEFyZWEpIDwgMCkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLCBmb3VuZEhpZ2hsaWdodCk7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyA9IGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEJvdW5kaW5ncyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRCb3VuZGluZyBvZiBhbGxIaWdobGlnaHRCb3VuZGluZ3MpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyB8fFxuICAgICAgICAgIGhpZ2hsaWdodEJvdW5kaW5nICE9PSBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZ1xuICAgICAgICApIHtcbiAgICAgICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZykge1xuICAgICAgICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgICAgICAgIHNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUoXG4gICAgICAgICAgICB3aW4sXG4gICAgICAgICAgICBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyxcbiAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXYudHlwZSA9PT0gXCJtb3VzZXVwXCIgfHwgZXYudHlwZSA9PT0gXCJ0b3VjaGVuZFwiKSB7XG4gICAgICBjb25zdCB0b3VjaGVkUG9zaXRpb24gPSB7XG4gICAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGZvdW5kUmVjdC5sZWZ0LFxuICAgICAgICB3aWR0aDogZm91bmRSZWN0LndpZHRoLFxuICAgICAgICB0b3A6IGZvdW5kUmVjdC50b3AsXG4gICAgICAgIGhlaWdodDogZm91bmRSZWN0LmhlaWdodCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGhpZ2hsaWdodDogZm91bmRIaWdobGlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB0b3VjaGVkUG9zaXRpb24sXG4gICAgICB9O1xuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIHdpbmRvdy5wcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHdpbmRvdy5wcm9jZXNzLnR5cGUgPT09IFwicmVuZGVyZXJcIlxuICAgICAgKSB7XG4gICAgICAgIGVsZWN0cm9uXzEuaXBjUmVuZGVyZXIuc2VuZFRvSG9zdChSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0ssIHBheWxvYWQpO1xuICAgICAgfSBlbHNlIGlmICh3aW5kb3cud2Via2l0VVJMKSB7XG4gICAgICAgIGlmIChmb3VuZEhpZ2hsaWdodC5pZC5zZWFyY2goXCJSMl9BTk5PVEFUSU9OX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQoZm91bmRIaWdobGlnaHQuaWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgICAgICAgICAgd2Via2l0Lm1lc3NhZ2VIYW5kbGVycy5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0hJR0hMSUdIVF9cIikgPj0gMCkge1xuICAgICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgICAgICAgICBBbmRyb2lkLmhpZ2hsaWdodEFjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QxLmxlZnQgPCByZWN0Mi5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIubGVmdCA8IHJlY3QxLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIubGVmdCwgcmVjdDEucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0MS50b3AgPCByZWN0Mi5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLnRvcCA8IHJlY3QxLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLnRvcCwgcmVjdDEuYm90dG9tLCB0b2xlcmFuY2UpKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhyZWN0cykge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIC0xKSkge1xuICAgICAgICBsZXQgdG9BZGQgPSBbXTtcbiAgICAgICAgbGV0IHRvUmVtb3ZlO1xuICAgICAgICBsZXQgdG9QcmVzZXJ2ZTtcbiAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czEgPSByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICB0b1ByZXNlcnZlID0gcmVjdDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czIgPSByZWN0U3VidHJhY3QocmVjdDIsIHJlY3QxKTtcbiAgICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoIDwgc3VidHJhY3RSZWN0czIubGVuZ3RoKSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICAgIHRvUHJlc2VydmUgPSByZWN0MjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMjtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDI7XG4gICAgICAgICAgICB0b1ByZXNlcnZlID0gcmVjdDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zdCB0b0NoZWNrID0gW107XG4gICAgICAgICAgdG9DaGVjay5wdXNoKHRvUHJlc2VydmUpO1xuICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRvQ2hlY2ssIHRvQWRkKTtcbiAgICAgICAgICBjaGVja092ZXJsYXBzKHRvQ2hlY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGBDTElFTlQgUkVDVDogb3ZlcmxhcCwgY3V0IG9uZSByZWN0IGludG8gJHt0b0FkZC5sZW5ndGh9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gdG9SZW1vdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShuZXdSZWN0cywgdG9BZGQpO1xuICAgICAgICByZXR1cm4gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhuZXdSZWN0cyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gY2hlY2tPdmVybGFwcyhyZWN0cykge1xuICBjb25zdCBzdGlsbE92ZXJsYXBpbmdSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJlY3QxIG9mIHJlY3RzKSB7XG4gICAgZm9yIChjb25zdCByZWN0MiBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhhczEgPSBzdGlsbE92ZXJsYXBpbmdSZWN0cy5pbmRleE9mKHJlY3QxKSA+PSAwO1xuICAgICAgY29uc3QgaGFzMiA9IHN0aWxsT3ZlcmxhcGluZ1JlY3RzLmluZGV4T2YocmVjdDIpID49IDA7XG4gICAgICBpZiAoIWhhczEgfHwgIWhhczIpIHtcbiAgICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgICBpZiAoIWhhczEpIHtcbiAgICAgICAgICAgIHN0aWxsT3ZlcmxhcGluZ1JlY3RzLnB1c2gocmVjdDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWhhczIpIHtcbiAgICAgICAgICAgIHN0aWxsT3ZlcmxhcGluZ1JlY3RzLnB1c2gocmVjdDIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiBvdmVybGFwIC0tLVwiKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAjMSBUT1A6JHtyZWN0MS50b3B9IEJPVFRPTToke3JlY3QxLmJvdHRvbX0gTEVGVDoke3JlY3QxLmxlZnR9IFJJR0hUOiR7cmVjdDEucmlnaHR9IFdJRFRIOiR7cmVjdDEud2lkdGh9IEhFSUdIVDoke3JlY3QxLmhlaWdodH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAjMiBUT1A6JHtyZWN0Mi50b3B9IEJPVFRPTToke3JlY3QyLmJvdHRvbX0gTEVGVDoke3JlY3QyLmxlZnR9IFJJR0hUOiR7cmVjdDIucmlnaHR9IFdJRFRIOiR7cmVjdDIud2lkdGh9IEhFSUdIVDoke3JlY3QyLmhlaWdodH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCB4T3ZlcmxhcCA9IGdldFJlY3RPdmVybGFwWChyZWN0MSwgcmVjdDIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGB4T3ZlcmxhcDogJHt4T3ZlcmxhcH1gKTtcbiAgICAgICAgICBjb25zdCB5T3ZlcmxhcCA9IGdldFJlY3RPdmVybGFwWShyZWN0MSwgcmVjdDIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGB5T3ZlcmxhcDogJHt5T3ZlcmxhcH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoc3RpbGxPdmVybGFwaW5nUmVjdHMubGVuZ3RoKSB7XG4gICAgY29uc29sZS5sb2coYENMSUVOVCBSRUNUOiBvdmVybGFwcyAke3N0aWxsT3ZlcmxhcGluZ1JlY3RzLmxlbmd0aH1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVDb250YWluZWRSZWN0cyhyZWN0cywgdG9sZXJhbmNlKSB7XG4gIGNvbnN0IHJlY3RzVG9LZWVwID0gbmV3IFNldChyZWN0cyk7XG4gIGZvciAoY29uc3QgcmVjdCBvZiByZWN0cykge1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggPiAxICYmIHJlY3QuaGVpZ2h0ID4gMTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgdGlueVwiKTtcbiAgICAgIH1cbiAgICAgIHJlY3RzVG9LZWVwLmRlbGV0ZShyZWN0KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHBvc3NpYmx5Q29udGFpbmluZ1JlY3Qgb2YgcmVjdHMpIHtcbiAgICAgIGlmIChyZWN0ID09PSBwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFyZWN0c1RvS2VlcC5oYXMocG9zc2libHlDb250YWluaW5nUmVjdCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdENvbnRhaW5zKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QsIHJlY3QsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBjb250YWluZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20ocmVjdHNUb0tlZXApO1xufVxuXG5mdW5jdGlvbiBhbG1vc3RFcXVhbChhLCBiLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8PSB0b2xlcmFuY2U7XG59XG5cbmZ1bmN0aW9uIHJlY3RJbnRlcnNlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IG1heExlZnQgPSBNYXRoLm1heChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgbWluUmlnaHQgPSBNYXRoLm1pbihyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCBtYXhUb3AgPSBNYXRoLm1heChyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IG1pbkJvdHRvbSA9IE1hdGgubWluKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgY29uc3QgcmVjdCA9IHtcbiAgICBib3R0b206IG1pbkJvdHRvbSxcbiAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIG1pbkJvdHRvbSAtIG1heFRvcCksXG4gICAgbGVmdDogbWF4TGVmdCxcbiAgICByaWdodDogbWluUmlnaHQsXG4gICAgdG9wOiBtYXhUb3AsXG4gICAgd2lkdGg6IE1hdGgubWF4KDAsIG1pblJpZ2h0IC0gbWF4TGVmdCksXG4gIH07XG4gIHJldHVybiByZWN0O1xufVxuXG5mdW5jdGlvbiByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IHJlY3RJbnRlcnNlY3RlZCA9IHJlY3RJbnRlcnNlY3QocmVjdDIsIHJlY3QxKTtcbiAgaWYgKHJlY3RJbnRlcnNlY3RlZC5oZWlnaHQgPT09IDAgfHwgcmVjdEludGVyc2VjdGVkLndpZHRoID09PSAwKSB7XG4gICAgcmV0dXJuIFtyZWN0MV07XG4gIH1cbiAgY29uc3QgcmVjdHMgPSBbXTtcbiAge1xuICAgIGNvbnN0IHJlY3RBID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0MS5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RBLndpZHRoID0gcmVjdEEucmlnaHQgLSByZWN0QS5sZWZ0O1xuICAgIHJlY3RBLmhlaWdodCA9IHJlY3RBLmJvdHRvbSAtIHJlY3RBLnRvcDtcbiAgICBpZiAocmVjdEEuaGVpZ2h0ICE9PSAwICYmIHJlY3RBLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RBKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RCID0ge1xuICAgICAgYm90dG9tOiByZWN0SW50ZXJzZWN0ZWQudG9wLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RCLndpZHRoID0gcmVjdEIucmlnaHQgLSByZWN0Qi5sZWZ0O1xuICAgIHJlY3RCLmhlaWdodCA9IHJlY3RCLmJvdHRvbSAtIHJlY3RCLnRvcDtcbiAgICBpZiAocmVjdEIuaGVpZ2h0ICE9PSAwICYmIHJlY3RCLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RCKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RDID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3RJbnRlcnNlY3RlZC5ib3R0b20sXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RDLndpZHRoID0gcmVjdEMucmlnaHQgLSByZWN0Qy5sZWZ0O1xuICAgIHJlY3RDLmhlaWdodCA9IHJlY3RDLmJvdHRvbSAtIHJlY3RDLnRvcDtcbiAgICBpZiAocmVjdEMuaGVpZ2h0ICE9PSAwICYmIHJlY3RDLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RDKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3REID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICByaWdodDogcmVjdDEucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEQud2lkdGggPSByZWN0RC5yaWdodCAtIHJlY3RELmxlZnQ7XG4gICAgcmVjdEQuaGVpZ2h0ID0gcmVjdEQuYm90dG9tIC0gcmVjdEQudG9wO1xuICAgIGlmIChyZWN0RC5oZWlnaHQgIT09IDAgJiYgcmVjdEQud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWluc1BvaW50KHJlY3QsIHgsIHksIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0LmxlZnQgPCB4IHx8IGFsbW9zdEVxdWFsKHJlY3QubGVmdCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5yaWdodCA+IHggfHwgYWxtb3N0RXF1YWwocmVjdC5yaWdodCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC50b3AgPCB5IHx8IGFsbW9zdEVxdWFsKHJlY3QudG9wLCB5LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LmJvdHRvbSA+IHkgfHwgYWxtb3N0RXF1YWwocmVjdC5ib3R0b20sIHksIHRvbGVyYW5jZSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWlucyhyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKVxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IGxlZnQgPSBNYXRoLm1pbihyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgcmlnaHQgPSBNYXRoLm1heChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCB0b3AgPSBNYXRoLm1pbihyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IGJvdHRvbSA9IE1hdGgubWF4KHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgcmV0dXJuIHtcbiAgICBib3R0b20sXG4gICAgaGVpZ2h0OiBib3R0b20gLSB0b3AsXG4gICAgbGVmdCxcbiAgICByaWdodCxcbiAgICB0b3AsXG4gICAgd2lkdGg6IHJpZ2h0IC0gbGVmdCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICByZWN0cyxcbiAgdG9sZXJhbmNlLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwibWVyZ2VUb3VjaGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0c0xpbmVVcFZlcnRpY2FsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIubGVmdCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCBob3Jpem9udGFsQWxsb3dlZCA9ICFkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzO1xuICAgICAgY29uc3QgYWxpZ25lZCA9XG4gICAgICAgIChyZWN0c0xpbmVVcEhvcml6b250YWxseSAmJiBob3Jpem9udGFsQWxsb3dlZCkgfHxcbiAgICAgICAgKHJlY3RzTGluZVVwVmVydGljYWxseSAmJiAhcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkpO1xuICAgICAgY29uc3QgY2FuTWVyZ2UgPSBhbGlnbmVkICYmIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpO1xuICAgICAgaWYgKGNhbk1lcmdlKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGBDTElFTlQgUkVDVDogbWVyZ2luZyB0d28gaW50byBvbmUsIFZFUlRJQ0FMOiAke3JlY3RzTGluZVVwVmVydGljYWxseX0gSE9SSVpPTlRBTDogJHtyZWN0c0xpbmVVcEhvcml6b250YWxseX0gKCR7ZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c30pYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gcmVjdDEgJiYgcmVjdCAhPT0gcmVjdDI7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXBsYWNlbWVudENsaWVudFJlY3QgPSBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgbmV3UmVjdHMucHVzaChyZXBsYWNlbWVudENsaWVudFJlY3QpO1xuICAgICAgICByZXR1cm4gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgICAgICAgIG5ld1JlY3RzLFxuICAgICAgICAgIHRvbGVyYW5jZSxcbiAgICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAocmFuZ2UsIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMpIHtcbiAgY29uc3QgcmFuZ2VDbGllbnRSZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG4gIHJldHVybiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcF8oXG4gICAgcmFuZ2VDbGllbnRSZWN0cyxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwXyhcbiAgY2xpZW50UmVjdHMsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBjb25zdCB0b2xlcmFuY2UgPSAxO1xuICBjb25zdCBvcmlnaW5hbFJlY3RzID0gW107XG4gIGZvciAoY29uc3QgcmFuZ2VDbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgb3JpZ2luYWxSZWN0cy5wdXNoKHtcbiAgICAgIGJvdHRvbTogcmFuZ2VDbGllbnRSZWN0LmJvdHRvbSxcbiAgICAgIGhlaWdodDogcmFuZ2VDbGllbnRSZWN0LmhlaWdodCxcbiAgICAgIGxlZnQ6IHJhbmdlQ2xpZW50UmVjdC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5yaWdodCxcbiAgICAgIHRvcDogcmFuZ2VDbGllbnRSZWN0LnRvcCxcbiAgICAgIHdpZHRoOiByYW5nZUNsaWVudFJlY3Qud2lkdGgsXG4gICAgfSk7XG4gIH1cbiAgY29uc3QgbWVyZ2VkUmVjdHMgPSBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gICAgb3JpZ2luYWxSZWN0cyxcbiAgICB0b2xlcmFuY2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICBjb25zdCBub0NvbnRhaW5lZFJlY3RzID0gcmVtb3ZlQ29udGFpbmVkUmVjdHMobWVyZ2VkUmVjdHMsIHRvbGVyYW5jZSk7XG4gIGNvbnN0IG5ld1JlY3RzID0gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhub0NvbnRhaW5lZFJlY3RzKTtcbiAgY29uc3QgbWluQXJlYSA9IDIgKiAyO1xuICBmb3IgKGxldCBqID0gbmV3UmVjdHMubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICBjb25zdCByZWN0ID0gbmV3UmVjdHNbal07XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCAqIHJlY3QuaGVpZ2h0ID4gbWluQXJlYTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgaWYgKG5ld1JlY3RzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBzbWFsbFwiKTtcbiAgICAgICAgfVxuICAgICAgICBuZXdSZWN0cy5zcGxpY2UoaiwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsLCBidXQga2VlcCBvdGhlcndpc2UgZW1wdHkhXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoSVNfREVWKSB7XG4gICAgY2hlY2tPdmVybGFwcyhuZXdSZWN0cyk7XG4gIH1cbiAgaWYgKElTX0RFVikge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYENMSUVOVCBSRUNUOiByZWR1Y2VkICR7b3JpZ2luYWxSZWN0cy5sZW5ndGh9IC0tPiAke25ld1JlY3RzLmxlbmd0aH1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4gbmV3UmVjdHM7XG59XG5cbmZ1bmN0aW9uIGlzUGFnaW5hdGVkKGRvY3VtZW50KSB7XG4gIHJldHVybiAoXG4gICAgZG9jdW1lbnQgJiZcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiZcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX1BBR0lOQVRFRClcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCkge1xuICBpZiAoZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCkge1xuICAgIHJldHVybiBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50O1xuICB9XG4gIHJldHVybiBkb2N1bWVudC5ib2R5O1xufVxuXG5mdW5jdGlvbiBlbnN1cmVDb250YWluZXIod2luLCBhbm5vdGF0aW9uRmxhZykge1xuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBpZiAoIV9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgaWYgKCFib2R5RXZlbnRMaXN0ZW5lcnNTZXQpIHtcbiAgICAgIGJvZHlFdmVudExpc3RlbmVyc1NldCA9IHRydWU7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwibW91c2Vkb3duXCIsXG4gICAgICAgIChldikgPT4ge1xuICAgICAgICAgIGxhc3RNb3VzZURvd25YID0gZXYuY2xpZW50WDtcbiAgICAgICAgICBsYXN0TW91c2VEb3duWSA9IGV2LmNsaWVudFk7XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcIm1vdXNldXBcIixcbiAgICAgICAgKGV2KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgTWF0aC5hYnMobGFzdE1vdXNlRG93blggLSBldi5jbGllbnRYKSA8IDMgJiZcbiAgICAgICAgICAgIE1hdGguYWJzKGxhc3RNb3VzZURvd25ZIC0gZXYuY2xpZW50WSkgPCAzXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcIm1vdXNlbW92ZVwiLFxuICAgICAgICAoZXYpID0+IHtcbiAgICAgICAgICBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJ0b3VjaGVuZFwiLFxuICAgICAgICBmdW5jdGlvbiB0b3VjaEVuZChlKSB7XG4gICAgICAgICAgcHJvY2Vzc1RvdWNoRXZlbnQod2luLCBlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgfVxuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBJRF9ISUdITElHSFRTX0NPTlRBSU5FUik7XG5cbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChfaGlnaGxpZ2h0c0NvbnRhaW5lcik7XG4gIH1cblxuICByZXR1cm4gX2hpZ2hsaWdodHNDb250YWluZXI7XG59XG5cbmZ1bmN0aW9uIGhpZGVBbGxoaWdobGlnaHRzKCkge1xuICBpZiAoX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5yZW1vdmUoKTtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lciA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVzdHJveUFsbGhpZ2hsaWdodHMoKSB7XG4gIGhpZGVBbGxoaWdobGlnaHRzKCk7XG4gIF9oaWdobGlnaHRzLnNwbGljZSgwLCBfaGlnaGxpZ2h0cy5sZW5ndGgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveUhpZ2hsaWdodChpZCkge1xuICBsZXQgaSA9IC0xO1xuICBsZXQgX2RvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoLCBqKSA9PiB7XG4gICAgaSA9IGo7XG4gICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICB9KTtcbiAgaWYgKGhpZ2hsaWdodCAmJiBpID49IDAgJiYgaSA8IF9oaWdobGlnaHRzLmxlbmd0aCkge1xuICAgIF9oaWdobGlnaHRzLnNwbGljZShpLCAxKTtcbiAgfVxuICBjb25zdCBoaWdobGlnaHRDb250YWluZXIgPSBfZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoaGlnaGxpZ2h0Q29udGFpbmVyKSB7XG4gICAgaGlnaGxpZ2h0Q29udGFpbmVyLnJlbW92ZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2ZpVGV4dE5vZGUobm9kZSkge1xuICByZXR1cm4gbm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREU7XG59XG5cbmZ1bmN0aW9uIGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChlbGVtZW50LCBjaGlsZCkge1xuICBsZXQgZm91bmQgPSAtMTtcbiAgbGV0IHRleHROb2RlSW5kZXggPSAtMTtcbiAgbGV0IHByZXZpb3VzV2FzRWxlbWVudCA9IGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkTm9kZSA9IGVsZW1lbnQuY2hpbGROb2Rlc1tpXTtcbiAgICBjb25zdCBpc1RleHQgPSBpc0NmaVRleHROb2RlKGNoaWxkTm9kZSk7XG4gICAgaWYgKGlzVGV4dCB8fCBwcmV2aW91c1dhc0VsZW1lbnQpIHtcbiAgICAgIHRleHROb2RlSW5kZXggKz0gMjtcbiAgICB9XG4gICAgaWYgKGlzVGV4dCkge1xuICAgICAgaWYgKGNoaWxkTm9kZSA9PT0gY2hpbGQpIHtcbiAgICAgICAgZm91bmQgPSB0ZXh0Tm9kZUluZGV4O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcHJldmlvdXNXYXNFbGVtZW50ID0gY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERTtcbiAgfVxuICByZXR1cm4gZm91bmQ7XG59XG5cbmZ1bmN0aW9uIGdldENvbW1vbkFuY2VzdG9yRWxlbWVudChub2RlMSwgbm9kZTIpIHtcbiAgaWYgKG5vZGUxLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMSA9PT0gbm9kZTIpIHtcbiAgICByZXR1cm4gbm9kZTE7XG4gIH1cbiAgaWYgKG5vZGUxLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMS5jb250YWlucyhub2RlMikpIHtcbiAgICByZXR1cm4gbm9kZTE7XG4gIH1cbiAgaWYgKG5vZGUyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMi5jb250YWlucyhub2RlMSkpIHtcbiAgICByZXR1cm4gbm9kZTI7XG4gIH1cbiAgY29uc3Qgbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbiA9IFtdO1xuICBsZXQgcGFyZW50ID0gbm9kZTEucGFyZW50Tm9kZTtcbiAgd2hpbGUgKHBhcmVudCAmJiBwYXJlbnQubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbi5wdXNoKHBhcmVudCk7XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XG4gIH1cbiAgY29uc3Qgbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbiA9IFtdO1xuICBwYXJlbnQgPSBub2RlMi5wYXJlbnROb2RlO1xuICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluLnB1c2gocGFyZW50KTtcbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgfVxuICBsZXQgY29tbW9uQW5jZXN0b3IgPSBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluLmZpbmQoXG4gICAgKG5vZGUxRWxlbWVudEFuY2VzdG9yKSA9PiB7XG4gICAgICByZXR1cm4gbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbi5pbmRleE9mKG5vZGUxRWxlbWVudEFuY2VzdG9yKSA+PSAwO1xuICAgIH1cbiAgKTtcbiAgaWYgKCFjb21tb25BbmNlc3Rvcikge1xuICAgIGNvbW1vbkFuY2VzdG9yID0gbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbi5maW5kKChub2RlMkVsZW1lbnRBbmNlc3RvcikgPT4ge1xuICAgICAgcmV0dXJuIG5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4uaW5kZXhPZihub2RlMkVsZW1lbnRBbmNlc3RvcikgPj0gMDtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gY29tbW9uQW5jZXN0b3I7XG59XG5cbmZ1bmN0aW9uIGZ1bGxRdWFsaWZpZWRTZWxlY3Rvcihub2RlKSB7XG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIGNvbnN0IGxvd2VyQ2FzZU5hbWUgPVxuICAgICAgKG5vZGUubG9jYWxOYW1lICYmIG5vZGUubG9jYWxOYW1lLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgICBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgcmV0dXJuIGxvd2VyQ2FzZU5hbWU7XG4gIH1cbiAgLy9yZXR1cm4gY3NzUGF0aChub2RlLCBqdXN0U2VsZWN0b3IpO1xuICByZXR1cm4gY3NzUGF0aChub2RlLCB0cnVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvKCkge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmICghc2VsZWN0aW9uKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIENPTExBUFNFRC5cIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYXdUZXh0ID0gc2VsZWN0aW9uLnRvU3RyaW5nKCk7XG4gIGNvbnN0IGNsZWFuVGV4dCA9IHJhd1RleHQudHJpbSgpLnJlcGxhY2UoL1xcbi9nLCBcIiBcIikucmVwbGFjZSgvXFxzXFxzKy9nLCBcIiBcIik7XG4gIGlmIChjbGVhblRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIFRFWFQgRU1QVFkuXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFzZWxlY3Rpb24uYW5jaG9yTm9kZSB8fCAhc2VsZWN0aW9uLmZvY3VzTm9kZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2UgPVxuICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxXG4gICAgICA/IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApXG4gICAgICA6IGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0XG4gICAgICAgICk7XG4gIGlmICghcmFuZ2UgfHwgcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCIkJCQkJCQkJCQkJCQkJCQkJCBDQU5OT1QgR0VUIE5PTi1DT0xMQVBTRUQgU0VMRUNUSU9OIFJBTkdFPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYW5nZUluZm8gPSBjb252ZXJ0UmFuZ2UocmFuZ2UsIGZ1bGxRdWFsaWZpZWRTZWxlY3RvciwgY29tcHV0ZUNGSSk7XG4gIGlmICghcmFuZ2VJbmZvKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIFJBTkdFIElORk8gRkFJTD8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoSVNfREVWICYmIERFQlVHX1ZJU1VBTFMpIHtcbiAgICBjb25zdCByZXN0b3JlZFJhbmdlID0gY29udmVydFJhbmdlSW5mbyh3aW4uZG9jdW1lbnQsIHJhbmdlSW5mbyk7XG4gICAgaWYgKHJlc3RvcmVkUmFuZ2UpIHtcbiAgICAgIGlmIChcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydE9mZnNldCA9PT0gcmFuZ2Uuc3RhcnRPZmZzZXQgJiZcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRPZmZzZXQgPT09IHJhbmdlLmVuZE9mZnNldCAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5zdGFydENvbnRhaW5lciAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLmVuZENvbnRhaW5lciA9PT0gcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgICApIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJTRUxFQ1RJT04gUkFOR0UgUkVTVE9SRUQgT0tBWSAoZGV2IGNoZWNrKS5cIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhcIlNFTEVDVElPTiBSQU5HRSBSRVNUT1JFIEZBSUwgKGRldiBjaGVjaykuXCIpO1xuICAgICAgICBkdW1wRGVidWcoXG4gICAgICAgICAgXCJTRUxFQ1RJT05cIixcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIk9SREVSRUQgUkFOR0UgRlJPTSBTRUxFQ1RJT05cIixcbiAgICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgICAgICByYW5nZS5zdGFydE9mZnNldCxcbiAgICAgICAgICByYW5nZS5lbmRDb250YWluZXIsXG4gICAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIlJFU1RPUkVEIFJBTkdFXCIsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kQ29udGFpbmVyLFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiQ0FOTk9UIFJFU1RPUkUgU0VMRUNUSU9OIFJBTkdFID8/IVwiKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGxvY2F0aW9uczogcmFuZ2VJbmZvMkxvY2F0aW9uKHJhbmdlSW5mbyksXG4gICAgdGV4dDoge1xuICAgICAgaGlnaGxpZ2h0OiByYXdUZXh0LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNoZWNrQmxhY2tsaXN0ZWQoZWwpIHtcbiAgbGV0IGJsYWNrbGlzdGVkSWQ7XG4gIGNvbnN0IGlkID0gZWwuZ2V0QXR0cmlidXRlKFwiaWRcIik7XG4gIGlmIChpZCAmJiBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSS5pbmRleE9mKGlkKSA+PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJjaGVja0JsYWNrbGlzdGVkIElEOiBcIiArIGlkKTtcbiAgICBibGFja2xpc3RlZElkID0gaWQ7XG4gIH1cbiAgbGV0IGJsYWNrbGlzdGVkQ2xhc3M7XG4gIGZvciAoY29uc3QgaXRlbSBvZiBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoaXRlbSkpIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiY2hlY2tCbGFja2xpc3RlZCBDTEFTUzogXCIgKyBpdGVtKTtcbiAgICAgIGJsYWNrbGlzdGVkQ2xhc3MgPSBpdGVtO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChibGFja2xpc3RlZElkIHx8IGJsYWNrbGlzdGVkQ2xhc3MpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY3NzUGF0aChub2RlLCBvcHRpbWl6ZWQpIHtcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cblxuICBjb25zdCBzdGVwcyA9IFtdO1xuICBsZXQgY29udGV4dE5vZGUgPSBub2RlO1xuICB3aGlsZSAoY29udGV4dE5vZGUpIHtcbiAgICBjb25zdCBzdGVwID0gX2Nzc1BhdGhTdGVwKGNvbnRleHROb2RlLCAhIW9wdGltaXplZCwgY29udGV4dE5vZGUgPT09IG5vZGUpO1xuICAgIGlmICghc3RlcCkge1xuICAgICAgYnJlYWs7IC8vIEVycm9yIC0gYmFpbCBvdXQgZWFybHkuXG4gICAgfVxuICAgIHN0ZXBzLnB1c2goc3RlcC52YWx1ZSk7XG4gICAgaWYgKHN0ZXAub3B0aW1pemVkKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY29udGV4dE5vZGUgPSBjb250ZXh0Tm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHN0ZXBzLnJldmVyc2UoKTtcbiAgcmV0dXJuIHN0ZXBzLmpvaW4oXCIgPiBcIik7XG59XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4vLyBodHRwczovL2Nocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vYmxpbmsvKy9tYXN0ZXIvU291cmNlL2RldnRvb2xzL2Zyb250X2VuZC9jb21wb25lbnRzL0RPTVByZXNlbnRhdGlvblV0aWxzLmpzIzMxNlxuZnVuY3Rpb24gX2Nzc1BhdGhTdGVwKG5vZGUsIG9wdGltaXplZCwgaXNUYXJnZXROb2RlKSB7XG4gIGZ1bmN0aW9uIHByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMobmQpIHtcbiAgICBjb25zdCBjbGFzc0F0dHJpYnV0ZSA9IG5kLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpO1xuICAgIGlmICghY2xhc3NBdHRyaWJ1dGUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NBdHRyaWJ1dGVcbiAgICAgIC5zcGxpdCgvXFxzKy9nKVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLm1hcCgobm0pID0+IHtcbiAgICAgICAgLy8gVGhlIHByZWZpeCBpcyByZXF1aXJlZCB0byBzdG9yZSBcIl9fcHJvdG9fX1wiIGluIGEgb2JqZWN0LWJhc2VkIG1hcC5cbiAgICAgICAgcmV0dXJuIFwiJFwiICsgbm07XG4gICAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlkU2VsZWN0b3IoaWRkKSB7XG4gICAgcmV0dXJuIFwiI1wiICsgZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkKGlkZCk7XG4gIH1cblxuICBmdW5jdGlvbiBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQoaWRlbnQpIHtcbiAgICBpZiAoaXNDU1NJZGVudGlmaWVyKGlkZW50KSkge1xuICAgICAgcmV0dXJuIGlkZW50O1xuICAgIH1cblxuICAgIGNvbnN0IHNob3VsZEVzY2FwZUZpcnN0ID0gL14oPzpbMC05XXwtWzAtOS1dPykvLnRlc3QoaWRlbnQpO1xuICAgIGNvbnN0IGxhc3RJbmRleCA9IGlkZW50Lmxlbmd0aCAtIDE7XG4gICAgcmV0dXJuIGlkZW50LnJlcGxhY2UoLy4vZywgZnVuY3Rpb24gKGMsIGlpKSB7XG4gICAgICByZXR1cm4gKHNob3VsZEVzY2FwZUZpcnN0ICYmIGlpID09PSAwKSB8fCAhaXNDU1NJZGVudENoYXIoYylcbiAgICAgICAgPyBlc2NhcGVBc2NpaUNoYXIoYywgaWkgPT09IGxhc3RJbmRleClcbiAgICAgICAgOiBjO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZXNjYXBlQXNjaWlDaGFyKGMsIGlzTGFzdCkge1xuICAgIHJldHVybiBcIlxcXFxcIiArIHRvSGV4Qnl0ZShjKSArIChpc0xhc3QgPyBcIlwiIDogXCIgXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9IZXhCeXRlKGMpIHtcbiAgICBsZXQgaGV4Qnl0ZSA9IGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNik7XG4gICAgaWYgKGhleEJ5dGUubGVuZ3RoID09PSAxKSB7XG4gICAgICBoZXhCeXRlID0gXCIwXCIgKyBoZXhCeXRlO1xuICAgIH1cbiAgICByZXR1cm4gaGV4Qnl0ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQ1NTSWRlbnRDaGFyKGMpIHtcbiAgICBpZiAoL1thLXpBLVowLTlfLV0vLnRlc3QoYykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gYy5jaGFyQ29kZUF0KDApID49IDB4YTA7XG4gIH1cblxuICBmdW5jdGlvbiBpc0NTU0lkZW50aWZpZXIodmFsdWUpIHtcbiAgICByZXR1cm4gL14tP1thLXpBLVpfXVthLXpBLVowLTlfLV0qJC8udGVzdCh2YWx1ZSk7XG4gIH1cblxuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGxvd2VyQ2FzZU5hbWUgPVxuICAgIChub2RlLmxvY2FsTmFtZSAmJiBub2RlLmxvY2FsTmFtZS50b0xvd2VyQ2FzZSgpKSB8fFxuICAgIG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuICBjb25zdCBlbGVtZW50ID0gbm9kZTtcblxuICBjb25zdCBpZCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaWRcIik7XG5cbiAgaWYgKG9wdGltaXplZCkge1xuICAgIGlmIChpZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3B0aW1pemVkOiB0cnVlLFxuICAgICAgICB2YWx1ZTogaWRTZWxlY3RvcihpZCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBsb3dlckNhc2VOYW1lID09PSBcImJvZHlcIiB8fFxuICAgICAgbG93ZXJDYXNlTmFtZSA9PT0gXCJoZWFkXCIgfHxcbiAgICAgIGxvd2VyQ2FzZU5hbWUgPT09IFwiaHRtbFwiXG4gICAgKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICAgIHZhbHVlOiBsb3dlckNhc2VOYW1lLCAvLyBub2RlLm5vZGVOYW1lSW5Db3JyZWN0Q2FzZSgpLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBub2RlTmFtZSA9IGxvd2VyQ2FzZU5hbWU7IC8vIG5vZGUubm9kZU5hbWVJbkNvcnJlY3RDYXNlKCk7XG4gIGlmIChpZCkge1xuICAgIHJldHVybiB7XG4gICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICB2YWx1ZTogbm9kZU5hbWUgKyBpZFNlbGVjdG9yKGlkKSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuXG4gIGlmICghcGFyZW50IHx8IHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5ET0NVTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgIHZhbHVlOiBub2RlTmFtZSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfID0gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhlbGVtZW50KTtcblxuICBjb25zdCBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheSA9IFtdOyAvLyAua2V5U2V0KClcbiAgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfLmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICBpZiAocHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkuaW5kZXhPZihhcnJJdGVtKSA8IDApIHtcbiAgICAgIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5LnB1c2goYXJySXRlbSk7XG4gICAgfVxuICB9KTtcblxuICBsZXQgbmVlZHNDbGFzc05hbWVzID0gZmFsc2U7XG4gIGxldCBuZWVkc050aENoaWxkID0gZmFsc2U7XG4gIGxldCBvd25JbmRleCA9IC0xO1xuICBsZXQgZWxlbWVudEluZGV4ID0gLTE7XG4gIGNvbnN0IHNpYmxpbmdzID0gcGFyZW50LmNoaWxkcmVuO1xuXG4gIGZvciAoXG4gICAgbGV0IGkgPSAwO1xuICAgIChvd25JbmRleCA9PT0gLTEgfHwgIW5lZWRzTnRoQ2hpbGQpICYmIGkgPCBzaWJsaW5ncy5sZW5ndGg7XG4gICAgKytpXG4gICkge1xuICAgIGNvbnN0IHNpYmxpbmcgPSBzaWJsaW5nc1tpXTtcbiAgICBpZiAoc2libGluZy5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBlbGVtZW50SW5kZXggKz0gMTtcbiAgICBpZiAoc2libGluZyA9PT0gbm9kZSkge1xuICAgICAgb3duSW5kZXggPSBlbGVtZW50SW5kZXg7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKG5lZWRzTnRoQ2hpbGQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHNpYmxpbmcubm9kZU5hbWVJbkNvcnJlY3RDYXNlKClcbiAgICBjb25zdCBzaWJsaW5nTmFtZSA9XG4gICAgICAoc2libGluZy5sb2NhbE5hbWUgJiYgc2libGluZy5sb2NhbE5hbWUudG9Mb3dlckNhc2UoKSkgfHxcbiAgICAgIHNpYmxpbmcubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoc2libGluZ05hbWUgIT09IG5vZGVOYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbmVlZHNDbGFzc05hbWVzID0gdHJ1ZTtcblxuICAgIGNvbnN0IG93bkNsYXNzTmFtZXMgPSBbXTtcbiAgICBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheS5mb3JFYWNoKChhcnJJdGVtKSA9PiB7XG4gICAgICBvd25DbGFzc05hbWVzLnB1c2goYXJySXRlbSk7XG4gICAgfSk7XG4gICAgbGV0IG93bkNsYXNzTmFtZUNvdW50ID0gb3duQ2xhc3NOYW1lcy5sZW5ndGg7XG5cbiAgICBpZiAob3duQ2xhc3NOYW1lQ291bnQgPT09IDApIHtcbiAgICAgIG5lZWRzTnRoQ2hpbGQgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHNpYmxpbmdDbGFzc05hbWVzQXJyYXlfID0gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhzaWJsaW5nKTtcbiAgICBjb25zdCBzaWJsaW5nQ2xhc3NOYW1lc0FycmF5ID0gW107IC8vIC5rZXlTZXQoKVxuICAgIHNpYmxpbmdDbGFzc05hbWVzQXJyYXlfLmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICAgIGlmIChzaWJsaW5nQ2xhc3NOYW1lc0FycmF5LmluZGV4T2YoYXJySXRlbSkgPCAwKSB7XG4gICAgICAgIHNpYmxpbmdDbGFzc05hbWVzQXJyYXkucHVzaChhcnJJdGVtKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgc2libGluZ0NsYXNzIG9mIHNpYmxpbmdDbGFzc05hbWVzQXJyYXkpIHtcbiAgICAgIGNvbnN0IGluZCA9IG93bkNsYXNzTmFtZXMuaW5kZXhPZihzaWJsaW5nQ2xhc3MpO1xuICAgICAgaWYgKGluZCA8IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIG93bkNsYXNzTmFtZXMuc3BsaWNlKGluZCwgMSk7IC8vIGRlbGV0ZSBvd25DbGFzc05hbWVzW3NpYmxpbmdDbGFzc107XG5cbiAgICAgIGlmICghLS1vd25DbGFzc05hbWVDb3VudCkge1xuICAgICAgICBuZWVkc050aENoaWxkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHJlc3VsdCA9IG5vZGVOYW1lO1xuICBpZiAoXG4gICAgaXNUYXJnZXROb2RlICYmXG4gICAgbm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJlxuICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwidHlwZVwiKSAmJlxuICAgICFlbGVtZW50LmdldEF0dHJpYnV0ZShcImlkXCIpICYmXG4gICAgIWVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIilcbiAgKSB7XG4gICAgcmVzdWx0ICs9ICdbdHlwZT1cIicgKyBlbGVtZW50LmdldEF0dHJpYnV0ZShcInR5cGVcIikgKyAnXCJdJztcbiAgfVxuICBpZiAobmVlZHNOdGhDaGlsZCkge1xuICAgIHJlc3VsdCArPSBcIjpudGgtY2hpbGQoXCIgKyAob3duSW5kZXggKyAxKSArIFwiKVwiO1xuICB9IGVsc2UgaWYgKG5lZWRzQ2xhc3NOYW1lcykge1xuICAgIGZvciAoY29uc3QgcHJlZml4ZWROYW1lIG9mIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5KSB7XG4gICAgICByZXN1bHQgKz0gXCIuXCIgKyBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQocHJlZml4ZWROYW1lLnN1YnN0cigxKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBvcHRpbWl6ZWQ6IGZhbHNlLFxuICAgIHZhbHVlOiByZXN1bHQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVDRkkobm9kZSkge1xuICAvLyBUT0RPOiBoYW5kbGUgY2hhcmFjdGVyIHBvc2l0aW9uIGluc2lkZSB0ZXh0IG5vZGVcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxldCBjZmkgPSBcIlwiO1xuXG4gIGxldCBjdXJyZW50RWxlbWVudCA9IG5vZGU7XG4gIHdoaWxlIChcbiAgICBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlICYmXG4gICAgY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgKSB7XG4gICAgY29uc3QgYmxhY2tsaXN0ZWQgPSBjaGVja0JsYWNrbGlzdGVkKGN1cnJlbnRFbGVtZW50KTtcbiAgICBpZiAoIWJsYWNrbGlzdGVkKSB7XG4gICAgICBjb25zdCBjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuID0gY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZS5jaGlsZHJlbjtcbiAgICAgIGxldCBjdXJyZW50RWxlbWVudEluZGV4ID0gLTE7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGN1cnJlbnRFbGVtZW50ID09PSBjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuW2ldKSB7XG4gICAgICAgICAgY3VycmVudEVsZW1lbnRJbmRleCA9IGk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50RWxlbWVudEluZGV4ID49IDApIHtcbiAgICAgICAgY29uc3QgY2ZpSW5kZXggPSAoY3VycmVudEVsZW1lbnRJbmRleCArIDEpICogMjtcbiAgICAgICAgY2ZpID1cbiAgICAgICAgICBjZmlJbmRleCArXG4gICAgICAgICAgKGN1cnJlbnRFbGVtZW50LmlkID8gXCJbXCIgKyBjdXJyZW50RWxlbWVudC5pZCArIFwiXVwiIDogXCJcIikgK1xuICAgICAgICAgIChjZmkubGVuZ3RoID8gXCIvXCIgKyBjZmkgOiBcIlwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY3VycmVudEVsZW1lbnQgPSBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlO1xuICB9XG5cbiAgcmV0dXJuIFwiL1wiICsgY2ZpO1xufVxuXG5mdW5jdGlvbiBfY3JlYXRlSGlnaGxpZ2h0KGxvY2F0aW9ucywgY29sb3IsIHBvaW50ZXJJbnRlcmFjdGlvbiwgdHlwZSkge1xuICBjb25zdCByYW5nZUluZm8gPSBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb25zKTtcbiAgY29uc3QgdW5pcXVlU3RyID0gYCR7cmFuZ2VJbmZvLmNmaX0ke3JhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcn0ke3JhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleH0ke3JhbmdlSW5mby5zdGFydE9mZnNldH0ke3JhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3J9JHtyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4fSR7cmFuZ2VJbmZvLmVuZE9mZnNldH1gO1xuXG4gIGNvbnN0IGhhc2ggPSByZXF1aXJlKFwiaGFzaC5qc1wiKTtcbiAgY29uc3Qgc2hhMjU2SGV4ID0gaGFzaC5zaGEyNTYoKS51cGRhdGUodW5pcXVlU3RyKS5kaWdlc3QoXCJoZXhcIik7XG5cbiAgdmFyIGlkO1xuICBpZiAodHlwZSA9PSBJRF9ISUdITElHSFRTX0NPTlRBSU5FUikge1xuICAgIGlkID0gXCJSMl9ISUdITElHSFRfXCIgKyBzaGEyNTZIZXg7XG4gIH0gZWxzZSB7XG4gICAgaWQgPSBcIlIyX0FOTk9UQVRJT05fXCIgKyBzaGEyNTZIZXg7XG4gIH1cblxuICBkZXN0cm95SGlnaGxpZ2h0KGlkKTtcblxuICBjb25zdCBoaWdobGlnaHQgPSB7XG4gICAgY29sb3I6IGNvbG9yID8gY29sb3IgOiBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IsXG4gICAgaWQsXG4gICAgcG9pbnRlckludGVyYWN0aW9uLFxuICAgIHJhbmdlSW5mbyxcbiAgfTtcbiAgX2hpZ2hsaWdodHMucHVzaChoaWdobGlnaHQpO1xuICBjcmVhdGVIaWdobGlnaHREb20oXG4gICAgd2luZG93LFxuICAgIGhpZ2hsaWdodCxcbiAgICB0eXBlID09IElEX0FOTk9UQVRJT05fQ09OVEFJTkVSID8gdHJ1ZSA6IGZhbHNlXG4gICk7XG5cbiAgcmV0dXJuIGhpZ2hsaWdodDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhpZ2hsaWdodChzZWxlY3Rpb25JbmZvLCBjb2xvciwgcG9pbnRlckludGVyYWN0aW9uKSB7XG4gIHJldHVybiBfY3JlYXRlSGlnaGxpZ2h0KFxuICAgIHNlbGVjdGlvbkluZm8sXG4gICAgY29sb3IsXG4gICAgcG9pbnRlckludGVyYWN0aW9uLFxuICAgIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBbm5vdGF0aW9uKGlkKSB7XG4gIGxldCBpID0gLTE7XG5cbiAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCwgaikgPT4ge1xuICAgIGkgPSBqO1xuICAgIHJldHVybiBoLmlkID09PSBpZDtcbiAgfSk7XG4gIGlmIChpID09IF9oaWdobGlnaHRzLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHZhciBsb2NhdGlvbnMgPSB7XG4gICAgbG9jYXRpb25zOiByYW5nZUluZm8yTG9jYXRpb24oaGlnaGxpZ2h0LnJhbmdlSW5mbyksXG4gIH07XG5cbiAgcmV0dXJuIF9jcmVhdGVIaWdobGlnaHQoXG4gICAgbG9jYXRpb25zLFxuICAgIGhpZ2hsaWdodC5jb2xvcixcbiAgICB0cnVlLFxuICAgIElEX0FOTk9UQVRJT05fQ09OVEFJTkVSXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUhpZ2hsaWdodERvbSh3aW4sIGhpZ2hsaWdodCwgYW5ub3RhdGlvbkZsYWcpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG5cbiAgY29uc3Qgc2NhbGUgPVxuICAgIDEgL1xuICAgICh3aW4uUkVBRElVTTIgJiYgd2luLlJFQURJVU0yLmlzRml4ZWRMYXlvdXRcbiAgICAgID8gd2luLlJFQURJVU0yLmZ4bFZpZXdwb3J0U2NhbGVcbiAgICAgIDogMSk7XG5cbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuXG4gIGNvbnN0IHJhbmdlID0gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgaGlnaGxpZ2h0LnJhbmdlSW5mbyk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBoaWdobGlnaHRzQ29udGFpbmVyID0gZW5zdXJlQ29udGFpbmVyKHdpbiwgYW5ub3RhdGlvbkZsYWcpO1xuICBjb25zdCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG4gIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBoaWdobGlnaHQuaWQpO1xuICBoaWdobGlnaHRQYXJlbnQuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUik7XG5cbiAgZG9jdW1lbnQuYm9keS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcbiAgaGlnaGxpZ2h0UGFyZW50LnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICBpZiAoaGlnaGxpZ2h0LnBvaW50ZXJJbnRlcmFjdGlvbikge1xuICAgIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJkYXRhLWNsaWNrXCIsIFwiMVwiKTtcbiAgfVxuXG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgY29uc3QgdXNlU1ZHID0gIURFQlVHX1ZJU1VBTFMgJiYgVVNFX1NWRztcbiAgLy9jb25zdCB1c2VTVkcgPSBVU0VfU1ZHO1xuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgbGV0IGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnO1xuICBjb25zdCByb3VuZGVkQ29ybmVyID0gMztcbiAgY29uc3QgdW5kZXJsaW5lVGhpY2tuZXNzID0gMjtcbiAgY29uc3Qgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgPSAzO1xuICBjb25zdCBvcGFjaXR5ID0gREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFk7XG4gIGxldCBleHRyYSA9IFwiXCI7XG4gIGNvbnN0IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdCA9XG4gICAgZnJhbWVGb3JIaWdobGlnaHRBbm5vdGF0aW9uTWFya1dpdGhJRCh3aW4sIGhpZ2hsaWdodC5pZCk7XG5cbiAgbGV0IHhPZmZzZXQ7XG4gIGxldCB5T2Zmc2V0O1xuICBsZXQgYW5ub3RhdGlvbk9mZnNldDtcblxuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0IDogYm9keVJlY3QubGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICAgIGFubm90YXRpb25PZmZzZXQgPVxuICAgICAgcGFyc2VJbnQoXG4gICAgICAgIChyYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QucmlnaHQgLSB4T2Zmc2V0KSAvIHdpbmRvdy5pbm5lcldpZHRoXG4gICAgICApICsgMTtcbiAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICAgIGFubm90YXRpb25PZmZzZXQgPSBwYXJzZUludChcbiAgICAgIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5yaWdodCAvIHdpbmRvdy5pbm5lcldpZHRoICsgMVxuICAgICk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBpZiAodXNlU1ZHKSB7XG4gICAgICBjb25zdCBib3JkZXJUaGlja25lc3MgPSAwO1xuICAgICAgaWYgKCFoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZykge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdSZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICBTVkdfWE1MX05BTUVTUEFDRSxcbiAgICAgICAgXCJyZWN0XCJcbiAgICAgICk7XG5cbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICBgZmlsbDogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pICFpbXBvcnRhbnQ7IGZpbGwtb3BhY2l0eTogJHtvcGFjaXR5fSAhaW1wb3J0YW50OyBzdHJva2Utd2lkdGg6IDA7YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNjYWxlID0gc2NhbGU7XG5cbiAgICAgIC8qXG4gICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdCA9IHtcbiAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAqL1xuXG4gICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwicnhcIiwgYCR7cm91bmRlZENvcm5lciAqIHNjYWxlfWApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwicnlcIiwgYCR7cm91bmRlZENvcm5lciAqIHNjYWxlfWApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInhcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QubGVmdCAtIGJvcmRlclRoaWNrbmVzcykgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInlcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QudG9wIC0gYm9yZGVyVGhpY2tuZXNzKSAqIHNjYWxlfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0LmhlaWdodCArIGJvcmRlclRoaWNrbmVzcyAqIDIpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJ3aWR0aFwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC53aWR0aCArIGJvcmRlclRoaWNrbmVzcyAqIDIpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnLmFwcGVuZENoaWxkKGhpZ2hsaWdodEFyZWFTVkdSZWN0KTtcbiAgICAgIGlmIChkcmF3VW5kZXJsaW5lKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICAgIFwibGluZVwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgICBgc3Ryb2tlLWxpbmVjYXA6IHJvdW5kOyBzdHJva2Utd2lkdGg6ICR7XG4gICAgICAgICAgICB1bmRlcmxpbmVUaGlja25lc3MgKiBzY2FsZVxuICAgICAgICAgIH07IHN0cm9rZTogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSkgIWltcG9ydGFudDsgc3Ryb2tlLW9wYWNpdHk6ICR7b3BhY2l0eX0gIWltcG9ydGFudGBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGluZU9mZnNldCA9XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCA+IHJvdW5kZWRDb3JuZXIgPyByb3VuZGVkQ29ybmVyIDogMDtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDFcIixcbiAgICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICsgbGluZU9mZnNldCkgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngyXCIsXG4gICAgICAgICAgYCR7XG4gICAgICAgICAgICAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICtcbiAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAtXG4gICAgICAgICAgICAgIGxpbmVPZmZzZXQpICpcbiAgICAgICAgICAgIHNjYWxlXG4gICAgICAgICAgfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgeSA9XG4gICAgICAgICAgKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QudG9wICtcbiAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0IC1cbiAgICAgICAgICAgIHVuZGVybGluZVRoaWNrbmVzcyAvIDIpICpcbiAgICAgICAgICBzY2FsZTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTFcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTJcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIndpZHRoXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0QXJlYVNWR0xpbmUpO1xuICAgICAgfVxuICAgICAgaWYgKGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICAgIFwibGluZVwiXG4gICAgICAgICk7XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICAgIGBzdHJva2UtbGluZWNhcDogYnV0dDsgc3Ryb2tlLXdpZHRoOiAke1xuICAgICAgICAgICAgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgKiBzY2FsZVxuICAgICAgICAgIH07IHN0cm9rZTogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSkgIWltcG9ydGFudDsgc3Ryb2tlLW9wYWNpdHk6ICR7b3BhY2l0eX0gIWltcG9ydGFudGBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2NhbGUgPSBzY2FsZTtcblxuICAgICAgICAvKlxuICAgICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngxXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ4MlwiLFxuICAgICAgICAgIGAke1xuICAgICAgICAgICAgKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QubGVmdCArIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGgpICpcbiAgICAgICAgICAgIHNjYWxlXG4gICAgICAgICAgfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbGluZU9mZnNldCA9IGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgY29uc3QgeSA9IChoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LnRvcCArIGxpbmVPZmZzZXQpICogc2NhbGU7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkxXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkyXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcImhlaWdodFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0ICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ3aWR0aFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGggKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnLmFwcGVuZENoaWxkKGhpZ2hsaWdodEFyZWFTVkdMaW5lKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgICAgIGhpZ2hsaWdodEFyZWEuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuXG4gICAgICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgICAgICBjb25zdCByZ2IgPSBNYXRoLnJvdW5kKDB4ZmZmZmZmICogTWF0aC5yYW5kb20oKSk7XG4gICAgICAgIGNvbnN0IHIgPSByZ2IgPj4gMTY7XG4gICAgICAgIGNvbnN0IGcgPSAocmdiID4+IDgpICYgMjU1O1xuICAgICAgICBjb25zdCBiID0gcmdiICYgMjU1O1xuICAgICAgICBleHRyYSA9IGBvdXRsaW5lLWNvbG9yOiByZ2IoJHtyfSwgJHtnfSwgJHtifSk7IG91dGxpbmUtc3R5bGU6IHNvbGlkOyBvdXRsaW5lLXdpZHRoOiAxcHg7IG91dGxpbmUtb2Zmc2V0OiAtMXB4O2A7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZHJhd1VuZGVybGluZSkge1xuICAgICAgICAgIGV4dHJhICs9IGBib3JkZXItYm90dG9tOiAke3VuZGVybGluZVRoaWNrbmVzcyAqIHNjYWxlfXB4IHNvbGlkIHJnYmEoJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5yZWRcbiAgICAgICAgICB9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7XG4gICAgICAgICAgICBoaWdobGlnaHQuY29sb3IuYmx1ZVxuICAgICAgICAgIH0sICR7b3BhY2l0eX0pICFpbXBvcnRhbnRgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoaWdobGlnaHRBcmVhLnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICBgYm9yZGVyLXJhZGl1czogJHtyb3VuZGVkQ29ybmVyfXB4ICFpbXBvcnRhbnQ7IGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDsgJHtleHRyYX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gICAgICBoaWdobGlnaHRBcmVhLnNjYWxlID0gc2NhbGU7XG4gICAgICAvKlxuICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAqL1xuICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnJlY3QgPSB7XG4gICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLndpZHRoID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LndpZHRoICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5oZWlnaHQgPSBgJHtoaWdobGlnaHRBcmVhLnJlY3QuaGVpZ2h0ICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5sZWZ0ID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LmxlZnQgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnRvcCA9IGAke2hpZ2hsaWdodEFyZWEucmVjdC50b3AgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRQYXJlbnQuYXBwZW5kKGhpZ2hsaWdodEFyZWEpO1xuICAgICAgaWYgKCFERUJVR19WSVNVQUxTICYmIGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIC8vaWYgKGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgICAgYGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDtgXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdCA9IHtcbiAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqL1xuXG4gICAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS53aWR0aCA9IGAke1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3Qud2lkdGggKiBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5oZWlnaHQgPSBgJHtcbiAgICAgICAgICBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyAqIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLmxlZnQgPSBgJHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0LmxlZnQgKiBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS50b3AgPSBgJHtcbiAgICAgICAgICAoaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC50b3AgK1xuICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC5oZWlnaHQgLyAyIC1cbiAgICAgICAgICAgIHN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzIC8gMikgKlxuICAgICAgICAgIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYUxpbmUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZykge1xuICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX1hNTF9OQU1FU1BBQ0UsIFwic3ZnXCIpO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc2V0QXR0cmlidXRlKFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS5vdmVyZmxvdyA9IFwidmlzaWJsZVwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUubGVmdCA9IFwiMFwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUudG9wID0gXCIwXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5hcHBlbmQoaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcpO1xuICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYVNWRyk7XG4gIH1cblxuICBjb25zdCBoaWdobGlnaHRCb3VuZGluZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBKTtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXG4gICAgICBcInN0eWxlXCIsXG4gICAgICBgYm9yZGVyLXJhZGl1czogJHtyb3VuZGVkQ29ybmVyfXB4ICFpbXBvcnRhbnQ7IGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDsgJHtleHRyYX1gXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSk7XG4gIH1cblxuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnNjYWxlID0gc2NhbGU7XG5cbiAgaWYgKERFQlVHX1ZJU1VBTFMpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXG4gICAgICBcInN0eWxlXCIsXG4gICAgICBgb3V0bGluZS1jb2xvcjogbWFnZW50YTsgb3V0bGluZS1zdHlsZTogc29saWQ7IG91dGxpbmUtd2lkdGg6IDFweDsgb3V0bGluZS1vZmZzZXQ6IC0xcHg7YFxuICAgICk7XG4gIH1cblxuICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5yZWN0ID0ge1xuICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QgPSByYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5yZWN0ID0ge1xuICAgICAgaGVpZ2h0OiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgIHRvcDogcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgIHdpZHRoOiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9O1xuICB9XG5cbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUud2lkdGggPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LndpZHRoICogc2NhbGV9cHhgO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5oZWlnaHQgPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LmhlaWdodCAqIHNjYWxlfXB4YDtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUubGVmdCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3QubGVmdCAqIHNjYWxlfXB4YDtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUudG9wID0gYCR7aGlnaGxpZ2h0Qm91bmRpbmcucmVjdC50b3AgKiBzY2FsZX1weGA7XG5cbiAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRCb3VuZGluZyk7XG4gIGhpZ2hsaWdodHNDb250YWluZXIuYXBwZW5kKGhpZ2hsaWdodFBhcmVudCk7XG5cbiAgcmV0dXJuIGhpZ2hsaWdodFBhcmVudDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT3JkZXJlZFJhbmdlKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQsIGVuZE5vZGUsIGVuZE9mZnNldCkge1xuICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZS5zZXRTdGFydChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIGlmICghcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGNvbnNvbGUubG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBDT0xMQVBTRUQgLi4uIFJBTkdFIFJFVkVSU0U/XCIpO1xuICBjb25zdCByYW5nZVJldmVyc2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2VSZXZlcnNlLnNldFN0YXJ0KGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRFbmQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIGlmICghcmFuZ2VSZXZlcnNlLmNvbGxhcHNlZCkge1xuICAgIGNvbnNvbGUubG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIE9LLlwiKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgY29uc29sZS5sb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgQUxTTyBDT0xMQVBTRUQ/IVwiKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gY29udmVydFJhbmdlKHJhbmdlLCBnZXRDc3NTZWxlY3RvciwgY29tcHV0ZUVsZW1lbnRDRkkpIHtcbiAgY29uc3Qgc3RhcnRJc0VsZW1lbnQgPSByYW5nZS5zdGFydENvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyRWxlbWVudCA9IHN0YXJ0SXNFbGVtZW50XG4gICAgPyByYW5nZS5zdGFydENvbnRhaW5lclxuICAgIDogcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZSAmJlxuICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICA/IHJhbmdlLnN0YXJ0Q29udGFpbmVyLnBhcmVudE5vZGVcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKCFzdGFydENvbnRhaW5lckVsZW1lbnQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID0gc3RhcnRJc0VsZW1lbnRcbiAgICA/IC0xXG4gICAgOiBBcnJheS5mcm9tKHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzKS5pbmRleE9mKFxuICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lclxuICAgICAgKTtcbiAgaWYgKHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IDwgLTEpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yID0gZ2V0Q3NzU2VsZWN0b3IoXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50XG4gICk7XG4gIGNvbnN0IGVuZElzRWxlbWVudCA9IHJhbmdlLmVuZENvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7XG4gIGNvbnN0IGVuZENvbnRhaW5lckVsZW1lbnQgPSBlbmRJc0VsZW1lbnRcbiAgICA/IHJhbmdlLmVuZENvbnRhaW5lclxuICAgIDogcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGUgJiZcbiAgICAgIHJhbmdlLmVuZENvbnRhaW5lci5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgID8gcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGVcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKCFlbmRDb250YWluZXJFbGVtZW50KSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPSBlbmRJc0VsZW1lbnRcbiAgICA/IC0xXG4gICAgOiBBcnJheS5mcm9tKGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2RlcykuaW5kZXhPZihyYW5nZS5lbmRDb250YWluZXIpO1xuICBpZiAoZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IDwgLTEpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciA9IGdldENzc1NlbGVjdG9yKGVuZENvbnRhaW5lckVsZW1lbnQpO1xuICBjb25zdCBjb21tb25FbGVtZW50QW5jZXN0b3IgPSBnZXRDb21tb25BbmNlc3RvckVsZW1lbnQoXG4gICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2UuZW5kQ29udGFpbmVyXG4gICk7XG4gIGlmICghY29tbW9uRWxlbWVudEFuY2VzdG9yKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gTk8gUkFOR0UgQ09NTU9OIEFOQ0VTVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAocmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIpIHtcbiAgICBjb25zdCByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCA9XG4gICAgICByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICAgICAgPyByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lclxuICAgICAgICA6IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQgJiZcbiAgICAgIHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50Lm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgICkge1xuICAgICAgaWYgKGNvbW1vbkVsZW1lbnRBbmNlc3RvciAhPT0gcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCI+Pj4+Pj4gQ09NTU9OIEFOQ0VTVE9SIENPTlRBSU5FUiBESUZGPz8hXCIpO1xuICAgICAgICBjb25zb2xlLmxvZyhnZXRDc3NTZWxlY3Rvcihjb21tb25FbGVtZW50QW5jZXN0b3IpKTtcbiAgICAgICAgY29uc29sZS5sb2coZ2V0Q3NzU2VsZWN0b3IocmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3Qgcm9vdEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShjb21tb25FbGVtZW50QW5jZXN0b3IpO1xuICBjb25zdCBzdGFydEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShzdGFydENvbnRhaW5lckVsZW1lbnQpO1xuICBjb25zdCBlbmRFbGVtZW50Q2ZpID0gY29tcHV0ZUVsZW1lbnRDRkkoZW5kQ29udGFpbmVyRWxlbWVudCk7XG4gIGxldCBjZmk7XG4gIGlmIChyb290RWxlbWVudENmaSAmJiBzdGFydEVsZW1lbnRDZmkgJiYgZW5kRWxlbWVudENmaSkge1xuICAgIGxldCBzdGFydEVsZW1lbnRPclRleHRDZmkgPSBzdGFydEVsZW1lbnRDZmk7XG4gICAgaWYgKCFzdGFydElzRWxlbWVudCkge1xuICAgICAgY29uc3Qgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkgPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXJcbiAgICAgICk7XG4gICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICBzdGFydEVsZW1lbnRDZmkgK1xuICAgICAgICBcIi9cIiArXG4gICAgICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpICtcbiAgICAgICAgXCI6XCIgK1xuICAgICAgICByYW5nZS5zdGFydE9mZnNldDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICByYW5nZS5zdGFydE9mZnNldCA+PSAwICYmXG4gICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0IDwgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgY2hpbGROb2RlID0gc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2Uuc3RhcnRPZmZzZXRdO1xuICAgICAgICBpZiAoY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIChyYW5nZS5zdGFydE9mZnNldCArIDEpICogMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBjZmlUZXh0Tm9kZUluZGV4ID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LFxuICAgICAgICAgICAgY2hpbGROb2RlXG4gICAgICAgICAgKTtcbiAgICAgICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPSBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIGNmaVRleHROb2RlSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNmaUluZGV4T2ZMYXN0RWxlbWVudCA9XG4gICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkRWxlbWVudENvdW50ICogMjtcbiAgICAgICAgY29uc3QgbGFzdENoaWxkTm9kZSA9XG4gICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbXG4gICAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggLSAxXG4gICAgICAgICAgXTtcbiAgICAgICAgaWYgKGxhc3RDaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIChjZmlJbmRleE9mTGFzdEVsZW1lbnQgKyAyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBsZXQgZW5kRWxlbWVudE9yVGV4dENmaSA9IGVuZEVsZW1lbnRDZmk7XG4gICAgaWYgKCFlbmRJc0VsZW1lbnQpIHtcbiAgICAgIGNvbnN0IGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSA9IGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChcbiAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgICApO1xuICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgIGVuZEVsZW1lbnRDZmkgK1xuICAgICAgICBcIi9cIiArXG4gICAgICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSArXG4gICAgICAgIFwiOlwiICtcbiAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIHJhbmdlLmVuZE9mZnNldCA+PSAwICYmXG4gICAgICAgIHJhbmdlLmVuZE9mZnNldCA8IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2UuZW5kT2Zmc2V0XTtcbiAgICAgICAgaWYgKGNoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID0gZW5kRWxlbWVudENmaSArIFwiL1wiICsgKHJhbmdlLmVuZE9mZnNldCArIDEpICogMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBjZmlUZXh0Tm9kZUluZGV4ID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgICAgIGNoaWxkTm9kZVxuICAgICAgICAgICk7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9IGVuZEVsZW1lbnRDZmkgKyBcIi9cIiArIGNmaVRleHROb2RlSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNmaUluZGV4T2ZMYXN0RWxlbWVudCA9IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQgKiAyO1xuICAgICAgICBjb25zdCBsYXN0Q2hpbGROb2RlID1cbiAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbXG4gICAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoIC0gMVxuICAgICAgICAgIF07XG4gICAgICAgIGlmIChsYXN0Q2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgZW5kRWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgZW5kRWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNmaSA9XG4gICAgICByb290RWxlbWVudENmaSArXG4gICAgICBcIixcIiArXG4gICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkucmVwbGFjZShyb290RWxlbWVudENmaSwgXCJcIikgK1xuICAgICAgXCIsXCIgK1xuICAgICAgZW5kRWxlbWVudE9yVGV4dENmaS5yZXBsYWNlKHJvb3RFbGVtZW50Q2ZpLCBcIlwiKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGNmaSxcbiAgICBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIGVuZE9mZnNldDogcmFuZ2UuZW5kT2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiByYW5nZS5zdGFydE9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgcmFuZ2VJbmZvKSB7XG4gIGNvbnN0IHN0YXJ0RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghc3RhcnRFbGVtZW50KSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBTVEFSVCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IHN0YXJ0Q29udGFpbmVyID0gc3RhcnRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBzdGFydENvbnRhaW5lciA9XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICBjb25zdCBlbmRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghZW5kRWxlbWVudCkge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gRU5EIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgZW5kQ29udGFpbmVyID0gZW5kRWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVuZENvbnRhaW5lciA9XG4gICAgICBlbmRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICBzdGFydENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uc3RhcnRPZmZzZXQsXG4gICAgZW5kQ29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5lbmRPZmZzZXRcbiAgKTtcbn1cblxuZnVuY3Rpb24gZnJhbWVGb3JIaWdobGlnaHRBbm5vdGF0aW9uTWFya1dpdGhJRCh3aW4sIGlkKSB7XG4gIGxldCBjbGllbnRSZWN0cyA9IGZyYW1lRm9ySGlnaGxpZ2h0V2l0aElEKGlkKTtcbiAgaWYgKCFjbGllbnRSZWN0cykgcmV0dXJuO1xuXG4gIHZhciB0b3BDbGllbnRSZWN0ID0gY2xpZW50UmVjdHNbMF07XG4gIHZhciBtYXhIZWlnaHQgPSB0b3BDbGllbnRSZWN0LmhlaWdodDtcbiAgZm9yIChjb25zdCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgaWYgKGNsaWVudFJlY3QudG9wIDwgdG9wQ2xpZW50UmVjdC50b3ApIHRvcENsaWVudFJlY3QgPSBjbGllbnRSZWN0O1xuICAgIGlmIChjbGllbnRSZWN0LmhlaWdodCA+IG1heEhlaWdodCkgbWF4SGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQ7XG4gIH1cblxuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeU9mZnNldDtcbiAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICB2YXIgbmV3VG9wID0gdG9wQ2xpZW50UmVjdC50b3A7XG5cbiAgaWYgKF9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgZG8ge1xuICAgICAgdmFyIGJvdW5kaW5nQXJlYXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFxuICAgICAgICBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcbiAgICAgICk7XG4gICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgIC8vZm9yIChsZXQgaSA9IDAsIGxlbmd0aCA9IGJvdW5kaW5nQXJlYXMuc25hcHNob3RMZW5ndGg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgZm9yIChcbiAgICAgICAgdmFyIGkgPSAwLCBsZW4gPSBib3VuZGluZ0FyZWFzLmxlbmd0aCB8IDA7XG4gICAgICAgIGkgPCBsZW47XG4gICAgICAgIGkgPSAoaSArIDEpIHwgMFxuICAgICAgKSB7XG4gICAgICAgIHZhciBib3VuZGluZ0FyZWEgPSBib3VuZGluZ0FyZWFzW2ldO1xuICAgICAgICBpZiAoTWF0aC5hYnMoYm91bmRpbmdBcmVhLnJlY3QudG9wIC0gKG5ld1RvcCAtIHlPZmZzZXQpKSA8IDMpIHtcbiAgICAgICAgICBuZXdUb3AgKz0gYm91bmRpbmdBcmVhLnJlY3QuaGVpZ2h0O1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gd2hpbGUgKGZvdW5kKTtcbiAgfVxuXG4gIHRvcENsaWVudFJlY3QudG9wID0gbmV3VG9wO1xuICB0b3BDbGllbnRSZWN0LmhlaWdodCA9IG1heEhlaWdodDtcblxuICByZXR1cm4gdG9wQ2xpZW50UmVjdDtcbn1cblxuZnVuY3Rpb24gaGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGxldCBpID0gLTE7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzLmZpbmQoKGgsIGopID0+IHtcbiAgICBpID0gajtcbiAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gIH0pO1xuICByZXR1cm4gaGlnaGxpZ2h0O1xufVxuXG5mdW5jdGlvbiBmcmFtZUZvckhpZ2hsaWdodFdpdGhJRChpZCkge1xuICBjb25zdCBoaWdobGlnaHQgPSBoaWdobGlnaHRXaXRoSUQoaWQpO1xuICBpZiAoIWhpZ2hsaWdodCkgcmV0dXJuO1xuXG4gIGNvbnN0IGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHJhbmdlID0gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgaGlnaGxpZ2h0LnJhbmdlSW5mbyk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgZHJhd1VuZGVybGluZSA9IGZhbHNlO1xuICBjb25zdCBkcmF3U3RyaWtlVGhyb3VnaCA9IGZhbHNlO1xuICBjb25zdCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gZHJhd1VuZGVybGluZSB8fCBkcmF3U3RyaWtlVGhyb3VnaDtcbiAgLy9jb25zdCBjbGllbnRSZWN0cyA9IERFQlVHX1ZJU1VBTFMgPyByYW5nZS5nZXRDbGllbnRSZWN0cygpIDpcbiAgY29uc3QgY2xpZW50UmVjdHMgPSBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgICByYW5nZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG5cbiAgcmV0dXJuIGNsaWVudFJlY3RzO1xufVxuXG5mdW5jdGlvbiByYW5nZUluZm8yTG9jYXRpb24ocmFuZ2VJbmZvKSB7XG4gIHJldHVybiB7XG4gICAgY3NzU2VsZWN0b3I6IHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICBwYXJ0aWFsQ2ZpOiByYW5nZUluZm8uY2ZpLFxuICAgIGRvbVJhbmdlOiB7XG4gICAgICBzdGFydDoge1xuICAgICAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgICAgICB0ZXh0Tm9kZUluZGV4OiByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgICAgIG9mZnNldDogcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgICAgfSxcbiAgICAgIGVuZDoge1xuICAgICAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICAgICAgdGV4dE5vZGVJbmRleDogcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICAgICAgb2Zmc2V0OiByYW5nZUluZm8uZW5kT2Zmc2V0LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb24pIHtcbiAgY29uc3QgbG9jYXRpb25zID0gbG9jYXRpb24ubG9jYXRpb25zO1xuICBjb25zdCBkb21SYW5nZSA9IGxvY2F0aW9ucy5kb21SYW5nZTtcbiAgY29uc3Qgc3RhcnQgPSBkb21SYW5nZS5zdGFydDtcbiAgY29uc3QgZW5kID0gZG9tUmFuZ2UuZW5kO1xuXG4gIHJldHVybiB7XG4gICAgY2ZpOiBsb2NhdGlvbi5wYXJ0aWFsQ2ZpLFxuICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogZW5kLnRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBlbmQuY3NzU2VsZWN0b3IsXG4gICAgZW5kT2Zmc2V0OiBlbmQub2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBzdGFydC50ZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBzdGFydC5jc3NTZWxlY3RvcixcbiAgICBzdGFydE9mZnNldDogc3RhcnQub2Zmc2V0LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IGhpZ2hsaWdodFdpdGhJRChpZCk7XG4gIGlmICghaGlnaGxpZ2h0KSByZXR1cm47XG5cbiAgY29uc3QgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgcmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCBoaWdobGlnaHQucmFuZ2VJbmZvKTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgdmFyIHNpemUgPSB7XG4gICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgIHNjcmVlbkhlaWdodDogd2luZG93Lm91dGVySGVpZ2h0LFxuICAgIGxlZnQ6IGNsaWVudFJlY3RzWzBdLmxlZnQsXG4gICAgd2lkdGg6IGNsaWVudFJlY3RzWzBdLndpZHRoLFxuICAgIHRvcDogY2xpZW50UmVjdHNbMF0udG9wLFxuICAgIGhlaWdodDogY2xpZW50UmVjdHNbMF0uaGVpZ2h0LFxuICB9O1xuXG4gIHJldHVybiBzaXplO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0aW9uUmVjdCgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciByYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuXG4gICAgY29uc3QgY2xpZW50UmVjdCA9IHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdmFyIGhhbmRsZUJvdW5kcyA9IHtcbiAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgIHNjcmVlbkhlaWdodDogd2luZG93Lm91dGVySGVpZ2h0LFxuICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0LFxuICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICB0b3A6IGNsaWVudFJlY3QudG9wLFxuICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICB9O1xuICAgIHJldHVybiBoYW5kbGVCb3VuZHM7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0U2Nyb2xsTW9kZShmbGFnKSB7XG4gIGlmICghZmxhZykge1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX1BBR0lOQVRFRCk7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfUEFHSU5BVEVEKTtcbiAgfVxufVxuXG4vKlxuIGlmIChkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKSB7IC8vIElFID49IDk7IG90aGVyIGJyb3dzZXJzXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgLy9hbGVydChcIllvdSd2ZSB0cmllZCB0byBvcGVuIGNvbnRleHQgbWVudVwiKTsgLy9oZXJlIHlvdSBkcmF3IHlvdXIgb3duIG1lbnVcbiAgICAgICAgICAgIC8vZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgLy9sZXQgZ2V0Q3NzU2VsZWN0b3IgPSBmdWxsUXVhbGlmaWVkU2VsZWN0b3I7XG4gICAgICAgICAgICBcblx0XHRcdGxldCBzdHIgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG5cdFx0XHRsZXQgc2VsZWN0aW9uSW5mbyA9IGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvKCk7XG5cdFx0XHRsZXQgcG9zID0gY3JlYXRlSGlnaGxpZ2h0KHNlbGVjdGlvbkluZm8se3JlZDoxMCxncmVlbjo1MCxibHVlOjIzMH0sdHJ1ZSk7XG5cdFx0XHRsZXQgcmV0MiA9IGNyZWF0ZUFubm90YXRpb24ocG9zLmlkKTtcblx0XHRcdFxuICB9LCBmYWxzZSk7XG4gICAgfSBlbHNlIHsgLy8gSUUgPCA5XG4gICAgICAgIGRvY3VtZW50LmF0dGFjaEV2ZW50KCdvbmNvbnRleHRtZW51JywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBhbGVydChcIllvdSd2ZSB0cmllZCB0byBvcGVuIGNvbnRleHQgbWVudVwiKTtcbiAgICAgICAgICAgIHdpbmRvdy5ldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG4qL1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgbG9nIGFzIGxvZ05hdGl2ZSwgbG9nRXJyb3IsIHNuYXBDdXJyZW50T2Zmc2V0IH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IHRvTmF0aXZlUmVjdCB9IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IFRleHRSYW5nZSB9IGZyb20gXCIuL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90ZXh0LXJhbmdlXCI7XG5cbi8vIFBvbHlmaWxsIGZvciBBbmRyb2lkIEFQSSAyNlxuaW1wb3J0IG1hdGNoQWxsIGZyb20gXCJzdHJpbmcucHJvdG90eXBlLm1hdGNoYWxsXCI7XG5tYXRjaEFsbC5zaGltKCk7XG5cbmNvbnN0IGRlYnVnID0gdHJ1ZTtcblxuLy8gTm90aWZ5IG5hdGl2ZSBjb2RlIHRoYXQgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwibG9hZFwiLFxuICBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGlzU2VsZWN0aW5nID0gZmFsc2U7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2xsYXBzZWQgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuaXNDb2xsYXBzZWQ7XG5cbiAgICAgIGlmIChjb2xsYXBzZWQgJiYgaXNTZWxlY3RpbmcpIHtcbiAgICAgICAgaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgQW5kcm9pZC5vblNlbGVjdGlvbkVuZCgpO1xuICAgICAgICAvLyBTbmFwcyB0aGUgY3VycmVudCBjb2x1bW4gaW4gY2FzZSB0aGUgdXNlciBzaGlmdGVkIHRoZSBzY3JvbGwgYnkgZHJhZ2dpbmcgdGhlIHRleHQgc2VsZWN0aW9uLlxuICAgICAgICBzbmFwQ3VycmVudE9mZnNldCgpO1xuICAgICAgfSBlbHNlIGlmICghY29sbGFwc2VkICYmICFpc1NlbGVjdGluZykge1xuICAgICAgICBpc1NlbGVjdGluZyA9IHRydWU7XG4gICAgICAgIEFuZHJvaWQub25TZWxlY3Rpb25TdGFydCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICBmYWxzZVxuKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb24oKSB7XG4gIGNvbnN0IHRleHQgPSBnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCgpO1xuICBpZiAoIXRleHQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCByZWN0ID0gZ2V0U2VsZWN0aW9uUmVjdCgpO1xuICByZXR1cm4geyB0ZXh0LCByZWN0IH07XG59XG5cbmZ1bmN0aW9uIGdldFNlbGVjdGlvblJlY3QoKSB7XG4gIHRyeSB7XG4gICAgbGV0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmFuZ2UgPSBzZWwuZ2V0UmFuZ2VBdCgwKTtcblxuICAgIHJldHVybiB0b05hdGl2ZVJlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nRXJyb3IoZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvblRleHQoKSB7XG4gIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGhpZ2hsaWdodCA9IHNlbGVjdGlvbi50b1N0cmluZygpO1xuICBjb25zdCBjbGVhbkhpZ2hsaWdodCA9IGhpZ2hsaWdodFxuICAgIC50cmltKClcbiAgICAucmVwbGFjZSgvXFxuL2csIFwiIFwiKVxuICAgIC5yZXBsYWNlKC9cXHNcXHMrL2csIFwiIFwiKTtcbiAgaWYgKGNsZWFuSGlnaGxpZ2h0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFzZWxlY3Rpb24uYW5jaG9yTm9kZSB8fCAhc2VsZWN0aW9uLmZvY3VzTm9kZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2UgPVxuICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxXG4gICAgICA/IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApXG4gICAgICA6IGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0XG4gICAgICAgICk7XG4gIGlmICghcmFuZ2UgfHwgcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgbG9nKFwiJCQkJCQkJCQkJCQkJCQkJCQgQ0FOTk9UIEdFVCBOT04tQ09MTEFQU0VEIFNFTEVDVElPTiBSQU5HRT8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCB0ZXh0ID0gZG9jdW1lbnQuYm9keS50ZXh0Q29udGVudDtcbiAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhkb2N1bWVudC5ib2R5KTtcbiAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICBjb25zdCBlbmQgPSB0ZXh0UmFuZ2UuZW5kLm9mZnNldDtcblxuICBjb25zdCBzbmlwcGV0TGVuZ3RoID0gMjAwO1xuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYmVmb3JlIHRoZSBoaWdobGlnaHQsIGlnbm9yaW5nIHRoZSBmaXJzdCBcIndvcmRcIiwgd2hpY2ggbWlnaHQgYmUgY3V0LlxuICBsZXQgYmVmb3JlID0gdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIHNuaXBwZXRMZW5ndGgpLCBzdGFydCk7XG4gIGxldCBmaXJzdFdvcmRTdGFydCA9IGJlZm9yZS5zZWFyY2goL1xcUHtMfVxccHtMfS9ndSk7XG4gIGlmIChmaXJzdFdvcmRTdGFydCAhPT0gLTEpIHtcbiAgICBiZWZvcmUgPSBiZWZvcmUuc2xpY2UoZmlyc3RXb3JkU3RhcnQgKyAxKTtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYWZ0ZXIgdGhlIGhpZ2hsaWdodCwgaWdub3JpbmcgdGhlIGxhc3QgXCJ3b3JkXCIsIHdoaWNoIG1pZ2h0IGJlIGN1dC5cbiAgbGV0IGFmdGVyID0gdGV4dC5zbGljZShlbmQsIE1hdGgubWluKHRleHQubGVuZ3RoLCBlbmQgKyBzbmlwcGV0TGVuZ3RoKSk7XG4gIGxldCBsYXN0V29yZEVuZCA9IEFycmF5LmZyb20oYWZ0ZXIubWF0Y2hBbGwoL1xccHtMfVxcUHtMfS9ndSkpLnBvcCgpO1xuICBpZiAobGFzdFdvcmRFbmQgIT09IHVuZGVmaW5lZCAmJiBsYXN0V29yZEVuZC5pbmRleCA+IDEpIHtcbiAgICBhZnRlciA9IGFmdGVyLnNsaWNlKDAsIGxhc3RXb3JkRW5kLmluZGV4ICsgMSk7XG4gIH1cblxuICByZXR1cm4geyBoaWdobGlnaHQsIGJlZm9yZSwgYWZ0ZXIgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT3JkZXJlZFJhbmdlKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQsIGVuZE5vZGUsIGVuZE9mZnNldCkge1xuICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZS5zZXRTdGFydChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIGlmICghcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgQ09MTEFQU0VEIC4uLiBSQU5HRSBSRVZFUlNFP1wiKTtcbiAgY29uc3QgcmFuZ2VSZXZlcnNlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRTdGFydChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICByYW5nZVJldmVyc2Uuc2V0RW5kKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICBpZiAoIXJhbmdlUmV2ZXJzZS5jb2xsYXBzZWQpIHtcbiAgICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgT0suXCIpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgQUxTTyBDT0xMQVBTRUQ/IVwiKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIHJhbmdlSW5mbykge1xuICBjb25zdCBzdGFydEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIXN0YXJ0RWxlbWVudCkge1xuICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIFNUQVJUIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgc3RhcnRDb250YWluZXIgPSBzdGFydEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBzdGFydENvbnRhaW5lciA9XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCIpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgY29uc3QgZW5kRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIWVuZEVsZW1lbnQpIHtcbiAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBFTkQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBlbmRDb250YWluZXIgPSBlbmRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVuZENvbnRhaW5lciA9XG4gICAgICBlbmRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgIGVuZENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uZW5kT2Zmc2V0XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb24pIHtcbiAgY29uc3QgbG9jYXRpb25zID0gbG9jYXRpb24ubG9jYXRpb25zO1xuICBjb25zdCBkb21SYW5nZSA9IGxvY2F0aW9ucy5kb21SYW5nZTtcbiAgY29uc3Qgc3RhcnQgPSBkb21SYW5nZS5zdGFydDtcbiAgY29uc3QgZW5kID0gZG9tUmFuZ2UuZW5kO1xuXG4gIHJldHVybiB7XG4gICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBlbmQudGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IGVuZC5jc3NTZWxlY3RvcixcbiAgICBlbmRPZmZzZXQ6IGVuZC5vZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IHN0YXJ0LnRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IHN0YXJ0LmNzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiBzdGFydC5vZmZzZXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgbG9nTmF0aXZlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIEJhc2Ugc2NyaXB0IHVzZWQgYnkgYm90aCByZWZsb3dhYmxlIGFuZCBmaXhlZCBsYXlvdXQgcmVzb3VyY2VzLlxuXG5pbXBvcnQgXCIuL2dlc3R1cmVzXCI7XG5pbXBvcnQgXCIuL2tleWJvYXJkXCI7XG5pbXBvcnQge1xuICByZW1vdmVQcm9wZXJ0eSxcbiAgc2Nyb2xsTGVmdCxcbiAgc2Nyb2xsUmlnaHQsXG4gIHNjcm9sbFRvRW5kLFxuICBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1Bvc2l0aW9uLFxuICBzY3JvbGxUb1N0YXJ0LFxuICBzY3JvbGxUb1RleHQsXG4gIHNldFByb3BlcnR5LFxuICBzZXRDU1NQcm9wZXJ0aWVzLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgY3JlYXRlQW5ub3RhdGlvbixcbiAgY3JlYXRlSGlnaGxpZ2h0LFxuICBkZXN0cm95SGlnaGxpZ2h0LFxuICBnZXRDdXJyZW50U2VsZWN0aW9uSW5mbyxcbiAgZ2V0U2VsZWN0aW9uUmVjdCxcbiAgcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElELFxuICBzZXRTY3JvbGxNb2RlLFxufSBmcm9tIFwiLi9oaWdobGlnaHRcIjtcbmltcG9ydCB7IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yIH0gZnJvbSBcIi4vZG9tXCI7XG5pbXBvcnQgeyBnZXRDdXJyZW50U2VsZWN0aW9uIH0gZnJvbSBcIi4vc2VsZWN0aW9uXCI7XG5pbXBvcnQgeyBnZXREZWNvcmF0aW9ucywgcmVnaXN0ZXJUZW1wbGF0ZXMgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcblxuLy8gUHVibGljIEFQSSB1c2VkIGJ5IHRoZSBuYXZpZ2F0b3IuXG53aW5kb3cucmVhZGl1bSA9IHtcbiAgLy8gdXRpbHNcbiAgc2Nyb2xsVG9JZDogc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9Qb3NpdGlvbjogc2Nyb2xsVG9Qb3NpdGlvbixcbiAgc2Nyb2xsVG9UZXh0OiBzY3JvbGxUb1RleHQsXG4gIHNjcm9sbExlZnQ6IHNjcm9sbExlZnQsXG4gIHNjcm9sbFJpZ2h0OiBzY3JvbGxSaWdodCxcbiAgc2Nyb2xsVG9TdGFydDogc2Nyb2xsVG9TdGFydCxcbiAgc2Nyb2xsVG9FbmQ6IHNjcm9sbFRvRW5kLFxuICBzZXRDU1NQcm9wZXJ0aWVzOiBzZXRDU1NQcm9wZXJ0aWVzLFxuICBzZXRQcm9wZXJ0eTogc2V0UHJvcGVydHksXG4gIHJlbW92ZVByb3BlcnR5OiByZW1vdmVQcm9wZXJ0eSxcblxuICAvLyBzZWxlY3Rpb25cbiAgZ2V0Q3VycmVudFNlbGVjdGlvbjogZ2V0Q3VycmVudFNlbGVjdGlvbixcblxuICAvLyBkZWNvcmF0aW9uXG4gIHJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlczogcmVnaXN0ZXJUZW1wbGF0ZXMsXG4gIGdldERlY29yYXRpb25zOiBnZXREZWNvcmF0aW9ucyxcblxuICAvLyBET01cbiAgZmluZEZpcnN0VmlzaWJsZUxvY2F0b3I6IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yLFxufTtcblxuLy8gTGVnYWN5IGhpZ2hsaWdodHMgQVBJLlxud2luZG93LmNyZWF0ZUFubm90YXRpb24gPSBjcmVhdGVBbm5vdGF0aW9uO1xud2luZG93LmNyZWF0ZUhpZ2hsaWdodCA9IGNyZWF0ZUhpZ2hsaWdodDtcbndpbmRvdy5kZXN0cm95SGlnaGxpZ2h0ID0gZGVzdHJveUhpZ2hsaWdodDtcbndpbmRvdy5nZXRDdXJyZW50U2VsZWN0aW9uSW5mbyA9IGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvO1xud2luZG93LmdldFNlbGVjdGlvblJlY3QgPSBnZXRTZWxlY3Rpb25SZWN0O1xud2luZG93LnJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRCA9IHJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRDtcbndpbmRvdy5zZXRTY3JvbGxNb2RlID0gc2V0U2Nyb2xsTW9kZTtcbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIFNjcmlwdCB1c2VkIGZvciBmaXhlZCBsYXlvdXRzIHJlc291cmNlcy5cblxuaW1wb3J0IFwiLi9pbmRleFwiO1xuXG53aW5kb3cucmVhZGl1bS5pc0ZpeGVkTGF5b3V0ID0gdHJ1ZTtcbiJdLCJuYW1lcyI6WyJhcHByb3hTZWFyY2giLCJzZWFyY2giLCJ0ZXh0Iiwic3RyIiwibWF4RXJyb3JzIiwibWF0Y2hQb3MiLCJleGFjdE1hdGNoZXMiLCJpbmRleE9mIiwicHVzaCIsInN0YXJ0IiwiZW5kIiwibGVuZ3RoIiwiZXJyb3JzIiwidGV4dE1hdGNoU2NvcmUiLCJtYXRjaGVzIiwibWF0Y2hRdW90ZSIsInF1b3RlIiwiY29udGV4dCIsIk1hdGgiLCJtaW4iLCJzY29yZU1hdGNoIiwibWF0Y2giLCJxdW90ZVdlaWdodCIsInByZWZpeFdlaWdodCIsInN1ZmZpeFdlaWdodCIsInBvc1dlaWdodCIsInF1b3RlU2NvcmUiLCJwcmVmaXhTY29yZSIsInByZWZpeCIsInNsaWNlIiwibWF4Iiwic3VmZml4U2NvcmUiLCJzdWZmaXgiLCJwb3NTY29yZSIsImhpbnQiLCJvZmZzZXQiLCJhYnMiLCJyYXdTY29yZSIsIm1heFNjb3JlIiwibm9ybWFsaXplZFNjb3JlIiwic2NvcmVkTWF0Y2hlcyIsIm1hcCIsIm0iLCJzY29yZSIsInNvcnQiLCJhIiwiYiIsIm5vZGVUZXh0TGVuZ3RoIiwibm9kZSIsIm5vZGVUeXBlIiwiTm9kZSIsIkVMRU1FTlRfTk9ERSIsIlRFWFRfTk9ERSIsInRleHRDb250ZW50IiwicHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgiLCJzaWJsaW5nIiwicHJldmlvdXNTaWJsaW5nIiwicmVzb2x2ZU9mZnNldHMiLCJlbGVtZW50Iiwib2Zmc2V0cyIsIm5leHRPZmZzZXQiLCJzaGlmdCIsIm5vZGVJdGVyIiwib3duZXJEb2N1bWVudCIsImNyZWF0ZU5vZGVJdGVyYXRvciIsIk5vZGVGaWx0ZXIiLCJTSE9XX1RFWFQiLCJyZXN1bHRzIiwiY3VycmVudE5vZGUiLCJuZXh0Tm9kZSIsInRleHROb2RlIiwidW5kZWZpbmVkIiwiZGF0YSIsIlJhbmdlRXJyb3IiLCJSRVNPTFZFX0ZPUldBUkRTIiwiUkVTT0xWRV9CQUNLV0FSRFMiLCJUZXh0UG9zaXRpb24iLCJFcnJvciIsInBhcmVudCIsImNvbnRhaW5zIiwiZWwiLCJwYXJlbnRFbGVtZW50Iiwib3B0aW9ucyIsImVyciIsImRpcmVjdGlvbiIsInR3IiwiZG9jdW1lbnQiLCJjcmVhdGVUcmVlV2Fsa2VyIiwiZ2V0Um9vdE5vZGUiLCJmb3J3YXJkcyIsInByZXZpb3VzTm9kZSIsImZyb21Qb2ludCIsInRleHRPZmZzZXQiLCJjaGlsZE5vZGVzIiwiaSIsIlRleHRSYW5nZSIsInJlbGF0aXZlVG8iLCJyZXNvbHZlIiwicmFuZ2UiLCJSYW5nZSIsInNldFN0YXJ0Iiwic2V0RW5kIiwic3RhcnRDb250YWluZXIiLCJzdGFydE9mZnNldCIsImVuZENvbnRhaW5lciIsImVuZE9mZnNldCIsInJvb3QiLCJub2RlRnJvbVhQYXRoIiwieHBhdGhGcm9tTm9kZSIsIlJhbmdlQW5jaG9yIiwibm9ybWFsaXplZFJhbmdlIiwiZnJvbVJhbmdlIiwidG9SYW5nZSIsInRleHRSYW5nZSIsInR5cGUiLCJzZWxlY3RvciIsInN0YXJ0UG9zIiwiZnJvbUNoYXJPZmZzZXQiLCJlbmRQb3MiLCJUZXh0UG9zaXRpb25BbmNob3IiLCJmcm9tT2Zmc2V0cyIsIlRleHRRdW90ZUFuY2hvciIsImV4YWN0IiwidG9Qb3NpdGlvbkFuY2hvciIsImNvbnRleHRMZW4iLCJ3aW5kb3ciLCJhZGRFdmVudExpc3RlbmVyIiwiZXZlbnQiLCJBbmRyb2lkIiwibG9nRXJyb3IiLCJtZXNzYWdlIiwiZmlsZW5hbWUiLCJsaW5lbm8iLCJvYnNlcnZlciIsIlJlc2l6ZU9ic2VydmVyIiwib25WaWV3cG9ydFdpZHRoQ2hhbmdlZCIsInNuYXBDdXJyZW50T2Zmc2V0Iiwib2JzZXJ2ZSIsImJvZHkiLCJhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQiLCJpZCIsInZpcnR1YWxDb2wiLCJnZXRFbGVtZW50QnlJZCIsImlzU2Nyb2xsTW9kZUVuYWJsZWQiLCJnZXRDb2x1bW5Db3VudFBlclNjcmVlbiIsInJlbW92ZSIsImRvY3VtZW50V2lkdGgiLCJzY3JvbGxpbmdFbGVtZW50Iiwic2Nyb2xsV2lkdGgiLCJjb2xDb3VudCIsInBhZ2VXaWR0aCIsImhhc09kZENvbENvdW50Iiwicm91bmQiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwic3R5bGUiLCJicmVha0JlZm9yZSIsImlubmVySFRNTCIsImFwcGVuZENoaWxkIiwid2lkdGgiLCJnZXRWaWV3cG9ydFdpZHRoIiwiZGV2aWNlUGl4ZWxSYXRpbyIsInNldFByb3BlcnR5IiwicGFyc2VJbnQiLCJnZXRDb21wdXRlZFN0eWxlIiwiZG9jdW1lbnRFbGVtZW50IiwiZ2V0UHJvcGVydHlWYWx1ZSIsInRyaW0iLCJpc1JUTCIsImRpciIsInRvTG93ZXJDYXNlIiwic2Nyb2xsVG9JZCIsInNjcm9sbFRvUmVjdCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInNjcm9sbFRvUG9zaXRpb24iLCJwb3NpdGlvbiIsInNjcm9sbEhlaWdodCIsInNjcm9sbFRvcCIsImZhY3RvciIsInNjcm9sbExlZnQiLCJzbmFwT2Zmc2V0Iiwic2Nyb2xsVG9UZXh0IiwicmFuZ2VGcm9tTG9jYXRvciIsInNjcm9sbFRvUmFuZ2UiLCJyZWN0IiwidG9wIiwic2Nyb2xsWSIsImlubmVySGVpZ2h0IiwibGVmdCIsInNjcm9sbFgiLCJzY3JvbGxUb1N0YXJ0Iiwic2Nyb2xsVG8iLCJzY3JvbGxUb0VuZCIsIm1pbk9mZnNldCIsInNjcm9sbFRvT2Zmc2V0Iiwic2Nyb2xsUmlnaHQiLCJtYXhPZmZzZXQiLCJjdXJyZW50T2Zmc2V0IiwiZGlmZiIsInZhbHVlIiwiZGVsdGEiLCJsb2NhdG9yIiwibG9jYXRpb25zIiwiaGlnaGxpZ2h0IiwiY3NzU2VsZWN0b3IiLCJxdWVyeVNlbGVjdG9yIiwiYW5jaG9yIiwiYmVmb3JlIiwiYWZ0ZXIiLCJmcmFnbWVudHMiLCJodG1sSWQiLCJjcmVhdGVSYW5nZSIsInNldFN0YXJ0QmVmb3JlIiwic2V0RW5kQWZ0ZXIiLCJlIiwic2V0Q1NTUHJvcGVydGllcyIsInByb3BlcnRpZXMiLCJuYW1lIiwia2V5IiwicmVtb3ZlUHJvcGVydHkiLCJsb2ciLCJBcnJheSIsInByb3RvdHlwZSIsImNhbGwiLCJhcmd1bWVudHMiLCJqb2luIiwibG9nTmF0aXZlIiwiZGVidWciLCJ0b05hdGl2ZVJlY3QiLCJwaXhlbFJhdGlvIiwiaGVpZ2h0IiwicmlnaHQiLCJib3R0b20iLCJnZXRDbGllbnRSZWN0c05vT3ZlcmxhcCIsImRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMiLCJjbGllbnRSZWN0cyIsImdldENsaWVudFJlY3RzIiwidG9sZXJhbmNlIiwib3JpZ2luYWxSZWN0cyIsInJhbmdlQ2xpZW50UmVjdCIsIm1lcmdlZFJlY3RzIiwibWVyZ2VUb3VjaGluZ1JlY3RzIiwibm9Db250YWluZWRSZWN0cyIsInJlbW92ZUNvbnRhaW5lZFJlY3RzIiwibmV3UmVjdHMiLCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIiwibWluQXJlYSIsImoiLCJiaWdFbm91Z2giLCJzcGxpY2UiLCJyZWN0cyIsInJlY3QxIiwicmVjdDIiLCJyZWN0c0xpbmVVcFZlcnRpY2FsbHkiLCJhbG1vc3RFcXVhbCIsInJlY3RzTGluZVVwSG9yaXpvbnRhbGx5IiwiaG9yaXpvbnRhbEFsbG93ZWQiLCJhbGlnbmVkIiwiY2FuTWVyZ2UiLCJyZWN0c1RvdWNoT3JPdmVybGFwIiwiZmlsdGVyIiwicmVwbGFjZW1lbnRDbGllbnRSZWN0IiwiZ2V0Qm91bmRpbmdSZWN0IiwicmVjdHNUb0tlZXAiLCJTZXQiLCJkZWxldGUiLCJwb3NzaWJseUNvbnRhaW5pbmdSZWN0IiwiaGFzIiwicmVjdENvbnRhaW5zIiwiZnJvbSIsInJlY3RDb250YWluc1BvaW50IiwieCIsInkiLCJ0b0FkZCIsInRvUmVtb3ZlIiwic3VidHJhY3RSZWN0czEiLCJyZWN0U3VidHJhY3QiLCJzdWJ0cmFjdFJlY3RzMiIsImFwcGx5IiwicmVjdEludGVyc2VjdGVkIiwicmVjdEludGVyc2VjdCIsInJlY3RBIiwicmVjdEIiLCJyZWN0QyIsInJlY3REIiwibWF4TGVmdCIsIm1pblJpZ2h0IiwibWF4VG9wIiwibWluQm90dG9tIiwic3R5bGVzIiwiTWFwIiwiZ3JvdXBzIiwibGFzdEdyb3VwSWQiLCJyZWdpc3RlclRlbXBsYXRlcyIsIm5ld1N0eWxlcyIsInN0eWxlc2hlZXQiLCJPYmplY3QiLCJlbnRyaWVzIiwic2V0Iiwic3R5bGVFbGVtZW50IiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJnZXREZWNvcmF0aW9ucyIsImdyb3VwTmFtZSIsImdyb3VwIiwiZ2V0IiwiRGVjb3JhdGlvbkdyb3VwIiwiaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQiLCJjbGlja0V2ZW50Iiwic2l6ZSIsImZpbmRUYXJnZXQiLCJncm91cENvbnRlbnQiLCJpdGVtcyIsInJldmVyc2UiLCJpdGVtIiwiY2xpY2thYmxlRWxlbWVudHMiLCJ0b0pTT04iLCJjbGllbnRYIiwiY2xpZW50WSIsInRhcmdldCIsIm9uRGVjb3JhdGlvbkFjdGl2YXRlZCIsIkpTT04iLCJzdHJpbmdpZnkiLCJkZWNvcmF0aW9uIiwiY2xpY2siLCJncm91cElkIiwibGFzdEl0ZW1JZCIsImNvbnRhaW5lciIsImFkZCIsImxheW91dCIsImRlY29yYXRpb25JZCIsImluZGV4IiwiZmluZEluZGV4IiwidXBkYXRlIiwiY2xlYXIiLCJjbGVhckNvbnRhaW5lciIsInJlcXVlc3RMYXlvdXQiLCJmb3JFYWNoIiwiZ3JvdXBDb250YWluZXIiLCJyZXF1aXJlQ29udGFpbmVyIiwiaXRlbUNvbnRhaW5lciIsInZpZXdwb3J0V2lkdGgiLCJpbm5lcldpZHRoIiwiY29sdW1uQ291bnQiLCJ4T2Zmc2V0IiwieU9mZnNldCIsInBvc2l0aW9uRWxlbWVudCIsImJvdW5kaW5nUmVjdCIsImZsb29yIiwiZWxlbWVudFRlbXBsYXRlIiwidGVtcGxhdGUiLCJjb250ZW50IiwiZmlyc3RFbGVtZW50Q2hpbGQiLCJlcnJvciIsInIxIiwicjIiLCJjbGllbnRSZWN0IiwibGluZSIsImNsb25lTm9kZSIsImFwcGVuZCIsImJvdW5kcyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJjaGlsZHJlbiIsImxhc3RTaXplIiwiY2xpZW50V2lkdGgiLCJjbGllbnRIZWlnaHQiLCJnZXRDc3NTZWxlY3RvciIsIm5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQiLCJpbnRlcmFjdGl2ZVRhZ3MiLCJub2RlTmFtZSIsIm91dGVySFRNTCIsImhhc0F0dHJpYnV0ZSIsImdldEF0dHJpYnV0ZSIsImZpbmRGaXJzdFZpc2libGVMb2NhdG9yIiwiZmluZEVsZW1lbnQiLCJocmVmIiwicm9vdEVsZW1lbnQiLCJjaGlsZCIsInNob3VsZElnbm9yZUVsZW1lbnQiLCJpc0VsZW1lbnRWaXNpYmxlIiwicmVhZGl1bSIsImlzRml4ZWRMYXlvdXQiLCJlbFN0eWxlIiwiZGlzcGxheSIsIm9wYWNpdHkiLCJvbkNsaWNrIiwiYmluZERyYWdHZXN0dXJlIiwiZ2V0U2VsZWN0aW9uIiwiaXNDb2xsYXBzZWQiLCJkZWZhdWx0UHJldmVudGVkIiwidGFyZ2V0RWxlbWVudCIsImludGVyYWN0aXZlRWxlbWVudCIsInNob3VsZFByZXZlbnREZWZhdWx0Iiwib25UYXAiLCJzdG9wUHJvcGFnYXRpb24iLCJwcmV2ZW50RGVmYXVsdCIsIm9uU3RhcnQiLCJwYXNzaXZlIiwib25FbmQiLCJvbk1vdmUiLCJzdGF0ZSIsImlzU3RhcnRpbmdEcmFnIiwic3RhcnRYIiwidG91Y2hlcyIsInN0YXJ0WSIsImN1cnJlbnRYIiwiY3VycmVudFkiLCJvZmZzZXRYIiwib2Zmc2V0WSIsIm9uRHJhZ1N0YXJ0Iiwib25EcmFnTW92ZSIsIm9uRHJhZ0VuZCIsInNob3VsZElnbm9yZUV2ZW50Iiwic2VuZFByZXNzS2V5TWVzc2FnZSIsImFjdGl2ZUVsZW1lbnQiLCJyZXBlYXQiLCJrZXlFdmVudCIsImNvZGUiLCJjaGFyYWN0ZXJzIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwia2V5Q29kZSIsImFsdCIsImFsdEtleSIsImNvbnRyb2wiLCJjdHJsS2V5Iiwic2hpZnRLZXkiLCJtZXRhIiwibWV0YUtleSIsIm9uS2V5IiwiUk9PVF9DTEFTU19SRURVQ0VfTU9USU9OIiwiUk9PVF9DTEFTU19OT19GT09UTk9URVMiLCJQT1BVUF9ESUFMT0dfQ0xBU1MiLCJGT09UTk9URVNfQ09OVEFJTkVSX0NMQVNTIiwiRk9PVE5PVEVTX0NMT1NFX0JVVFRPTl9DTEFTUyIsIkZPT1ROT1RFX0ZPUkNFX1NIT1ciLCJUVFNfSURfUFJFVklPVVMiLCJUVFNfSURfTkVYVCIsIlRUU19JRF9TTElERVIiLCJUVFNfSURfQUNUSVZFX1dPUkQiLCJUVFNfSURfQ09OVEFJTkVSIiwiVFRTX0lEX0lORk8iLCJUVFNfTkFWX0JVVFRPTl9DTEFTUyIsIlRUU19JRF9TUEVBS0lOR19ET0NfRUxFTUVOVCIsIlRUU19DTEFTU19JTkpFQ1RFRF9TUEFOIiwiVFRTX0NMQVNTX0lOSkVDVEVEX1NVQlNQQU4iLCJUVFNfSURfSU5KRUNURURfUEFSRU5UIiwiSURfSElHSExJR0hUU19DT05UQUlORVIiLCJJRF9BTk5PVEFUSU9OX0NPTlRBSU5FUiIsIkNMQVNTX0hJR0hMSUdIVF9DT05UQUlORVIiLCJDTEFTU19BTk5PVEFUSU9OX0NPTlRBSU5FUiIsIkNMQVNTX0hJR0hMSUdIVF9BUkVBIiwiQ0xBU1NfQU5OT1RBVElPTl9BUkVBIiwiQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEiLCJDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUEiLCJfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSIsIkNMQVNTX1BBR0lOQVRFRCIsIklTX0RFViIsIl9oaWdobGlnaHRzIiwiX2hpZ2hsaWdodHNDb250YWluZXIiLCJfYW5ub3RhdGlvbkNvbnRhaW5lciIsImxhc3RNb3VzZURvd25YIiwibGFzdE1vdXNlRG93blkiLCJib2R5RXZlbnRMaXN0ZW5lcnNTZXQiLCJVU0VfU1ZHIiwiREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkiLCJBTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZIiwiREVCVUdfVklTVUFMUyIsIkRFRkFVTFRfQkFDS0dST1VORF9DT0xPUiIsImJsdWUiLCJncmVlbiIsInJlZCIsIkFOTk9UQVRJT05fV0lEVEgiLCJyZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUiLCJfd2luIiwiaGlnaGxpZ2h0Qm91bmRpbmciLCJvdXRsaW5lIiwic2V0SGlnaGxpZ2h0QXJlYVN0eWxlIiwid2luIiwiaGlnaGxpZ2h0QXJlYXMiLCJ1c2VTVkciLCJoaWdobGlnaHRBcmVhIiwiaXNTVkciLCJuYW1lc3BhY2VVUkkiLCJTVkdfWE1MX05BTUVTUEFDRSIsImNvbG9yIiwicmVzZXRIaWdobGlnaHRBcmVhU3R5bGUiLCJwYXJlbnROb2RlIiwiZmluZCIsImgiLCJwcm9jZXNzVG91Y2hFdmVudCIsImV2Iiwic2Nyb2xsRWxlbWVudCIsImdldFNjcm9sbGluZ0VsZW1lbnQiLCJjaGFuZ2VkVG91Y2hlcyIsInBhZ2luYXRlZCIsImlzUGFnaW5hdGVkIiwiYm9keVJlY3QiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJmb3VuZEhpZ2hsaWdodCIsImZvdW5kRWxlbWVudCIsImZvdW5kUmVjdCIsImhpZ2hsaWdodFBhcmVudCIsImhpdCIsImhpZ2hsaWdodEZyYWdtZW50cyIsImhpZ2hsaWdodEZyYWdtZW50Iiwid2l0aFJlY3QiLCJoaWdobGlnaHRCb3VuZGluZ3MiLCJhbGxIaWdobGlnaHRBcmVhcyIsImZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzIiwiZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmciLCJhbGxIaWdobGlnaHRCb3VuZGluZ3MiLCJzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlIiwic2NyZWVuV2lkdGgiLCJvdXRlcldpZHRoIiwic2NyZWVuSGVpZ2h0Iiwib3V0ZXJIZWlnaHQiLCJwYXlsb2FkIiwicHJvY2VzcyIsImVsZWN0cm9uXzEiLCJpcGNSZW5kZXJlciIsInNlbmRUb0hvc3QiLCJSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0siLCJ3ZWJraXRVUkwiLCJjb25zb2xlIiwiaW5jbHVkZXMiLCJoaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZCIsIndlYmtpdCIsIm1lc3NhZ2VIYW5kbGVycyIsInBvc3RNZXNzYWdlIiwiaGlnaGxpZ2h0QWN0aXZhdGVkIiwicHJvY2Vzc01vdXNlRXZlbnQiLCJ0b3VjaGVkUG9zaXRpb24iLCJ0b1ByZXNlcnZlIiwidG9DaGVjayIsImNoZWNrT3ZlcmxhcHMiLCJzdGlsbE92ZXJsYXBpbmdSZWN0cyIsImhhczEiLCJoYXMyIiwieE92ZXJsYXAiLCJnZXRSZWN0T3ZlcmxhcFgiLCJ5T3ZlcmxhcCIsImdldFJlY3RPdmVybGFwWSIsInJhbmdlQ2xpZW50UmVjdHMiLCJnZXRDbGllbnRSZWN0c05vT3ZlcmxhcF8iLCJjbGFzc0xpc3QiLCJlbnN1cmVDb250YWluZXIiLCJhbm5vdGF0aW9uRmxhZyIsInRvdWNoRW5kIiwiaGlkZUFsbGhpZ2hsaWdodHMiLCJkZXN0cm95QWxsaGlnaGxpZ2h0cyIsImRlc3Ryb3lIaWdobGlnaHQiLCJfZG9jdW1lbnQiLCJoaWdobGlnaHRDb250YWluZXIiLCJpc0NmaVRleHROb2RlIiwiZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4IiwiZm91bmQiLCJ0ZXh0Tm9kZUluZGV4IiwicHJldmlvdXNXYXNFbGVtZW50IiwiY2hpbGROb2RlIiwiaXNUZXh0IiwiZ2V0Q29tbW9uQW5jZXN0b3JFbGVtZW50Iiwibm9kZTEiLCJub2RlMiIsIm5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4iLCJub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluIiwiY29tbW9uQW5jZXN0b3IiLCJub2RlMUVsZW1lbnRBbmNlc3RvciIsIm5vZGUyRWxlbWVudEFuY2VzdG9yIiwiZnVsbFF1YWxpZmllZFNlbGVjdG9yIiwibG93ZXJDYXNlTmFtZSIsImxvY2FsTmFtZSIsImNzc1BhdGgiLCJnZXRDdXJyZW50U2VsZWN0aW9uSW5mbyIsInNlbGVjdGlvbiIsInJhd1RleHQiLCJ0b1N0cmluZyIsImNsZWFuVGV4dCIsInJlcGxhY2UiLCJhbmNob3JOb2RlIiwiZm9jdXNOb2RlIiwicmFuZ2VDb3VudCIsImdldFJhbmdlQXQiLCJjcmVhdGVPcmRlcmVkUmFuZ2UiLCJhbmNob3JPZmZzZXQiLCJmb2N1c09mZnNldCIsImNvbGxhcHNlZCIsInJhbmdlSW5mbyIsImNvbnZlcnRSYW5nZSIsImNvbXB1dGVDRkkiLCJyZXN0b3JlZFJhbmdlIiwiY29udmVydFJhbmdlSW5mbyIsImR1bXBEZWJ1ZyIsInJhbmdlSW5mbzJMb2NhdGlvbiIsImNoZWNrQmxhY2tsaXN0ZWQiLCJibGFja2xpc3RlZElkIiwiYmxhY2tsaXN0ZWRDbGFzcyIsIm9wdGltaXplZCIsInN0ZXBzIiwiY29udGV4dE5vZGUiLCJzdGVwIiwiX2Nzc1BhdGhTdGVwIiwiaXNUYXJnZXROb2RlIiwicHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyIsIm5kIiwiY2xhc3NBdHRyaWJ1dGUiLCJzcGxpdCIsIkJvb2xlYW4iLCJubSIsImlkU2VsZWN0b3IiLCJpZGQiLCJlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQiLCJpZGVudCIsImlzQ1NTSWRlbnRpZmllciIsInNob3VsZEVzY2FwZUZpcnN0IiwidGVzdCIsImxhc3RJbmRleCIsImMiLCJpaSIsImlzQ1NTSWRlbnRDaGFyIiwiZXNjYXBlQXNjaWlDaGFyIiwiaXNMYXN0IiwidG9IZXhCeXRlIiwiaGV4Qnl0ZSIsImNoYXJDb2RlQXQiLCJET0NVTUVOVF9OT0RFIiwicHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfIiwicHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkiLCJhcnJJdGVtIiwibmVlZHNDbGFzc05hbWVzIiwibmVlZHNOdGhDaGlsZCIsIm93bkluZGV4IiwiZWxlbWVudEluZGV4Iiwic2libGluZ3MiLCJzaWJsaW5nTmFtZSIsIm93bkNsYXNzTmFtZXMiLCJvd25DbGFzc05hbWVDb3VudCIsInNpYmxpbmdDbGFzc05hbWVzQXJyYXlfIiwic2libGluZ0NsYXNzTmFtZXNBcnJheSIsInNpYmxpbmdDbGFzcyIsImluZCIsInJlc3VsdCIsInByZWZpeGVkTmFtZSIsInN1YnN0ciIsImNmaSIsImN1cnJlbnRFbGVtZW50IiwiYmxhY2tsaXN0ZWQiLCJjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuIiwiY3VycmVudEVsZW1lbnRJbmRleCIsImNmaUluZGV4IiwiX2NyZWF0ZUhpZ2hsaWdodCIsInBvaW50ZXJJbnRlcmFjdGlvbiIsImxvY2F0aW9uMlJhbmdlSW5mbyIsInVuaXF1ZVN0ciIsInN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yIiwic3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgiLCJlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IiLCJlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgiLCJoYXNoIiwicmVxdWlyZSIsInNoYTI1NkhleCIsInNoYTI1NiIsImRpZ2VzdCIsImNyZWF0ZUhpZ2hsaWdodERvbSIsImNyZWF0ZUhpZ2hsaWdodCIsInNlbGVjdGlvbkluZm8iLCJjcmVhdGVBbm5vdGF0aW9uIiwic2NhbGUiLCJSRUFESVVNMiIsImZ4bFZpZXdwb3J0U2NhbGUiLCJoaWdobGlnaHRzQ29udGFpbmVyIiwiZHJhd1VuZGVybGluZSIsImRyYXdTdHJpa2VUaHJvdWdoIiwiaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWciLCJyb3VuZGVkQ29ybmVyIiwidW5kZXJsaW5lVGhpY2tuZXNzIiwic3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MiLCJleHRyYSIsInJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdCIsImZyYW1lRm9ySGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtXaXRoSUQiLCJhbm5vdGF0aW9uT2Zmc2V0IiwiYm9yZGVyVGhpY2tuZXNzIiwiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCIsImhpZ2hsaWdodEFyZWFTVkdSZWN0IiwiY3JlYXRlRWxlbWVudE5TIiwiaGlnaGxpZ2h0QXJlYVNWR0xpbmUiLCJsaW5lT2Zmc2V0IiwicmdiIiwicmFuZG9tIiwiciIsImciLCJoaWdobGlnaHRBcmVhTGluZSIsImhpZ2hsaWdodEFyZWFTVkciLCJvdmVyZmxvdyIsInJhbmdlQm91bmRpbmdDbGllbnRSZWN0Iiwic3RhcnROb2RlIiwiZW5kTm9kZSIsInJhbmdlUmV2ZXJzZSIsImNvbXB1dGVFbGVtZW50Q0ZJIiwic3RhcnRJc0VsZW1lbnQiLCJzdGFydENvbnRhaW5lckVsZW1lbnQiLCJlbmRJc0VsZW1lbnQiLCJlbmRDb250YWluZXJFbGVtZW50IiwiY29tbW9uRWxlbWVudEFuY2VzdG9yIiwiY29tbW9uQW5jZXN0b3JDb250YWluZXIiLCJyYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCIsInJvb3RFbGVtZW50Q2ZpIiwic3RhcnRFbGVtZW50Q2ZpIiwiZW5kRWxlbWVudENmaSIsInN0YXJ0RWxlbWVudE9yVGV4dENmaSIsInN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpIiwiY2ZpVGV4dE5vZGVJbmRleCIsImNmaUluZGV4T2ZMYXN0RWxlbWVudCIsImNoaWxkRWxlbWVudENvdW50IiwibGFzdENoaWxkTm9kZSIsImVuZEVsZW1lbnRPclRleHRDZmkiLCJlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkiLCJzdGFydEVsZW1lbnQiLCJlbmRFbGVtZW50IiwiZnJhbWVGb3JIaWdobGlnaHRXaXRoSUQiLCJ0b3BDbGllbnRSZWN0IiwibWF4SGVpZ2h0IiwibmV3VG9wIiwiYm91bmRpbmdBcmVhcyIsImdldEVsZW1lbnRzQnlDbGFzc05hbWUiLCJsZW4iLCJib3VuZGluZ0FyZWEiLCJoaWdobGlnaHRXaXRoSUQiLCJwYXJ0aWFsQ2ZpIiwiZG9tUmFuZ2UiLCJsb2NhdGlvbiIsInJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRCIsImdldFNlbGVjdGlvblJlY3QiLCJzZWwiLCJoYW5kbGVCb3VuZHMiLCJzZXRTY3JvbGxNb2RlIiwiZmxhZyIsIm1hdGNoQWxsIiwic2hpbSIsImlzU2VsZWN0aW5nIiwib25TZWxlY3Rpb25FbmQiLCJvblNlbGVjdGlvblN0YXJ0IiwiZ2V0Q3VycmVudFNlbGVjdGlvbiIsImdldEN1cnJlbnRTZWxlY3Rpb25UZXh0IiwiY2xlYW5IaWdobGlnaHQiLCJzbmlwcGV0TGVuZ3RoIiwiZmlyc3RXb3JkU3RhcnQiLCJsYXN0V29yZEVuZCIsInBvcCIsInJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlcyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3088\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},3715:function(__unused_webpack_module,exports,__webpack_require__){eval("var hash = exports;\n\nhash.utils = __webpack_require__(6436);\nhash.common = __webpack_require__(5772);\nhash.sha = __webpack_require__(9041);\nhash.ripemd = __webpack_require__(2949);\nhash.hmac = __webpack_require__(2344);\n\n// Proxy hash functions to the main object\nhash.sha1 = hash.sha.sha1;\nhash.sha256 = hash.sha.sha256;\nhash.sha224 = hash.sha.sha224;\nhash.sha384 = hash.sha.sha384;\nhash.sha512 = hash.sha.sha512;\nhash.ripemd160 = hash.ripemd.ripemd160;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcxNS5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQSxhQUFhLG1CQUFPLENBQUMsSUFBYztBQUNuQyxjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBWTtBQUMvQixjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsSUFBYTs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanM/N2Q5MiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3715\n")},5772:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction BlockHash() {\n this.pending = null;\n this.pendingTotal = 0;\n this.blockSize = this.constructor.blockSize;\n this.outSize = this.constructor.outSize;\n this.hmacStrength = this.constructor.hmacStrength;\n this.padLength = this.constructor.padLength / 8;\n this.endian = 'big';\n\n this._delta8 = this.blockSize / 8;\n this._delta32 = this.blockSize / 32;\n}\nexports.BlockHash = BlockHash;\n\nBlockHash.prototype.update = function update(msg, enc) {\n // Convert message to array, pad it, and join into 32bit blocks\n msg = utils.toArray(msg, enc);\n if (!this.pending)\n this.pending = msg;\n else\n this.pending = this.pending.concat(msg);\n this.pendingTotal += msg.length;\n\n // Enough data, try updating\n if (this.pending.length >= this._delta8) {\n msg = this.pending;\n\n // Process pending data in blocks\n var r = msg.length % this._delta8;\n this.pending = msg.slice(msg.length - r, msg.length);\n if (this.pending.length === 0)\n this.pending = null;\n\n msg = utils.join32(msg, 0, msg.length - r, this.endian);\n for (var i = 0; i < msg.length; i += this._delta32)\n this._update(msg, i, i + this._delta32);\n }\n\n return this;\n};\n\nBlockHash.prototype.digest = function digest(enc) {\n this.update(this._pad());\n assert(this.pending === null);\n\n return this._digest(enc);\n};\n\nBlockHash.prototype._pad = function pad() {\n var len = this.pendingTotal;\n var bytes = this._delta8;\n var k = bytes - ((len + this.padLength) % bytes);\n var res = new Array(k + this.padLength);\n res[0] = 0x80;\n for (var i = 1; i < k; i++)\n res[i] = 0;\n\n // Append length\n len <<= 3;\n if (this.endian === 'big') {\n for (var t = 8; t < this.padLength; t++)\n res[i++] = 0;\n\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = len & 0xff;\n } else {\n res[i++] = len & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n\n for (t = 8; t < this.padLength; t++)\n res[i++] = 0;\n }\n\n return res;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTc3Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLE9BQU87QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzP2VkYzkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5772\n")},2344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction Hmac(hash, key, enc) {\n if (!(this instanceof Hmac))\n return new Hmac(hash, key, enc);\n this.Hash = hash;\n this.blockSize = hash.blockSize / 8;\n this.outSize = hash.outSize / 8;\n this.inner = null;\n this.outer = null;\n\n this._init(utils.toArray(key, enc));\n}\nmodule.exports = Hmac;\n\nHmac.prototype._init = function init(key) {\n // Shorten key, if needed\n if (key.length > this.blockSize)\n key = new this.Hash().update(key).digest();\n assert(key.length <= this.blockSize);\n\n // Add padding to key\n for (var i = key.length; i < this.blockSize; i++)\n key.push(0);\n\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x36;\n this.inner = new this.Hash().update(key);\n\n // 0x36 ^ 0x5c = 0x6a\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x6a;\n this.outer = new this.Hash().update(key);\n};\n\nHmac.prototype.update = function update(msg, enc) {\n this.inner.update(msg, enc);\n return this;\n};\n\nHmac.prototype.digest = function digest(enc) {\n this.outer.update(this.inner.digest());\n return this.outer.digest(enc);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsb0JBQW9CO0FBQy9DOztBQUVBLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvaG1hYy5qcz8yMTM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gSG1hYyhoYXNoLCBrZXksIGVuYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hYykpXG4gICAgcmV0dXJuIG5ldyBIbWFjKGhhc2gsIGtleSwgZW5jKTtcbiAgdGhpcy5IYXNoID0gaGFzaDtcbiAgdGhpcy5ibG9ja1NpemUgPSBoYXNoLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMub3V0U2l6ZSA9IGhhc2gub3V0U2l6ZSAvIDg7XG4gIHRoaXMuaW5uZXIgPSBudWxsO1xuICB0aGlzLm91dGVyID0gbnVsbDtcblxuICB0aGlzLl9pbml0KHV0aWxzLnRvQXJyYXkoa2V5LCBlbmMpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hYztcblxuSG1hYy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGtleSkge1xuICAvLyBTaG9ydGVuIGtleSwgaWYgbmVlZGVkXG4gIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpXG4gICAga2V5ID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xuICBhc3NlcnQoa2V5Lmxlbmd0aCA8PSB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gQWRkIHBhZGRpbmcgdG8ga2V5XG4gIGZvciAodmFyIGkgPSBrZXkubGVuZ3RoOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKylcbiAgICBrZXkucHVzaCgwKTtcblxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDM2O1xuICB0aGlzLmlubmVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xuXG4gIC8vIDB4MzYgXiAweDVjID0gMHg2YVxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2344\n")},2949:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_3 = utils.sum32_3;\nvar sum32_4 = utils.sum32_4;\nvar BlockHash = common.BlockHash;\n\nfunction RIPEMD160() {\n if (!(this instanceof RIPEMD160))\n return new RIPEMD160();\n\n BlockHash.call(this);\n\n this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];\n this.endian = 'little';\n}\nutils.inherits(RIPEMD160, BlockHash);\nexports.ripemd160 = RIPEMD160;\n\nRIPEMD160.blockSize = 512;\nRIPEMD160.outSize = 160;\nRIPEMD160.hmacStrength = 192;\nRIPEMD160.padLength = 64;\n\nRIPEMD160.prototype._update = function update(msg, start) {\n var A = this.h[0];\n var B = this.h[1];\n var C = this.h[2];\n var D = this.h[3];\n var E = this.h[4];\n var Ah = A;\n var Bh = B;\n var Ch = C;\n var Dh = D;\n var Eh = E;\n for (var j = 0; j < 80; j++) {\n var T = sum32(\n rotl32(\n sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),\n s[j]),\n E);\n A = E;\n E = D;\n D = rotl32(C, 10);\n C = B;\n B = T;\n T = sum32(\n rotl32(\n sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),\n sh[j]),\n Eh);\n Ah = Eh;\n Eh = Dh;\n Dh = rotl32(Ch, 10);\n Ch = Bh;\n Bh = T;\n }\n T = sum32_3(this.h[1], C, Dh);\n this.h[1] = sum32_3(this.h[2], D, Eh);\n this.h[2] = sum32_3(this.h[3], E, Ah);\n this.h[3] = sum32_3(this.h[4], A, Bh);\n this.h[4] = sum32_3(this.h[0], B, Ch);\n this.h[0] = T;\n};\n\nRIPEMD160.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'little');\n else\n return utils.split32(this.h, 'little');\n};\n\nfunction f(j, x, y, z) {\n if (j <= 15)\n return x ^ y ^ z;\n else if (j <= 31)\n return (x & y) | ((~x) & z);\n else if (j <= 47)\n return (x | (~y)) ^ z;\n else if (j <= 63)\n return (x & z) | (y & (~z));\n else\n return x ^ (y | (~z));\n}\n\nfunction K(j) {\n if (j <= 15)\n return 0x00000000;\n else if (j <= 31)\n return 0x5a827999;\n else if (j <= 47)\n return 0x6ed9eba1;\n else if (j <= 63)\n return 0x8f1bbcdc;\n else\n return 0xa953fd4e;\n}\n\nfunction Kh(j) {\n if (j <= 15)\n return 0x50a28be6;\n else if (j <= 31)\n return 0x5c4dd124;\n else if (j <= 47)\n return 0x6d703ef3;\n else if (j <= 63)\n return 0x7a6d76e9;\n else\n return 0x00000000;\n}\n\nvar r = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,\n 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,\n 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13\n];\n\nvar rh = [\n 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,\n 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,\n 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,\n 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,\n 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11\n];\n\nvar s = [\n 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,\n 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,\n 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,\n 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,\n 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6\n];\n\nvar sh = [\n 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,\n 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,\n 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,\n 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,\n 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11\n];\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBVTs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzP2JiNDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2949\n")},9041:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nexports.sha1 = __webpack_require__(4761);\nexports.sha224 = __webpack_require__(799);\nexports.sha256 = __webpack_require__(9344);\nexports.sha384 = __webpack_require__(772);\nexports.sha512 = __webpack_require__(5900);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA0MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix3Q0FBaUM7QUFDakMseUNBQXFDO0FBQ3JDLDBDQUFxQztBQUNyQyx5Q0FBcUM7QUFDckMsMENBQXFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcz81OTE5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGEvMScpO1xuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYS8yMjQnKTtcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEvMjU2Jyk7XG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhLzM4NCcpO1xuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYS81MTInKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9041\n")},4761:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_5 = utils.sum32_5;\nvar ft_1 = shaCommon.ft_1;\nvar BlockHash = common.BlockHash;\n\nvar sha1_K = [\n 0x5A827999, 0x6ED9EBA1,\n 0x8F1BBCDC, 0xCA62C1D6\n];\n\nfunction SHA1() {\n if (!(this instanceof SHA1))\n return new SHA1();\n\n BlockHash.call(this);\n this.h = [\n 0x67452301, 0xefcdab89, 0x98badcfe,\n 0x10325476, 0xc3d2e1f0 ];\n this.W = new Array(80);\n}\n\nutils.inherits(SHA1, BlockHash);\nmodule.exports = SHA1;\n\nSHA1.blockSize = 512;\nSHA1.outSize = 160;\nSHA1.hmacStrength = 80;\nSHA1.padLength = 64;\n\nSHA1.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n\n for(; i < W.length; i++)\n W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n\n for (i = 0; i < W.length; i++) {\n var s = ~~(i / 20);\n var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);\n e = d;\n d = c;\n c = rotl32(b, 30);\n b = a;\n a = t;\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n};\n\nSHA1.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc2MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVOztBQUVsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixRQUFRO0FBQzFCOztBQUVBLFFBQVEsY0FBYztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzEuanM/MTNlMiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGZ0XzEgPSBzaGFDb21tb24uZnRfMTtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMTtcblxuU0hBMS5ibG9ja1NpemUgPSA1MTI7XG5TSEExLm91dFNpemUgPSAxNjA7XG5TSEExLmhtYWNTdHJlbmd0aCA9IDgwO1xuU0hBMS5wYWRMZW5ndGggPSA2NDtcblxuU0hBMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuXG4gIGZvcig7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSByb3RsMzIoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSwgMSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4761\n")},799:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar SHA256 = __webpack_require__(9344);\n\nfunction SHA224() {\n if (!(this instanceof SHA224))\n return new SHA224();\n\n SHA256.call(this);\n this.h = [\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];\n}\nutils.inherits(SHA224, SHA256);\nmodule.exports = SHA224;\n\nSHA224.blockSize = 512;\nSHA224.outSize = 224;\nSHA224.hmacStrength = 192;\nSHA224.padLength = 64;\n\nSHA224.prototype._digest = function digest(enc) {\n // Just truncate output\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 7), 'big');\n else\n return utils.split32(this.h.slice(0, 7), 'big');\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVO0FBQzlCLGFBQWEsbUJBQU8sQ0FBQyxJQUFPOztBQUU1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzIyNC5qcz8wN2YyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBTSEEyNTYgPSByZXF1aXJlKCcuLzI1NicpO1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///799\n")},9344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\nvar assert = __webpack_require__(9746);\n\nvar sum32 = utils.sum32;\nvar sum32_4 = utils.sum32_4;\nvar sum32_5 = utils.sum32_5;\nvar ch32 = shaCommon.ch32;\nvar maj32 = shaCommon.maj32;\nvar s0_256 = shaCommon.s0_256;\nvar s1_256 = shaCommon.s1_256;\nvar g0_256 = shaCommon.g0_256;\nvar g1_256 = shaCommon.g1_256;\n\nvar BlockHash = common.BlockHash;\n\nvar sha256_K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\nfunction SHA256() {\n if (!(this instanceof SHA256))\n return new SHA256();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n ];\n this.k = sha256_K;\n this.W = new Array(64);\n}\nutils.inherits(SHA256, BlockHash);\nmodule.exports = SHA256;\n\nSHA256.blockSize = 512;\nSHA256.outSize = 256;\nSHA256.hmacStrength = 192;\nSHA256.padLength = 64;\n\nSHA256.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i++)\n W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n var f = this.h[5];\n var g = this.h[6];\n var h = this.h[7];\n\n assert(this.k.length === W.length);\n for (i = 0; i < W.length; i++) {\n var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);\n var T2 = sum32(s0_256(a), maj32(a, b, c));\n h = g;\n g = f;\n f = e;\n e = sum32(d, T1);\n d = c;\n c = b;\n b = a;\n a = sum32(T1, T2);\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n this.h[5] = sum32(this.h[5], f);\n this.h[6] = sum32(this.h[6], g);\n this.h[7] = sum32(this.h[7], h);\n};\n\nSHA256.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBLFNBQVMsY0FBYztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMjU2LmpzPzZlZWQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIHNoYUNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciBjaDMyID0gc2hhQ29tbW9uLmNoMzI7XG52YXIgbWFqMzIgPSBzaGFDb21tb24ubWFqMzI7XG52YXIgczBfMjU2ID0gc2hhQ29tbW9uLnMwXzI1NjtcbnZhciBzMV8yNTYgPSBzaGFDb21tb24uczFfMjU2O1xudmFyIGcwXzI1NiA9IHNoYUNvbW1vbi5nMF8yNTY7XG52YXIgZzFfMjU2ID0gc2hhQ29tbW9uLmcxXzI1NjtcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG4gIF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBUMSA9IHN1bTMyXzUoaCwgczFfMjU2KGUpLCBjaDMyKGUsIGYsIGcpLCB0aGlzLmtbaV0sIFdbaV0pO1xuICAgIHZhciBUMiA9IHN1bTMyKHMwXzI1NihhKSwgbWFqMzIoYSwgYiwgYykpO1xuICAgIGggPSBnO1xuICAgIGcgPSBmO1xuICAgIGYgPSBlO1xuICAgIGUgPSBzdW0zMihkLCBUMSk7XG4gICAgZCA9IGM7XG4gICAgYyA9IGI7XG4gICAgYiA9IGE7XG4gICAgYSA9IHN1bTMyKFQxLCBUMik7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xuICB0aGlzLmhbNV0gPSBzdW0zMih0aGlzLmhbNV0sIGYpO1xuICB0aGlzLmhbNl0gPSBzdW0zMih0aGlzLmhbNl0sIGcpO1xuICB0aGlzLmhbN10gPSBzdW0zMih0aGlzLmhbN10sIGgpO1xufTtcblxuU0hBMjU2LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9344\n")},772:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\n\nvar SHA512 = __webpack_require__(5900);\n\nfunction SHA384() {\n if (!(this instanceof SHA384))\n return new SHA384();\n\n SHA512.call(this);\n this.h = [\n 0xcbbb9d5d, 0xc1059ed8,\n 0x629a292a, 0x367cd507,\n 0x9159015a, 0x3070dd17,\n 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31,\n 0x8eb44a87, 0x68581511,\n 0xdb0c2e0d, 0x64f98fa7,\n 0x47b5481d, 0xbefa4fa4 ];\n}\nutils.inherits(SHA384, SHA512);\nmodule.exports = SHA384;\n\nSHA384.blockSize = 1024;\nSHA384.outSize = 384;\nSHA384.hmacStrength = 192;\nSHA384.padLength = 128;\n\nSHA384.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 12), 'big');\n else\n return utils.split32(this.h.slice(0, 12), 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcyLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVOztBQUU5QixhQUFhLG1CQUFPLENBQUMsSUFBTzs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMzg0LmpzPzhiOTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi81MTInKTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///772\n")},5900:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar assert = __webpack_require__(9746);\n\nvar rotr64_hi = utils.rotr64_hi;\nvar rotr64_lo = utils.rotr64_lo;\nvar shr64_hi = utils.shr64_hi;\nvar shr64_lo = utils.shr64_lo;\nvar sum64 = utils.sum64;\nvar sum64_hi = utils.sum64_hi;\nvar sum64_lo = utils.sum64_lo;\nvar sum64_4_hi = utils.sum64_4_hi;\nvar sum64_4_lo = utils.sum64_4_lo;\nvar sum64_5_hi = utils.sum64_5_hi;\nvar sum64_5_lo = utils.sum64_5_lo;\n\nvar BlockHash = common.BlockHash;\n\nvar sha512_K = [\n 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,\n 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,\n 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,\n 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,\n 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,\n 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,\n 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,\n 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,\n 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,\n 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,\n 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,\n 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,\n 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,\n 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,\n 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,\n 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,\n 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,\n 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,\n 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,\n 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,\n 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,\n 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,\n 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,\n 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,\n 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,\n 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,\n 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,\n 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,\n 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,\n 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,\n 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,\n 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,\n 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,\n 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,\n 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,\n 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,\n 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,\n 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,\n 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,\n 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817\n];\n\nfunction SHA512() {\n if (!(this instanceof SHA512))\n return new SHA512();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xf3bcc908,\n 0xbb67ae85, 0x84caa73b,\n 0x3c6ef372, 0xfe94f82b,\n 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1,\n 0x9b05688c, 0x2b3e6c1f,\n 0x1f83d9ab, 0xfb41bd6b,\n 0x5be0cd19, 0x137e2179 ];\n this.k = sha512_K;\n this.W = new Array(160);\n}\nutils.inherits(SHA512, BlockHash);\nmodule.exports = SHA512;\n\nSHA512.blockSize = 1024;\nSHA512.outSize = 512;\nSHA512.hmacStrength = 192;\nSHA512.padLength = 128;\n\nSHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {\n var W = this.W;\n\n // 32 x 32bit words\n for (var i = 0; i < 32; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i += 2) {\n var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2\n var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);\n var c1_hi = W[i - 14]; // i - 7\n var c1_lo = W[i - 13];\n var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15\n var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);\n var c3_hi = W[i - 32]; // i - 16\n var c3_lo = W[i - 31];\n\n W[i] = sum64_4_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n W[i + 1] = sum64_4_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n }\n};\n\nSHA512.prototype._update = function _update(msg, start) {\n this._prepareBlock(msg, start);\n\n var W = this.W;\n\n var ah = this.h[0];\n var al = this.h[1];\n var bh = this.h[2];\n var bl = this.h[3];\n var ch = this.h[4];\n var cl = this.h[5];\n var dh = this.h[6];\n var dl = this.h[7];\n var eh = this.h[8];\n var el = this.h[9];\n var fh = this.h[10];\n var fl = this.h[11];\n var gh = this.h[12];\n var gl = this.h[13];\n var hh = this.h[14];\n var hl = this.h[15];\n\n assert(this.k.length === W.length);\n for (var i = 0; i < W.length; i += 2) {\n var c0_hi = hh;\n var c0_lo = hl;\n var c1_hi = s1_512_hi(eh, el);\n var c1_lo = s1_512_lo(eh, el);\n var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);\n var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);\n var c3_hi = this.k[i];\n var c3_lo = this.k[i + 1];\n var c4_hi = W[i];\n var c4_lo = W[i + 1];\n\n var T1_hi = sum64_5_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n var T1_lo = sum64_5_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n\n c0_hi = s0_512_hi(ah, al);\n c0_lo = s0_512_lo(ah, al);\n c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);\n c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);\n\n var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);\n var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);\n\n hh = gh;\n hl = gl;\n\n gh = fh;\n gl = fl;\n\n fh = eh;\n fl = el;\n\n eh = sum64_hi(dh, dl, T1_hi, T1_lo);\n el = sum64_lo(dl, dl, T1_hi, T1_lo);\n\n dh = ch;\n dl = cl;\n\n ch = bh;\n cl = bl;\n\n bh = ah;\n bl = al;\n\n ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);\n al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);\n }\n\n sum64(this.h, 0, ah, al);\n sum64(this.h, 2, bh, bl);\n sum64(this.h, 4, ch, cl);\n sum64(this.h, 6, dh, dl);\n sum64(this.h, 8, eh, el);\n sum64(this.h, 10, fh, fl);\n sum64(this.h, 12, gh, gl);\n sum64(this.h, 14, hh, hl);\n};\n\nSHA512.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n\nfunction ch64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ ((~xh) & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction ch64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ ((~xl) & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 28);\n var c1_hi = rotr64_hi(xl, xh, 2); // 34\n var c2_hi = rotr64_hi(xl, xh, 7); // 39\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 28);\n var c1_lo = rotr64_lo(xl, xh, 2); // 34\n var c2_lo = rotr64_lo(xl, xh, 7); // 39\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 14);\n var c1_hi = rotr64_hi(xh, xl, 18);\n var c2_hi = rotr64_hi(xl, xh, 9); // 41\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 14);\n var c1_lo = rotr64_lo(xh, xl, 18);\n var c2_lo = rotr64_lo(xl, xh, 9); // 41\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 1);\n var c1_hi = rotr64_hi(xh, xl, 8);\n var c2_hi = shr64_hi(xh, xl, 7);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 1);\n var c1_lo = rotr64_lo(xh, xl, 8);\n var c2_lo = shr64_lo(xh, xl, 7);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 19);\n var c1_hi = rotr64_hi(xl, xh, 29); // 61\n var c2_hi = shr64_hi(xh, xl, 6);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 19);\n var c1_lo = rotr64_lo(xl, xh, 29); // 61\n var c2_lo = shr64_lo(xh, xl, 6);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTkwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixRQUFRO0FBQzFCO0FBQ0EsU0FBUyxjQUFjO0FBQ3ZCLGdEQUFnRDtBQUNoRDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzUxMi5qcz9iNTI1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbnZhciByb3RyNjRfaGkgPSB1dGlscy5yb3RyNjRfaGk7XG52YXIgcm90cjY0X2xvID0gdXRpbHMucm90cjY0X2xvO1xudmFyIHNocjY0X2hpID0gdXRpbHMuc2hyNjRfaGk7XG52YXIgc2hyNjRfbG8gPSB1dGlscy5zaHI2NF9sbztcbnZhciBzdW02NCA9IHV0aWxzLnN1bTY0O1xudmFyIHN1bTY0X2hpID0gdXRpbHMuc3VtNjRfaGk7XG52YXIgc3VtNjRfbG8gPSB1dGlscy5zdW02NF9sbztcbnZhciBzdW02NF80X2hpID0gdXRpbHMuc3VtNjRfNF9oaTtcbnZhciBzdW02NF80X2xvID0gdXRpbHMuc3VtNjRfNF9sbztcbnZhciBzdW02NF81X2hpID0gdXRpbHMuc3VtNjRfNV9oaTtcbnZhciBzdW02NF81X2xvID0gdXRpbHMuc3VtNjRfNV9sbztcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCxcbiAgICAweGJiNjdhZTg1LCAweDg0Y2FhNzNiLFxuICAgIDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIsXG4gICAgMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSxcbiAgICAweDUxMGU1MjdmLCAweGFkZTY4MmQxLFxuICAgIDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYsXG4gICAgMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YixcbiAgICAweDViZTBjZDE5LCAweDEzN2UyMTc5IF07XG4gIHRoaXMuayA9IHNoYTUxMl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoMTYwKTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTUxMiwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBNTEyO1xuXG5TSEE1MTIuYmxvY2tTaXplID0gMTAyNDtcblNIQTUxMi5vdXRTaXplID0gNTEyO1xuU0hBNTEyLmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTUxMi5wYWRMZW5ndGggPSAxMjg7XG5cblNIQTUxMi5wcm90b3R5cGUuX3ByZXBhcmVCbG9jayA9IGZ1bmN0aW9uIF9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICAvLyAzMiB4IDMyYml0IHdvcmRzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGcxXzUxMl9oaShXW2kgLSA0XSwgV1tpIC0gM10pOyAgLy8gaSAtIDJcbiAgICB2YXIgYzBfbG8gPSBnMV81MTJfbG8oV1tpIC0gNF0sIFdbaSAtIDNdKTtcbiAgICB2YXIgYzFfaGkgPSBXW2kgLSAxNF07ICAvLyBpIC0gN1xuICAgIHZhciBjMV9sbyA9IFdbaSAtIDEzXTtcbiAgICB2YXIgYzJfaGkgPSBnMF81MTJfaGkoV1tpIC0gMzBdLCBXW2kgLSAyOV0pOyAgLy8gaSAtIDE1XG4gICAgdmFyIGMyX2xvID0gZzBfNTEyX2xvKFdbaSAtIDMwXSwgV1tpIC0gMjldKTtcbiAgICB2YXIgYzNfaGkgPSBXW2kgLSAzMl07ICAvLyBpIC0gMTZcbiAgICB2YXIgYzNfbG8gPSBXW2kgLSAzMV07XG5cbiAgICBXW2ldID0gc3VtNjRfNF9oaShcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyk7XG4gICAgV1tpICsgMV0gPSBzdW02NF80X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcbiAgICB2YXIgVDFfbG8gPSBzdW02NF81X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcblxuICAgIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgYzBfbG8gPSBzMF81MTJfbG8oYWgsIGFsKTtcbiAgICBjMV9oaSA9IG1hajY0X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wpO1xuICAgIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gY2g2NF9oaSh4aCwgeGwsIHloLCB5bCwgemgpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICh4aCAmIHpoKSBeICh5aCAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKHhsICYgemwpIF4gKHlsICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDEpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDEpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5900\n")},7038:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar rotr32 = utils.rotr32;\n\nfunction ft_1(s, x, y, z) {\n if (s === 0)\n return ch32(x, y, z);\n if (s === 1 || s === 3)\n return p32(x, y, z);\n if (s === 2)\n return maj32(x, y, z);\n}\nexports.ft_1 = ft_1;\n\nfunction ch32(x, y, z) {\n return (x & y) ^ ((~x) & z);\n}\nexports.ch32 = ch32;\n\nfunction maj32(x, y, z) {\n return (x & y) ^ (x & z) ^ (y & z);\n}\nexports.maj32 = maj32;\n\nfunction p32(x, y, z) {\n return x ^ y ^ z;\n}\nexports.p32 = p32;\n\nfunction s0_256(x) {\n return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);\n}\nexports.s0_256 = s0_256;\n\nfunction s1_256(x) {\n return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);\n}\nexports.s1_256 = s1_256;\n\nfunction g0_256(x) {\n return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);\n}\nexports.g0_256 = g0_256;\n\nfunction g1_256(x) {\n return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);\n}\nexports.g1_256 = g1_256;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAzOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0EsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxjQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS9jb21tb24uanM/YWE1NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgcm90cjMyID0gdXRpbHMucm90cjMyO1xuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuZXhwb3J0cy5mdF8xID0gZnRfMTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cbmV4cG9ydHMuY2gzMiA9IGNoMzI7XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cbmV4cG9ydHMubWFqMzIgPSBtYWozMjtcblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cbmV4cG9ydHMucDMyID0gcDMyO1xuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5leHBvcnRzLnMwXzI1NiA9IHMwXzI1NjtcblxuZnVuY3Rpb24gczFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA2KSBeIHJvdHIzMih4LCAxMSkgXiByb3RyMzIoeCwgMjUpO1xufVxuZXhwb3J0cy5zMV8yNTYgPSBzMV8yNTY7XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuZXhwb3J0cy5nMF8yNTYgPSBnMF8yNTY7XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5leHBvcnRzLmcxXzI1NiA9IGcxXzI1NjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7038\n")},6436:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar assert = __webpack_require__(9746);\nvar inherits = __webpack_require__(5717);\n\nexports.inherits = inherits;\n\nfunction isSurrogatePair(msg, i) {\n if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {\n return false;\n }\n if (i < 0 || i + 1 >= msg.length) {\n return false;\n }\n return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;\n}\n\nfunction toArray(msg, enc) {\n if (Array.isArray(msg))\n return msg.slice();\n if (!msg)\n return [];\n var res = [];\n if (typeof msg === 'string') {\n if (!enc) {\n // Inspired by stringToUtf8ByteArray() in closure-library by Google\n // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143\n // Apache License 2.0\n // https://github.com/google/closure-library/blob/master/LICENSE\n var p = 0;\n for (var i = 0; i < msg.length; i++) {\n var c = msg.charCodeAt(i);\n if (c < 128) {\n res[p++] = c;\n } else if (c < 2048) {\n res[p++] = (c >> 6) | 192;\n res[p++] = (c & 63) | 128;\n } else if (isSurrogatePair(msg, i)) {\n c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);\n res[p++] = (c >> 18) | 240;\n res[p++] = ((c >> 12) & 63) | 128;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n } else {\n res[p++] = (c >> 12) | 224;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n }\n }\n } else if (enc === 'hex') {\n msg = msg.replace(/[^a-z0-9]+/ig, '');\n if (msg.length % 2 !== 0)\n msg = '0' + msg;\n for (i = 0; i < msg.length; i += 2)\n res.push(parseInt(msg[i] + msg[i + 1], 16));\n }\n } else {\n for (i = 0; i < msg.length; i++)\n res[i] = msg[i] | 0;\n }\n return res;\n}\nexports.toArray = toArray;\n\nfunction toHex(msg) {\n var res = '';\n for (var i = 0; i < msg.length; i++)\n res += zero2(msg[i].toString(16));\n return res;\n}\nexports.toHex = toHex;\n\nfunction htonl(w) {\n var res = (w >>> 24) |\n ((w >>> 8) & 0xff00) |\n ((w << 8) & 0xff0000) |\n ((w & 0xff) << 24);\n return res >>> 0;\n}\nexports.htonl = htonl;\n\nfunction toHex32(msg, endian) {\n var res = '';\n for (var i = 0; i < msg.length; i++) {\n var w = msg[i];\n if (endian === 'little')\n w = htonl(w);\n res += zero8(w.toString(16));\n }\n return res;\n}\nexports.toHex32 = toHex32;\n\nfunction zero2(word) {\n if (word.length === 1)\n return '0' + word;\n else\n return word;\n}\nexports.zero2 = zero2;\n\nfunction zero8(word) {\n if (word.length === 7)\n return '0' + word;\n else if (word.length === 6)\n return '00' + word;\n else if (word.length === 5)\n return '000' + word;\n else if (word.length === 4)\n return '0000' + word;\n else if (word.length === 3)\n return '00000' + word;\n else if (word.length === 2)\n return '000000' + word;\n else if (word.length === 1)\n return '0000000' + word;\n else\n return word;\n}\nexports.zero8 = zero8;\n\nfunction join32(msg, start, end, endian) {\n var len = end - start;\n assert(len % 4 === 0);\n var res = new Array(len / 4);\n for (var i = 0, k = start; i < res.length; i++, k += 4) {\n var w;\n if (endian === 'big')\n w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];\n else\n w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];\n res[i] = w >>> 0;\n }\n return res;\n}\nexports.join32 = join32;\n\nfunction split32(msg, endian) {\n var res = new Array(msg.length * 4);\n for (var i = 0, k = 0; i < msg.length; i++, k += 4) {\n var m = msg[i];\n if (endian === 'big') {\n res[k] = m >>> 24;\n res[k + 1] = (m >>> 16) & 0xff;\n res[k + 2] = (m >>> 8) & 0xff;\n res[k + 3] = m & 0xff;\n } else {\n res[k + 3] = m >>> 24;\n res[k + 2] = (m >>> 16) & 0xff;\n res[k + 1] = (m >>> 8) & 0xff;\n res[k] = m & 0xff;\n }\n }\n return res;\n}\nexports.split32 = split32;\n\nfunction rotr32(w, b) {\n return (w >>> b) | (w << (32 - b));\n}\nexports.rotr32 = rotr32;\n\nfunction rotl32(w, b) {\n return (w << b) | (w >>> (32 - b));\n}\nexports.rotl32 = rotl32;\n\nfunction sum32(a, b) {\n return (a + b) >>> 0;\n}\nexports.sum32 = sum32;\n\nfunction sum32_3(a, b, c) {\n return (a + b + c) >>> 0;\n}\nexports.sum32_3 = sum32_3;\n\nfunction sum32_4(a, b, c, d) {\n return (a + b + c + d) >>> 0;\n}\nexports.sum32_4 = sum32_4;\n\nfunction sum32_5(a, b, c, d, e) {\n return (a + b + c + d + e) >>> 0;\n}\nexports.sum32_5 = sum32_5;\n\nfunction sum64(buf, pos, ah, al) {\n var bh = buf[pos];\n var bl = buf[pos + 1];\n\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n buf[pos] = hi >>> 0;\n buf[pos + 1] = lo;\n}\nexports.sum64 = sum64;\n\nfunction sum64_hi(ah, al, bh, bl) {\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n return hi >>> 0;\n}\nexports.sum64_hi = sum64_hi;\n\nfunction sum64_lo(ah, al, bh, bl) {\n var lo = al + bl;\n return lo >>> 0;\n}\nexports.sum64_lo = sum64_lo;\n\nfunction sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n\n var hi = ah + bh + ch + dh + carry;\n return hi >>> 0;\n}\nexports.sum64_4_hi = sum64_4_hi;\n\nfunction sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {\n var lo = al + bl + cl + dl;\n return lo >>> 0;\n}\nexports.sum64_4_lo = sum64_4_lo;\n\nfunction sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n lo = (lo + el) >>> 0;\n carry += lo < el ? 1 : 0;\n\n var hi = ah + bh + ch + dh + eh + carry;\n return hi >>> 0;\n}\nexports.sum64_5_hi = sum64_5_hi;\n\nfunction sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var lo = al + bl + cl + dl + el;\n\n return lo >>> 0;\n}\nexports.sum64_5_lo = sum64_5_lo;\n\nfunction rotr64_hi(ah, al, num) {\n var r = (al << (32 - num)) | (ah >>> num);\n return r >>> 0;\n}\nexports.rotr64_hi = rotr64_hi;\n\nfunction rotr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.rotr64_lo = rotr64_lo;\n\nfunction shr64_hi(ah, al, num) {\n return ah >>> num;\n}\nexports.shr64_hi = shr64_hi;\n\nfunction shr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.shr64_lo = shr64_lo;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBcUI7QUFDMUMsZUFBZSxtQkFBTyxDQUFDLElBQVU7O0FBRWpDLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGdCQUFnQjtBQUN0QztBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0EsSUFBSTtBQUNKLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsZ0JBQWdCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcz9jM2MwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuaW5oZXJpdHMgPSBpbmhlcml0cztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkge1xuICBpZiAoKG1zZy5jaGFyQ29kZUF0KGkpICYgMHhGQzAwKSAhPT0gMHhEODAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpIDwgMCB8fCBpICsgMSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAobXNnLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwO1xufVxuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIC8vIEluc3BpcmVkIGJ5IHN0cmluZ1RvVXRmOEJ5dGVBcnJheSgpIGluIGNsb3N1cmUtbGlicmFyeSBieSBHb29nbGVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvODU5OGQ4NzI0MmFmNTlhYWMyMzMyNzA3NDJjODk4NGUyYjJiZGJlMC9jbG9zdXJlL2dvb2cvY3J5cHQvY3J5cHQuanMjTDExNy1MMTQzXG4gICAgICAvLyBBcGFjaGUgTGljZW5zZSAyLjBcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAgICAgIHZhciBwID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSBjO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPCAyMDQ4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyA+PiA2KSB8IDE5MjtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3Vycm9nYXRlUGFpcihtc2csIGkpKSB7XG4gICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgJiAweDAzRkYpIDw8IDEwKSArIChtc2cuY2hhckNvZGVBdCgrK2kpICYgMHgwM0ZGKTtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDE4KSB8IDI0MDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiAxMikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoKGMgPj4gNikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyAmIDYzKSB8IDEyODtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDEyKSB8IDIyNDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleCA9IHRvSGV4O1xuXG5mdW5jdGlvbiBodG9ubCh3KSB7XG4gIHZhciByZXMgPSAodyA+Pj4gMjQpIHxcbiAgICAgICAgICAgICgodyA+Pj4gOCkgJiAweGZmMDApIHxcbiAgICAgICAgICAgICgodyA8PCA4KSAmIDB4ZmYwMDAwKSB8XG4gICAgICAgICAgICAoKHcgJiAweGZmKSA8PCAyNCk7XG4gIHJldHVybiByZXMgPj4+IDA7XG59XG5leHBvcnRzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHplcm84KHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSA3KVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNilcbiAgICByZXR1cm4gJzAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA1KVxuICAgIHJldHVybiAnMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA0KVxuICAgIHJldHVybiAnMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMylcbiAgICByZXR1cm4gJzAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAyKVxuICAgIHJldHVybiAnMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMDAwMDAwMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5zcGxpdDMyID0gc3BsaXQzMjtcblxuZnVuY3Rpb24gcm90cjMyKHcsIGIpIHtcbiAgcmV0dXJuICh3ID4+PiBiKSB8ICh3IDw8ICgzMiAtIGIpKTtcbn1cbmV4cG9ydHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyID0gc3VtMzI7XG5cbmZ1bmN0aW9uIHN1bTMyXzMoYSwgYiwgYykge1xuICByZXR1cm4gKGEgKyBiICsgYykgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNSA9IHN1bTMyXzU7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0X2hpID0gc3VtNjRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0X2xvKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IGFsICsgYmw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNF9sbyA9IHN1bTY0XzRfbG87XG5cbmZ1bmN0aW9uIHN1bTY0XzVfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZWwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGVsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBlaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMucm90cjY0X2hpID0gcm90cjY0X2hpO1xuXG5mdW5jdGlvbiByb3RyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufVxuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnNocjY0X2xvID0gc2hyNjRfbG87XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6436\n")},5717:function(module){eval("if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTcxNy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzPzNmYjUiXSwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5717\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},9746:function(module){eval("module.exports = assert;\n\nfunction assert(val, msg) {\n if (!val)\n throw new Error(msg || 'Assertion failed');\n}\n\nassert.equal = function assertEqual(l, r, msg) {\n if (l != r)\n throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvbWluaW1hbGlzdGljLWFzc2VydC9pbmRleC5qcz9kYTNlIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXNzZXJ0O1xuXG5mdW5jdGlvbiBhc3NlcnQodmFsLCBtc2cpIHtcbiAgaWYgKCF2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBhc3NlcnRFcXVhbChsLCByLCBtc2cpIHtcbiAgaWYgKGwgIT0gcilcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICgnQXNzZXJ0aW9uIGZhaWxlZDogJyArIGwgKyAnICE9ICcgKyByKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9746\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz81OWY4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz8zNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/MWJmMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzP2I4OGUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NmRiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/ZmI1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz9mMGYzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/YjMwZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz82OTY3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzP2E4ZjciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz83NzYwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/Yjg2MiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzc0OWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz9hYTJiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82ZGMxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz83ZmY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZDJhYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzPzYwOGYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzPzY5NDciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz83YTkyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz80NTY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YjY2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzP2FhYTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz9lZDA1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz9mMTM2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZWVlNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz84MTA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzPzdmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz8zNTA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz9iYTg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz9jZGZlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz8zNGI3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzkxOWUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9jZjY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz8wZjA5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/ZTQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz8zMmFlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzJjNTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/ZThjZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/M2Q3NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9jNmVmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/MGFlMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/MmI4ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/NzczNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzPzViNGEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzPzY4MWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz81NmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzPzUxYTAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/M2JkYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz9iN2UzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzPzA5YmMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZThlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/MDY5OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/ZjhkMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz9lNGZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzPzJhMmYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/MTNkNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9jNjA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(Q){var t=__webpack_module_cache__[Q];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[Q]={exports:{}};return __webpack_modules__[Q](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=function(Q){var t=Q&&Q.__esModule?function(){return Q.default}:function(){return Q};return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=function(Q,t){for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(Q,n)&&Object.defineProperty(Q,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=function(Q,t){return Object.prototype.hasOwnProperty.call(Q,t)};var __webpack_exports__=__webpack_require__(3088)})(); \ No newline at end of file diff --git a/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js b/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js index b9d80c0718..8deeb4717c 100644 --- a/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js +++ b/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js @@ -1 +1 @@ -(function(){var __webpack_modules__={3089:function(__unused_webpack_module,exports){"use strict";eval('var __webpack_unused_export__;\n\n/**\n * Implementation of Myers\' online approximate string matching algorithm [1],\n * with additional optimizations suggested by [2].\n *\n * This has O((k/w) * n) complexity where `n` is the length of the text, `k` is\n * the maximum number of errors allowed (always <= the pattern length) and `w`\n * is the word size. Because JS only supports bitwise operations on 32 bit\n * integers, `w` is 32.\n *\n * As far as I am aware, there aren\'t any online algorithms which are\n * significantly better for a wide range of input parameters. The problem can be\n * solved faster using "filter then verify" approaches which first filter out\n * regions of the text that cannot match using a "cheap" check and then verify\n * the remaining potential matches. The verify step requires an algorithm such\n * as this one however.\n *\n * The algorithm\'s approach is essentially to optimize the classic dynamic\n * programming solution to the problem by computing columns of the matrix in\n * word-sized chunks (ie. dealing with 32 chars of the pattern at a time) and\n * avoiding calculating regions of the matrix where the minimum error count is\n * guaranteed to exceed the input threshold.\n *\n * The paper consists of two parts, the first describes the core algorithm for\n * matching patterns <= the size of a word (implemented by `advanceBlock` here).\n * The second uses the core algorithm as part of a larger block-based algorithm\n * to handle longer patterns.\n *\n * [1] G. Myers, “A Fast Bit-Vector Algorithm for Approximate String Matching\n * Based on Dynamic Programming,” vol. 46, no. 3, pp. 395–415, 1999.\n *\n * [2] Šošić, M. (2014). An simd dynamic programming c/c++ library (Doctoral\n * dissertation, Fakultet Elektrotehnike i računarstva, Sveučilište u Zagrebu).\n */\n__webpack_unused_export__ = ({ value: true });\nfunction reverse(s) {\n return s\n .split("")\n .reverse()\n .join("");\n}\n/**\n * Given the ends of approximate matches for `pattern` in `text`, find\n * the start of the matches.\n *\n * @param findEndFn - Function for finding the end of matches in\n * text.\n * @return Matches with the `start` property set.\n */\nfunction findMatchStarts(text, pattern, matches) {\n var patRev = reverse(pattern);\n return matches.map(function (m) {\n // Find start of each match by reversing the pattern and matching segment\n // of text and searching for an approx match with the same number of\n // errors.\n var minStart = Math.max(0, m.end - pattern.length - m.errors);\n var textRev = reverse(text.slice(minStart, m.end));\n // If there are multiple possible start points, choose the one that\n // maximizes the length of the match.\n var start = findMatchEnds(textRev, patRev, m.errors).reduce(function (min, rm) {\n if (m.end - rm.end < min) {\n return m.end - rm.end;\n }\n return min;\n }, m.end);\n return {\n start: start,\n end: m.end,\n errors: m.errors\n };\n });\n}\n/**\n * Return 1 if a number is non-zero or zero otherwise, without using\n * conditional operators.\n *\n * This should get inlined into `advanceBlock` below by the JIT.\n *\n * Adapted from https://stackoverflow.com/a/3912218/434243\n */\nfunction oneIfNotZero(n) {\n return ((n | -n) >> 31) & 1;\n}\n/**\n * Block calculation step of the algorithm.\n *\n * From Fig 8. on p. 408 of [1], additionally optimized to replace conditional\n * checks with bitwise operations as per Section 4.2.3 of [2].\n *\n * @param ctx - The pattern context object\n * @param peq - The `peq` array for the current character (`ctx.peq.get(ch)`)\n * @param b - The block level\n * @param hIn - Horizontal input delta ∈ {1,0,-1}\n * @return Horizontal output delta ∈ {1,0,-1}\n */\nfunction advanceBlock(ctx, peq, b, hIn) {\n var pV = ctx.P[b];\n var mV = ctx.M[b];\n var hInIsNegative = hIn >>> 31; // 1 if hIn < 0 or 0 otherwise.\n var eq = peq[b] | hInIsNegative;\n // Step 1: Compute horizontal deltas.\n var xV = eq | mV;\n var xH = (((eq & pV) + pV) ^ pV) | eq;\n var pH = mV | ~(xH | pV);\n var mH = pV & xH;\n // Step 2: Update score (value of last row of this block).\n var hOut = oneIfNotZero(pH & ctx.lastRowMask[b]) -\n oneIfNotZero(mH & ctx.lastRowMask[b]);\n // Step 3: Update vertical deltas for use when processing next char.\n pH <<= 1;\n mH <<= 1;\n mH |= hInIsNegative;\n pH |= oneIfNotZero(hIn) - hInIsNegative; // set pH[0] if hIn > 0\n pV = mH | ~(xV | pH);\n mV = pH & xV;\n ctx.P[b] = pV;\n ctx.M[b] = mV;\n return hOut;\n}\n/**\n * Find the ends and error counts for matches of `pattern` in `text`.\n *\n * Only the matches with the lowest error count are reported. Other matches\n * with error counts <= maxErrors are discarded.\n *\n * This is the block-based search algorithm from Fig. 9 on p.410 of [1].\n */\nfunction findMatchEnds(text, pattern, maxErrors) {\n if (pattern.length === 0) {\n return [];\n }\n // Clamp error count so we can rely on the `maxErrors` and `pattern.length`\n // rows being in the same block below.\n maxErrors = Math.min(maxErrors, pattern.length);\n var matches = [];\n // Word size.\n var w = 32;\n // Index of maximum block level.\n var bMax = Math.ceil(pattern.length / w) - 1;\n // Context used across block calculations.\n var ctx = {\n P: new Uint32Array(bMax + 1),\n M: new Uint32Array(bMax + 1),\n lastRowMask: new Uint32Array(bMax + 1)\n };\n ctx.lastRowMask.fill(1 << 31);\n ctx.lastRowMask[bMax] = 1 << (pattern.length - 1) % w;\n // Dummy "peq" array for chars in the text which do not occur in the pattern.\n var emptyPeq = new Uint32Array(bMax + 1);\n // Map of UTF-16 character code to bit vector indicating positions in the\n // pattern that equal that character.\n var peq = new Map();\n // Version of `peq` that only stores mappings for small characters. This\n // allows faster lookups when iterating through the text because a simple\n // array lookup can be done instead of a hash table lookup.\n var asciiPeq = [];\n for (var i = 0; i < 256; i++) {\n asciiPeq.push(emptyPeq);\n }\n // Calculate `ctx.peq` - a map of character values to bitmasks indicating\n // positions of that character within the pattern, where each bit represents\n // a position in the pattern.\n for (var c = 0; c < pattern.length; c += 1) {\n var val = pattern.charCodeAt(c);\n if (peq.has(val)) {\n // Duplicate char in pattern.\n continue;\n }\n var charPeq = new Uint32Array(bMax + 1);\n peq.set(val, charPeq);\n if (val < asciiPeq.length) {\n asciiPeq[val] = charPeq;\n }\n for (var b = 0; b <= bMax; b += 1) {\n charPeq[b] = 0;\n // Set all the bits where the pattern matches the current char (ch).\n // For indexes beyond the end of the pattern, always set the bit as if the\n // pattern contained a wildcard char in that position.\n for (var r = 0; r < w; r += 1) {\n var idx = b * w + r;\n if (idx >= pattern.length) {\n continue;\n }\n var match = pattern.charCodeAt(idx) === val;\n if (match) {\n charPeq[b] |= 1 << r;\n }\n }\n }\n }\n // Index of last-active block level in the column.\n var y = Math.max(0, Math.ceil(maxErrors / w) - 1);\n // Initialize maximum error count at bottom of each block.\n var score = new Uint32Array(bMax + 1);\n for (var b = 0; b <= y; b += 1) {\n score[b] = (b + 1) * w;\n }\n score[bMax] = pattern.length;\n // Initialize vertical deltas for each block.\n for (var b = 0; b <= y; b += 1) {\n ctx.P[b] = ~0;\n ctx.M[b] = 0;\n }\n // Process each char of the text, computing the error count for `w` chars of\n // the pattern at a time.\n for (var j = 0; j < text.length; j += 1) {\n // Lookup the bitmask representing the positions of the current char from\n // the text within the pattern.\n var charCode = text.charCodeAt(j);\n var charPeq = void 0;\n if (charCode < asciiPeq.length) {\n // Fast array lookup.\n charPeq = asciiPeq[charCode];\n }\n else {\n // Slower hash table lookup.\n charPeq = peq.get(charCode);\n if (typeof charPeq === "undefined") {\n charPeq = emptyPeq;\n }\n }\n // Calculate error count for blocks that we definitely have to process for\n // this column.\n var carry = 0;\n for (var b = 0; b <= y; b += 1) {\n carry = advanceBlock(ctx, charPeq, b, carry);\n score[b] += carry;\n }\n // Check if we also need to compute an additional block, or if we can reduce\n // the number of blocks processed for the next column.\n if (score[y] - carry <= maxErrors &&\n y < bMax &&\n (charPeq[y + 1] & 1 || carry < 0)) {\n // Error count for bottom block is under threshold, increase the number of\n // blocks processed for this column & next by 1.\n y += 1;\n ctx.P[y] = ~0;\n ctx.M[y] = 0;\n var maxBlockScore = y === bMax ? pattern.length % w : w;\n score[y] =\n score[y - 1] +\n maxBlockScore -\n carry +\n advanceBlock(ctx, charPeq, y, carry);\n }\n else {\n // Error count for bottom block exceeds threshold, reduce the number of\n // blocks processed for the next column.\n while (y > 0 && score[y] >= maxErrors + w) {\n y -= 1;\n }\n }\n // If error count is under threshold, report a match.\n if (y === bMax && score[y] <= maxErrors) {\n if (score[y] < maxErrors) {\n // Discard any earlier, worse matches.\n matches.splice(0, matches.length);\n }\n matches.push({\n start: -1,\n end: j + 1,\n errors: score[y]\n });\n // Because `search` only reports the matches with the lowest error count,\n // we can "ratchet down" the max error threshold whenever a match is\n // encountered and thereby save a small amount of work for the remainder\n // of the text.\n maxErrors = score[y];\n }\n }\n return matches;\n}\n/**\n * Search for matches for `pattern` in `text` allowing up to `maxErrors` errors.\n *\n * Returns the start, and end positions and error counts for each lowest-cost\n * match. Only the "best" matches are returned.\n */\nfunction search(text, pattern, maxErrors) {\n var matches = findMatchEnds(text, pattern, maxErrors);\n return findMatchStarts(text, pattern, matches);\n}\nexports.Z = search;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA4OS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkMsRUFBRSxhQUFhLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLE9BQU87QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2FwcHJveC1zdHJpbmctbWF0Y2gvZGlzdC9pbmRleC5qcz83MjMwIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBNeWVycycgb25saW5lIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBhbGdvcml0aG0gWzFdLFxuICogd2l0aCBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgc3VnZ2VzdGVkIGJ5IFsyXS5cbiAqXG4gKiBUaGlzIGhhcyBPKChrL3cpICogbikgY29tcGxleGl0eSB3aGVyZSBgbmAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCwgYGtgIGlzXG4gKiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIGFsbG93ZWQgKGFsd2F5cyA8PSB0aGUgcGF0dGVybiBsZW5ndGgpIGFuZCBgd2BcbiAqIGlzIHRoZSB3b3JkIHNpemUuIEJlY2F1c2UgSlMgb25seSBzdXBwb3J0cyBiaXR3aXNlIG9wZXJhdGlvbnMgb24gMzIgYml0XG4gKiBpbnRlZ2VycywgYHdgIGlzIDMyLlxuICpcbiAqIEFzIGZhciBhcyBJIGFtIGF3YXJlLCB0aGVyZSBhcmVuJ3QgYW55IG9ubGluZSBhbGdvcml0aG1zIHdoaWNoIGFyZVxuICogc2lnbmlmaWNhbnRseSBiZXR0ZXIgZm9yIGEgd2lkZSByYW5nZSBvZiBpbnB1dCBwYXJhbWV0ZXJzLiBUaGUgcHJvYmxlbSBjYW4gYmVcbiAqIHNvbHZlZCBmYXN0ZXIgdXNpbmcgXCJmaWx0ZXIgdGhlbiB2ZXJpZnlcIiBhcHByb2FjaGVzIHdoaWNoIGZpcnN0IGZpbHRlciBvdXRcbiAqIHJlZ2lvbnMgb2YgdGhlIHRleHQgdGhhdCBjYW5ub3QgbWF0Y2ggdXNpbmcgYSBcImNoZWFwXCIgY2hlY2sgYW5kIHRoZW4gdmVyaWZ5XG4gKiB0aGUgcmVtYWluaW5nIHBvdGVudGlhbCBtYXRjaGVzLiBUaGUgdmVyaWZ5IHN0ZXAgcmVxdWlyZXMgYW4gYWxnb3JpdGhtIHN1Y2hcbiAqIGFzIHRoaXMgb25lIGhvd2V2ZXIuXG4gKlxuICogVGhlIGFsZ29yaXRobSdzIGFwcHJvYWNoIGlzIGVzc2VudGlhbGx5IHRvIG9wdGltaXplIHRoZSBjbGFzc2ljIGR5bmFtaWNcbiAqIHByb2dyYW1taW5nIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGJ5IGNvbXB1dGluZyBjb2x1bW5zIG9mIHRoZSBtYXRyaXggaW5cbiAqIHdvcmQtc2l6ZWQgY2h1bmtzIChpZS4gZGVhbGluZyB3aXRoIDMyIGNoYXJzIG9mIHRoZSBwYXR0ZXJuIGF0IGEgdGltZSkgYW5kXG4gKiBhdm9pZGluZyBjYWxjdWxhdGluZyByZWdpb25zIG9mIHRoZSBtYXRyaXggd2hlcmUgdGhlIG1pbmltdW0gZXJyb3IgY291bnQgaXNcbiAqIGd1YXJhbnRlZWQgdG8gZXhjZWVkIHRoZSBpbnB1dCB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHBhcGVyIGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgdGhlIGZpcnN0IGRlc2NyaWJlcyB0aGUgY29yZSBhbGdvcml0aG0gZm9yXG4gKiBtYXRjaGluZyBwYXR0ZXJucyA8PSB0aGUgc2l6ZSBvZiBhIHdvcmQgKGltcGxlbWVudGVkIGJ5IGBhZHZhbmNlQmxvY2tgIGhlcmUpLlxuICogVGhlIHNlY29uZCB1c2VzIHRoZSBjb3JlIGFsZ29yaXRobSBhcyBwYXJ0IG9mIGEgbGFyZ2VyIGJsb2NrLWJhc2VkIGFsZ29yaXRobVxuICogdG8gaGFuZGxlIGxvbmdlciBwYXR0ZXJucy5cbiAqXG4gKiBbMV0gRy4gTXllcnMsIOKAnEEgRmFzdCBCaXQtVmVjdG9yIEFsZ29yaXRobSBmb3IgQXBwcm94aW1hdGUgU3RyaW5nIE1hdGNoaW5nXG4gKiBCYXNlZCBvbiBEeW5hbWljIFByb2dyYW1taW5nLOKAnSB2b2wuIDQ2LCBuby4gMywgcHAuIDM5NeKAkzQxNSwgMTk5OS5cbiAqXG4gKiBbMl0gxaBvxaFpxIcsIE0uICgyMDE0KS4gQW4gc2ltZCBkeW5hbWljIHByb2dyYW1taW5nIGMvYysrIGxpYnJhcnkgKERvY3RvcmFsXG4gKiBkaXNzZXJ0YXRpb24sIEZha3VsdGV0IEVsZWt0cm90ZWhuaWtlIGkgcmHEjXVuYXJzdHZhLCBTdmV1xI1pbGnFoXRlIHUgWmFncmVidSkuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJldmVyc2Uocykge1xuICAgIHJldHVybiBzXG4gICAgICAgIC5zcGxpdChcIlwiKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5qb2luKFwiXCIpO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgZW5kcyBvZiBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHRleHRgLCBmaW5kXG4gKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMuXG4gKlxuICogQHBhcmFtIGZpbmRFbmRGbiAtIEZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBlbmQgb2YgbWF0Y2hlcyBpblxuICogdGV4dC5cbiAqIEByZXR1cm4gTWF0Y2hlcyB3aXRoIHRoZSBgc3RhcnRgIHByb3BlcnR5IHNldC5cbiAqL1xuZnVuY3Rpb24gZmluZE1hdGNoU3RhcnRzKHRleHQsIHBhdHRlcm4sIG1hdGNoZXMpIHtcbiAgICB2YXIgcGF0UmV2ID0gcmV2ZXJzZShwYXR0ZXJuKTtcbiAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgLy8gRmluZCBzdGFydCBvZiBlYWNoIG1hdGNoIGJ5IHJldmVyc2luZyB0aGUgcGF0dGVybiBhbmQgbWF0Y2hpbmcgc2VnbWVudFxuICAgICAgICAvLyBvZiB0ZXh0IGFuZCBzZWFyY2hpbmcgZm9yIGFuIGFwcHJveCBtYXRjaCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZlxuICAgICAgICAvLyBlcnJvcnMuXG4gICAgICAgIHZhciBtaW5TdGFydCA9IE1hdGgubWF4KDAsIG0uZW5kIC0gcGF0dGVybi5sZW5ndGggLSBtLmVycm9ycyk7XG4gICAgICAgIHZhciB0ZXh0UmV2ID0gcmV2ZXJzZSh0ZXh0LnNsaWNlKG1pblN0YXJ0LCBtLmVuZCkpO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgc3RhcnQgcG9pbnRzLCBjaG9vc2UgdGhlIG9uZSB0aGF0XG4gICAgICAgIC8vIG1heGltaXplcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaC5cbiAgICAgICAgdmFyIHN0YXJ0ID0gZmluZE1hdGNoRW5kcyh0ZXh0UmV2LCBwYXRSZXYsIG0uZXJyb3JzKS5yZWR1Y2UoZnVuY3Rpb24gKG1pbiwgcm0pIHtcbiAgICAgICAgICAgIGlmIChtLmVuZCAtIHJtLmVuZCA8IG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmVuZCAtIHJtLmVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtaW47XG4gICAgICAgIH0sIG0uZW5kKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogbS5lbmQsXG4gICAgICAgICAgICBlcnJvcnM6IG0uZXJyb3JzXG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybiAxIGlmIGEgbnVtYmVyIGlzIG5vbi16ZXJvIG9yIHplcm8gb3RoZXJ3aXNlLCB3aXRob3V0IHVzaW5nXG4gKiBjb25kaXRpb25hbCBvcGVyYXRvcnMuXG4gKlxuICogVGhpcyBzaG91bGQgZ2V0IGlubGluZWQgaW50byBgYWR2YW5jZUJsb2NrYCBiZWxvdyBieSB0aGUgSklULlxuICpcbiAqIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzkxMjIxOC80MzQyNDNcbiAqL1xuZnVuY3Rpb24gb25lSWZOb3RaZXJvKG4pIHtcbiAgICByZXR1cm4gKChuIHwgLW4pID4+IDMxKSAmIDE7XG59XG4vKipcbiAqIEJsb2NrIGNhbGN1bGF0aW9uIHN0ZXAgb2YgdGhlIGFsZ29yaXRobS5cbiAqXG4gKiBGcm9tIEZpZyA4LiBvbiBwLiA0MDggb2YgWzFdLCBhZGRpdGlvbmFsbHkgb3B0aW1pemVkIHRvIHJlcGxhY2UgY29uZGl0aW9uYWxcbiAqIGNoZWNrcyB3aXRoIGJpdHdpc2Ugb3BlcmF0aW9ucyBhcyBwZXIgU2VjdGlvbiA0LjIuMyBvZiBbMl0uXG4gKlxuICogQHBhcmFtIGN0eCAtIFRoZSBwYXR0ZXJuIGNvbnRleHQgb2JqZWN0XG4gKiBAcGFyYW0gcGVxIC0gVGhlIGBwZXFgIGFycmF5IGZvciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgKGBjdHgucGVxLmdldChjaClgKVxuICogQHBhcmFtIGIgLSBUaGUgYmxvY2sgbGV2ZWxcbiAqIEBwYXJhbSBoSW4gLSBIb3Jpem9udGFsIGlucHV0IGRlbHRhIOKIiCB7MSwwLC0xfVxuICogQHJldHVybiBIb3Jpem9udGFsIG91dHB1dCBkZWx0YSDiiIggezEsMCwtMX1cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUJsb2NrKGN0eCwgcGVxLCBiLCBoSW4pIHtcbiAgICB2YXIgcFYgPSBjdHguUFtiXTtcbiAgICB2YXIgbVYgPSBjdHguTVtiXTtcbiAgICB2YXIgaEluSXNOZWdhdGl2ZSA9IGhJbiA+Pj4gMzE7IC8vIDEgaWYgaEluIDwgMCBvciAwIG90aGVyd2lzZS5cbiAgICB2YXIgZXEgPSBwZXFbYl0gfCBoSW5Jc05lZ2F0aXZlO1xuICAgIC8vIFN0ZXAgMTogQ29tcHV0ZSBob3Jpem9udGFsIGRlbHRhcy5cbiAgICB2YXIgeFYgPSBlcSB8IG1WO1xuICAgIHZhciB4SCA9ICgoKGVxICYgcFYpICsgcFYpIF4gcFYpIHwgZXE7XG4gICAgdmFyIHBIID0gbVYgfCB+KHhIIHwgcFYpO1xuICAgIHZhciBtSCA9IHBWICYgeEg7XG4gICAgLy8gU3RlcCAyOiBVcGRhdGUgc2NvcmUgKHZhbHVlIG9mIGxhc3Qgcm93IG9mIHRoaXMgYmxvY2spLlxuICAgIHZhciBoT3V0ID0gb25lSWZOb3RaZXJvKHBIICYgY3R4Lmxhc3RSb3dNYXNrW2JdKSAtXG4gICAgICAgIG9uZUlmTm90WmVybyhtSCAmIGN0eC5sYXN0Um93TWFza1tiXSk7XG4gICAgLy8gU3RlcCAzOiBVcGRhdGUgdmVydGljYWwgZGVsdGFzIGZvciB1c2Ugd2hlbiBwcm9jZXNzaW5nIG5leHQgY2hhci5cbiAgICBwSCA8PD0gMTtcbiAgICBtSCA8PD0gMTtcbiAgICBtSCB8PSBoSW5Jc05lZ2F0aXZlO1xuICAgIHBIIHw9IG9uZUlmTm90WmVybyhoSW4pIC0gaEluSXNOZWdhdGl2ZTsgLy8gc2V0IHBIWzBdIGlmIGhJbiA+IDBcbiAgICBwViA9IG1IIHwgfih4ViB8IHBIKTtcbiAgICBtViA9IHBIICYgeFY7XG4gICAgY3R4LlBbYl0gPSBwVjtcbiAgICBjdHguTVtiXSA9IG1WO1xuICAgIHJldHVybiBoT3V0O1xufVxuLyoqXG4gKiBGaW5kIHRoZSBlbmRzIGFuZCBlcnJvciBjb3VudHMgZm9yIG1hdGNoZXMgb2YgYHBhdHRlcm5gIGluIGB0ZXh0YC5cbiAqXG4gKiBPbmx5IHRoZSBtYXRjaGVzIHdpdGggdGhlIGxvd2VzdCBlcnJvciBjb3VudCBhcmUgcmVwb3J0ZWQuIE90aGVyIG1hdGNoZXNcbiAqIHdpdGggZXJyb3IgY291bnRzIDw9IG1heEVycm9ycyBhcmUgZGlzY2FyZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGJsb2NrLWJhc2VkIHNlYXJjaCBhbGdvcml0aG0gZnJvbSBGaWcuIDkgb24gcC40MTAgb2YgWzFdLlxuICovXG5mdW5jdGlvbiBmaW5kTWF0Y2hFbmRzKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIENsYW1wIGVycm9yIGNvdW50IHNvIHdlIGNhbiByZWx5IG9uIHRoZSBgbWF4RXJyb3JzYCBhbmQgYHBhdHRlcm4ubGVuZ3RoYFxuICAgIC8vIHJvd3MgYmVpbmcgaW4gdGhlIHNhbWUgYmxvY2sgYmVsb3cuXG4gICAgbWF4RXJyb3JzID0gTWF0aC5taW4obWF4RXJyb3JzLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgICAvLyBXb3JkIHNpemUuXG4gICAgdmFyIHcgPSAzMjtcbiAgICAvLyBJbmRleCBvZiBtYXhpbXVtIGJsb2NrIGxldmVsLlxuICAgIHZhciBiTWF4ID0gTWF0aC5jZWlsKHBhdHRlcm4ubGVuZ3RoIC8gdykgLSAxO1xuICAgIC8vIENvbnRleHQgdXNlZCBhY3Jvc3MgYmxvY2sgY2FsY3VsYXRpb25zLlxuICAgIHZhciBjdHggPSB7XG4gICAgICAgIFA6IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIE06IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIGxhc3RSb3dNYXNrOiBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpXG4gICAgfTtcbiAgICBjdHgubGFzdFJvd01hc2suZmlsbCgxIDw8IDMxKTtcbiAgICBjdHgubGFzdFJvd01hc2tbYk1heF0gPSAxIDw8IChwYXR0ZXJuLmxlbmd0aCAtIDEpICUgdztcbiAgICAvLyBEdW1teSBcInBlcVwiIGFycmF5IGZvciBjaGFycyBpbiB0aGUgdGV4dCB3aGljaCBkbyBub3Qgb2NjdXIgaW4gdGhlIHBhdHRlcm4uXG4gICAgdmFyIGVtcHR5UGVxID0gbmV3IFVpbnQzMkFycmF5KGJNYXggKyAxKTtcbiAgICAvLyBNYXAgb2YgVVRGLTE2IGNoYXJhY3RlciBjb2RlIHRvIGJpdCB2ZWN0b3IgaW5kaWNhdGluZyBwb3NpdGlvbnMgaW4gdGhlXG4gICAgLy8gcGF0dGVybiB0aGF0IGVxdWFsIHRoYXQgY2hhcmFjdGVyLlxuICAgIHZhciBwZXEgPSBuZXcgTWFwKCk7XG4gICAgLy8gVmVyc2lvbiBvZiBgcGVxYCB0aGF0IG9ubHkgc3RvcmVzIG1hcHBpbmdzIGZvciBzbWFsbCBjaGFyYWN0ZXJzLiBUaGlzXG4gICAgLy8gYWxsb3dzIGZhc3RlciBsb29rdXBzIHdoZW4gaXRlcmF0aW5nIHRocm91Z2ggdGhlIHRleHQgYmVjYXVzZSBhIHNpbXBsZVxuICAgIC8vIGFycmF5IGxvb2t1cCBjYW4gYmUgZG9uZSBpbnN0ZWFkIG9mIGEgaGFzaCB0YWJsZSBsb29rdXAuXG4gICAgdmFyIGFzY2lpUGVxID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgICBhc2NpaVBlcS5wdXNoKGVtcHR5UGVxKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlIGBjdHgucGVxYCAtIGEgbWFwIG9mIGNoYXJhY3RlciB2YWx1ZXMgdG8gYml0bWFza3MgaW5kaWNhdGluZ1xuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGF0IGNoYXJhY3RlciB3aXRoaW4gdGhlIHBhdHRlcm4sIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHNcbiAgICAvLyBhIHBvc2l0aW9uIGluIHRoZSBwYXR0ZXJuLlxuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgcGF0dGVybi5sZW5ndGg7IGMgKz0gMSkge1xuICAgICAgICB2YXIgdmFsID0gcGF0dGVybi5jaGFyQ29kZUF0KGMpO1xuICAgICAgICBpZiAocGVxLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgY2hhciBpbiBwYXR0ZXJuLlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoYXJQZXEgPSBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpO1xuICAgICAgICBwZXEuc2V0KHZhbCwgY2hhclBlcSk7XG4gICAgICAgIGlmICh2YWwgPCBhc2NpaVBlcS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFzY2lpUGVxW3ZhbF0gPSBjaGFyUGVxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGIgPSAwOyBiIDw9IGJNYXg7IGIgKz0gMSkge1xuICAgICAgICAgICAgY2hhclBlcVtiXSA9IDA7XG4gICAgICAgICAgICAvLyBTZXQgYWxsIHRoZSBiaXRzIHdoZXJlIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGN1cnJlbnQgY2hhciAoY2gpLlxuICAgICAgICAgICAgLy8gRm9yIGluZGV4ZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIGFsd2F5cyBzZXQgdGhlIGJpdCBhcyBpZiB0aGVcbiAgICAgICAgICAgIC8vIHBhdHRlcm4gY29udGFpbmVkIGEgd2lsZGNhcmQgY2hhciBpbiB0aGF0IHBvc2l0aW9uLlxuICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCB3OyByICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gYiAqIHcgKyByO1xuICAgICAgICAgICAgICAgIGlmIChpZHggPj0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IHBhdHRlcm4uY2hhckNvZGVBdChpZHgpID09PSB2YWw7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJQZXFbYl0gfD0gMSA8PCByO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJbmRleCBvZiBsYXN0LWFjdGl2ZSBibG9jayBsZXZlbCBpbiB0aGUgY29sdW1uLlxuICAgIHZhciB5ID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKG1heEVycm9ycyAvIHcpIC0gMSk7XG4gICAgLy8gSW5pdGlhbGl6ZSBtYXhpbXVtIGVycm9yIGNvdW50IGF0IGJvdHRvbSBvZiBlYWNoIGJsb2NrLlxuICAgIHZhciBzY29yZSA9IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSk7XG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIHNjb3JlW2JdID0gKGIgKyAxKSAqIHc7XG4gICAgfVxuICAgIHNjb3JlW2JNYXhdID0gcGF0dGVybi5sZW5ndGg7XG4gICAgLy8gSW5pdGlhbGl6ZSB2ZXJ0aWNhbCBkZWx0YXMgZm9yIGVhY2ggYmxvY2suXG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIGN0eC5QW2JdID0gfjA7XG4gICAgICAgIGN0eC5NW2JdID0gMDtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBlYWNoIGNoYXIgb2YgdGhlIHRleHQsIGNvbXB1dGluZyB0aGUgZXJyb3IgY291bnQgZm9yIGB3YCBjaGFycyBvZlxuICAgIC8vIHRoZSBwYXR0ZXJuIGF0IGEgdGltZS5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRleHQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBiaXRtYXNrIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb25zIG9mIHRoZSBjdXJyZW50IGNoYXIgZnJvbVxuICAgICAgICAvLyB0aGUgdGV4dCB3aXRoaW4gdGhlIHBhdHRlcm4uXG4gICAgICAgIHZhciBjaGFyQ29kZSA9IHRleHQuY2hhckNvZGVBdChqKTtcbiAgICAgICAgdmFyIGNoYXJQZXEgPSB2b2lkIDA7XG4gICAgICAgIGlmIChjaGFyQ29kZSA8IGFzY2lpUGVxLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gRmFzdCBhcnJheSBsb29rdXAuXG4gICAgICAgICAgICBjaGFyUGVxID0gYXNjaWlQZXFbY2hhckNvZGVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU2xvd2VyIGhhc2ggdGFibGUgbG9va3VwLlxuICAgICAgICAgICAgY2hhclBlcSA9IHBlcS5nZXQoY2hhckNvZGUpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyUGVxID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgY2hhclBlcSA9IGVtcHR5UGVxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3VudCBmb3IgYmxvY2tzIHRoYXQgd2UgZGVmaW5pdGVseSBoYXZlIHRvIHByb2Nlc3MgZm9yXG4gICAgICAgIC8vIHRoaXMgY29sdW1uLlxuICAgICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBiID0gMDsgYiA8PSB5OyBiICs9IDEpIHtcbiAgICAgICAgICAgIGNhcnJ5ID0gYWR2YW5jZUJsb2NrKGN0eCwgY2hhclBlcSwgYiwgY2FycnkpO1xuICAgICAgICAgICAgc2NvcmVbYl0gKz0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgYWxzbyBuZWVkIHRvIGNvbXB1dGUgYW4gYWRkaXRpb25hbCBibG9jaywgb3IgaWYgd2UgY2FuIHJlZHVjZVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGJsb2NrcyBwcm9jZXNzZWQgZm9yIHRoZSBuZXh0IGNvbHVtbi5cbiAgICAgICAgaWYgKHNjb3JlW3ldIC0gY2FycnkgPD0gbWF4RXJyb3JzICYmXG4gICAgICAgICAgICB5IDwgYk1heCAmJlxuICAgICAgICAgICAgKGNoYXJQZXFbeSArIDFdICYgMSB8fCBjYXJyeSA8IDApKSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGlzIHVuZGVyIHRocmVzaG9sZCwgaW5jcmVhc2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhpcyBjb2x1bW4gJiBuZXh0IGJ5IDEuXG4gICAgICAgICAgICB5ICs9IDE7XG4gICAgICAgICAgICBjdHguUFt5XSA9IH4wO1xuICAgICAgICAgICAgY3R4Lk1beV0gPSAwO1xuICAgICAgICAgICAgdmFyIG1heEJsb2NrU2NvcmUgPSB5ID09PSBiTWF4ID8gcGF0dGVybi5sZW5ndGggJSB3IDogdztcbiAgICAgICAgICAgIHNjb3JlW3ldID1cbiAgICAgICAgICAgICAgICBzY29yZVt5IC0gMV0gK1xuICAgICAgICAgICAgICAgICAgICBtYXhCbG9ja1Njb3JlIC1cbiAgICAgICAgICAgICAgICAgICAgY2FycnkgK1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlQmxvY2soY3R4LCBjaGFyUGVxLCB5LCBjYXJyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGV4Y2VlZHMgdGhyZXNob2xkLCByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhlIG5leHQgY29sdW1uLlxuICAgICAgICAgICAgd2hpbGUgKHkgPiAwICYmIHNjb3JlW3ldID49IG1heEVycm9ycyArIHcpIHtcbiAgICAgICAgICAgICAgICB5IC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZXJyb3IgY291bnQgaXMgdW5kZXIgdGhyZXNob2xkLCByZXBvcnQgYSBtYXRjaC5cbiAgICAgICAgaWYgKHkgPT09IGJNYXggJiYgc2NvcmVbeV0gPD0gbWF4RXJyb3JzKSB7XG4gICAgICAgICAgICBpZiAoc2NvcmVbeV0gPCBtYXhFcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIGFueSBlYXJsaWVyLCB3b3JzZSBtYXRjaGVzLlxuICAgICAgICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKDAsIG1hdGNoZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICAgICAgICAgIGVuZDogaiArIDEsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBzY29yZVt5XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBCZWNhdXNlIGBzZWFyY2hgIG9ubHkgcmVwb3J0cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBsb3dlc3QgZXJyb3IgY291bnQsXG4gICAgICAgICAgICAvLyB3ZSBjYW4gXCJyYXRjaGV0IGRvd25cIiB0aGUgbWF4IGVycm9yIHRocmVzaG9sZCB3aGVuZXZlciBhIG1hdGNoIGlzXG4gICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbmQgdGhlcmVieSBzYXZlIGEgc21hbGwgYW1vdW50IG9mIHdvcmsgZm9yIHRoZSByZW1haW5kZXJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB0ZXh0LlxuICAgICAgICAgICAgbWF4RXJyb3JzID0gc2NvcmVbeV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59XG4vKipcbiAqIFNlYXJjaCBmb3IgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogUmV0dXJucyB0aGUgc3RhcnQsIGFuZCBlbmQgcG9zaXRpb25zIGFuZCBlcnJvciBjb3VudHMgZm9yIGVhY2ggbG93ZXN0LWNvc3RcbiAqIG1hdGNoLiBPbmx5IHRoZSBcImJlc3RcIiBtYXRjaGVzIGFyZSByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoRW5kcyh0ZXh0LCBwYXR0ZXJuLCBtYXhFcnJvcnMpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hTdGFydHModGV4dCwgcGF0dGVybiwgbWF0Y2hlcyk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzZWFyY2g7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3089\n')},5232:function(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__){"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/approx-string-match/dist/index.js\nvar dist = __webpack_require__(3089);\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/match-quote.js\n\n/**\n * @typedef {import(\'approx-string-match\').Match} StringMatch\n */\n\n/**\n * @typedef Match\n * @prop {number} start - Start offset of match in text\n * @prop {number} end - End offset of match in text\n * @prop {number} score -\n * Score for the match between 0 and 1.0, where 1.0 indicates a perfect match\n * for the quote and context.\n */\n\n/**\n * Find the best approximate matches for `str` in `text` allowing up to `maxErrors` errors.\n *\n * @param {string} text\n * @param {string} str\n * @param {number} maxErrors\n * @return {StringMatch[]}\n */\n\nfunction search(text, str, maxErrors) {\n // Do a fast search for exact matches. The `approx-string-match` library\n // doesn\'t currently incorporate this optimization itself.\n var matchPos = 0;\n var exactMatches = [];\n\n while (matchPos !== -1) {\n matchPos = text.indexOf(str, matchPos);\n\n if (matchPos !== -1) {\n exactMatches.push({\n start: matchPos,\n end: matchPos + str.length,\n errors: 0\n });\n matchPos += 1;\n }\n }\n\n if (exactMatches.length > 0) {\n return exactMatches;\n } // If there are no exact matches, do a more expensive search for matches\n // with errors.\n\n\n return (0,dist/* default */.Z)(text, str, maxErrors);\n}\n/**\n * Compute a score between 0 and 1.0 for the similarity between `text` and `str`.\n *\n * @param {string} text\n * @param {string} str\n */\n\n\nfunction textMatchScore(text, str) {\n /* istanbul ignore next - `scoreMatch` will never pass an empty string */\n if (str.length === 0 || text.length === 0) {\n return 0.0;\n }\n\n var matches = search(text, str, str.length); // prettier-ignore\n\n return 1 - matches[0].errors / str.length;\n}\n/**\n * Find the best approximate match for `quote` in `text`.\n *\n * Returns `null` if no match exceeding the minimum quality threshold was found.\n *\n * @param {string} text - Document text to search\n * @param {string} quote - String to find within `text`\n * @param {Object} context -\n * Context in which the quote originally appeared. This is used to choose the\n * best match.\n * @param {string} [context.prefix] - Expected text before the quote\n * @param {string} [context.suffix] - Expected text after the quote\n * @param {number} [context.hint] - Expected offset of match within text\n * @return {Match|null}\n */\n\n\nfunction matchQuote(text, quote) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (quote.length === 0) {\n return null;\n } // Choose the maximum number of errors to allow for the initial search.\n // This choice involves a tradeoff between:\n //\n // - Recall (proportion of "good" matches found)\n // - Precision (proportion of matches found which are "good")\n // - Cost of the initial search and of processing the candidate matches [1]\n //\n // [1] Specifically, the expected-time complexity of the initial search is\n // `O((maxErrors / 32) * text.length)`. See `approx-string-match` docs.\n\n\n var maxErrors = Math.min(256, quote.length / 2); // Find closest matches for `quote` in `text` based on edit distance.\n\n var matches = search(text, quote, maxErrors);\n\n if (matches.length === 0) {\n return null;\n }\n /**\n * Compute a score between 0 and 1.0 for a match candidate.\n *\n * @param {StringMatch} match\n */\n\n\n var scoreMatch = function scoreMatch(match) {\n var quoteWeight = 50; // Similarity of matched text to quote.\n\n var prefixWeight = 20; // Similarity of text before matched text to `context.prefix`.\n\n var suffixWeight = 20; // Similarity of text after matched text to `context.suffix`.\n\n var posWeight = 2; // Proximity to expected location. Used as a tie-breaker.\n\n var quoteScore = 1 - match.errors / quote.length;\n var prefixScore = context.prefix ? textMatchScore(text.slice(Math.max(0, match.start - context.prefix.length), match.start), context.prefix) : 1.0;\n var suffixScore = context.suffix ? textMatchScore(text.slice(match.end, match.end + context.suffix.length), context.suffix) : 1.0;\n var posScore = 1.0;\n\n if (typeof context.hint === \'number\') {\n var offset = Math.abs(match.start - context.hint);\n posScore = 1.0 - offset / text.length;\n }\n\n var rawScore = quoteWeight * quoteScore + prefixWeight * prefixScore + suffixWeight * suffixScore + posWeight * posScore;\n var maxScore = quoteWeight + prefixWeight + suffixWeight + posWeight;\n var normalizedScore = rawScore / maxScore;\n return normalizedScore;\n }; // Rank matches based on similarity of actual and expected surrounding text\n // and actual/expected offset in the document text.\n\n\n var scoredMatches = matches.map(function (m) {\n return {\n start: m.start,\n end: m.end,\n score: scoreMatch(m)\n };\n }); // Choose match with highest score.\n\n scoredMatches.sort(function (a, b) {\n return b.score - a.score;\n });\n return scoredMatches[0];\n}\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/text-range.js\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Return the combined length of text nodes contained in `node`.\n *\n * @param {Node} node\n */\nfunction nodeTextLength(node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.TEXT_NODE:\n // nb. `textContent` excludes text in comments and processing instructions\n // when called on a parent element, so we don\'t need to subtract that here.\n return (\n /** @type {string} */\n node.textContent.length\n );\n\n default:\n return 0;\n }\n}\n/**\n * Return the total length of the text of all previous siblings of `node`.\n *\n * @param {Node} node\n */\n\n\nfunction previousSiblingsTextLength(node) {\n var sibling = node.previousSibling;\n var length = 0;\n\n while (sibling) {\n length += nodeTextLength(sibling);\n sibling = sibling.previousSibling;\n }\n\n return length;\n}\n/**\n * Resolve one or more character offsets within an element to (text node, position)\n * pairs.\n *\n * @param {Element} element\n * @param {number[]} offsets - Offsets, which must be sorted in ascending order\n * @return {{ node: Text, offset: number }[]}\n */\n\n\nfunction resolveOffsets(element) {\n for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n offsets[_key - 1] = arguments[_key];\n }\n\n var nextOffset = offsets.shift();\n var nodeIter =\n /** @type {Document} */\n element.ownerDocument.createNodeIterator(element, NodeFilter.SHOW_TEXT);\n var results = [];\n var currentNode = nodeIter.nextNode();\n var textNode;\n var length = 0; // Find the text node containing the `nextOffset`th character from the start\n // of `element`.\n\n while (nextOffset !== undefined && currentNode) {\n textNode =\n /** @type {Text} */\n currentNode;\n\n if (length + textNode.data.length > nextOffset) {\n results.push({\n node: textNode,\n offset: nextOffset - length\n });\n nextOffset = offsets.shift();\n } else {\n currentNode = nodeIter.nextNode();\n length += textNode.data.length;\n }\n } // Boundary case.\n\n\n while (nextOffset !== undefined && textNode && length === nextOffset) {\n results.push({\n node: textNode,\n offset: textNode.data.length\n });\n nextOffset = offsets.shift();\n }\n\n if (nextOffset !== undefined) {\n throw new RangeError(\'Offset exceeds text length\');\n }\n\n return results;\n}\n\nvar RESOLVE_FORWARDS = 1;\nvar RESOLVE_BACKWARDS = 2;\n/**\n * Represents an offset within the text content of an element.\n *\n * This position can be resolved to a specific descendant node in the current\n * DOM subtree of the element using the `resolve` method.\n */\n\nvar text_range_TextPosition = /*#__PURE__*/function () {\n /**\n * Construct a `TextPosition` that refers to the text position `offset` within\n * the text content of `element`.\n *\n * @param {Element} element\n * @param {number} offset\n */\n function TextPosition(element, offset) {\n _classCallCheck(this, TextPosition);\n\n if (offset < 0) {\n throw new Error(\'Offset is invalid\');\n }\n /** Element that `offset` is relative to. */\n\n\n this.element = element;\n /** Character offset from the start of the element\'s `textContent`. */\n\n this.offset = offset;\n }\n /**\n * Return a copy of this position with offset relative to a given ancestor\n * element.\n *\n * @param {Element} parent - Ancestor of `this.element`\n * @return {TextPosition}\n */\n\n\n _createClass(TextPosition, [{\n key: "relativeTo",\n value: function relativeTo(parent) {\n if (!parent.contains(this.element)) {\n throw new Error(\'Parent is not an ancestor of current element\');\n }\n\n var el = this.element;\n var offset = this.offset;\n\n while (el !== parent) {\n offset += previousSiblingsTextLength(el);\n el =\n /** @type {Element} */\n el.parentElement;\n }\n\n return new TextPosition(el, offset);\n }\n /**\n * Resolve the position to a specific text node and offset within that node.\n *\n * Throws if `this.offset` exceeds the length of the element\'s text. In the\n * case where the element has no text and `this.offset` is 0, the `direction`\n * option determines what happens.\n *\n * Offsets at the boundary between two nodes are resolved to the start of the\n * node that begins at the boundary.\n *\n * @param {Object} [options]\n * @param {RESOLVE_FORWARDS|RESOLVE_BACKWARDS} [options.direction] -\n * Specifies in which direction to search for the nearest text node if\n * `this.offset` is `0` and `this.element` has no text. If not specified\n * an error is thrown.\n * @return {{ node: Text, offset: number }}\n * @throws {RangeError}\n */\n\n }, {\n key: "resolve",\n value: function resolve() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n try {\n return resolveOffsets(this.element, this.offset)[0];\n } catch (err) {\n if (this.offset === 0 && options.direction !== undefined) {\n var tw = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);\n tw.currentNode = this.element;\n var forwards = options.direction === RESOLVE_FORWARDS;\n var text =\n /** @type {Text|null} */\n forwards ? tw.nextNode() : tw.previousNode();\n\n if (!text) {\n throw err;\n }\n\n return {\n node: text,\n offset: forwards ? 0 : text.data.length\n };\n } else {\n throw err;\n }\n }\n }\n /**\n * Construct a `TextPosition` that refers to the `offset`th character within\n * `node`.\n *\n * @param {Node} node\n * @param {number} offset\n * @return {TextPosition}\n */\n\n }], [{\n key: "fromCharOffset",\n value: function fromCharOffset(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n return TextPosition.fromPoint(node, offset);\n\n case Node.ELEMENT_NODE:\n return new TextPosition(\n /** @type {Element} */\n node, offset);\n\n default:\n throw new Error(\'Node is not an element or text node\');\n }\n }\n /**\n * Construct a `TextPosition` representing the range start or end point (node, offset).\n *\n * @param {Node} node - Text or Element node\n * @param {number} offset - Offset within the node.\n * @return {TextPosition}\n */\n\n }, {\n key: "fromPoint",\n value: function fromPoint(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n {\n if (offset < 0 || offset >\n /** @type {Text} */\n node.data.length) {\n throw new Error(\'Text node offset is out of range\');\n }\n\n if (!node.parentElement) {\n throw new Error(\'Text node has no parent\');\n } // Get the offset from the start of the parent element.\n\n\n var textOffset = previousSiblingsTextLength(node) + offset;\n return new TextPosition(node.parentElement, textOffset);\n }\n\n case Node.ELEMENT_NODE:\n {\n if (offset < 0 || offset > node.childNodes.length) {\n throw new Error(\'Child node offset is out of range\');\n } // Get the text length before the `offset`th child of element.\n\n\n var _textOffset = 0;\n\n for (var i = 0; i < offset; i++) {\n _textOffset += nodeTextLength(node.childNodes[i]);\n }\n\n return new TextPosition(\n /** @type {Element} */\n node, _textOffset);\n }\n\n default:\n throw new Error(\'Point is not in an element or text node\');\n }\n }\n }]);\n\n return TextPosition;\n}();\n/**\n * Represents a region of a document as a (start, end) pair of `TextPosition` points.\n *\n * Representing a range in this way allows for changes in the DOM content of the\n * range which don\'t affect its text content, without affecting the text content\n * of the range itself.\n */\n\nvar text_range_TextRange = /*#__PURE__*/function () {\n /**\n * Construct an immutable `TextRange` from a `start` and `end` point.\n *\n * @param {TextPosition} start\n * @param {TextPosition} end\n */\n function TextRange(start, end) {\n _classCallCheck(this, TextRange);\n\n this.start = start;\n this.end = end;\n }\n /**\n * Return a copy of this range with start and end positions relative to a\n * given ancestor. See `TextPosition.relativeTo`.\n *\n * @param {Element} element\n */\n\n\n _createClass(TextRange, [{\n key: "relativeTo",\n value: function relativeTo(element) {\n return new TextRange(this.start.relativeTo(element), this.end.relativeTo(element));\n }\n /**\n * Resolve the `TextRange` to a DOM range.\n *\n * The resulting DOM Range will always start and end in a `Text` node.\n * Hence `TextRange.fromRange(range).toRange()` can be used to "shrink" a\n * range to the text it contains.\n *\n * May throw if the `start` or `end` positions cannot be resolved to a range.\n *\n * @return {Range}\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var start;\n var end;\n\n if (this.start.element === this.end.element && this.start.offset <= this.end.offset) {\n // Fast path for start and end points in same element.\n var _resolveOffsets = resolveOffsets(this.start.element, this.start.offset, this.end.offset);\n\n var _resolveOffsets2 = _slicedToArray(_resolveOffsets, 2);\n\n start = _resolveOffsets2[0];\n end = _resolveOffsets2[1];\n } else {\n start = this.start.resolve({\n direction: RESOLVE_FORWARDS\n });\n end = this.end.resolve({\n direction: RESOLVE_BACKWARDS\n });\n }\n\n var range = new Range();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range;\n }\n /**\n * Convert an existing DOM `Range` to a `TextRange`\n *\n * @param {Range} range\n * @return {TextRange}\n */\n\n }], [{\n key: "fromRange",\n value: function fromRange(range) {\n var start = text_range_TextPosition.fromPoint(range.startContainer, range.startOffset);\n var end = text_range_TextPosition.fromPoint(range.endContainer, range.endOffset);\n return new TextRange(start, end);\n }\n /**\n * Return a `TextRange` from the `start`th to `end`th characters in `root`.\n *\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n\n }, {\n key: "fromOffsets",\n value: function fromOffsets(root, start, end) {\n return new TextRange(new text_range_TextPosition(root, start), new text_range_TextPosition(root, end));\n }\n }]);\n\n return TextRange;\n}();\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/types.js\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction types_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction types_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction types_createClass(Constructor, protoProps, staticProps) { if (protoProps) types_defineProperties(Constructor.prototype, protoProps); if (staticProps) types_defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This module exports a set of classes for converting between DOM `Range`\n * objects and different types of selectors. It is mostly a thin wrapper around a\n * set of anchoring libraries. It serves two main purposes:\n *\n * 1. Providing a consistent interface across different types of anchors.\n * 2. Insulating the rest of the code from API changes in the underlying anchoring\n * libraries.\n */\n\n\n\n/**\n * @typedef {import(\'../../types/api\').RangeSelector} RangeSelector\n * @typedef {import(\'../../types/api\').TextPositionSelector} TextPositionSelector\n * @typedef {import(\'../../types/api\').TextQuoteSelector} TextQuoteSelector\n */\n\n/**\n * Converts between `RangeSelector` selectors and `Range` objects.\n */\n\nvar RangeAnchor = /*#__PURE__*/(/* unused pure expression or super */ null && (function () {\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n function RangeAnchor(root, range) {\n types_classCallCheck(this, RangeAnchor);\n\n this.root = root;\n this.range = range;\n }\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n\n\n types_createClass(RangeAnchor, [{\n key: "toRange",\n value: function toRange() {\n return this.range;\n }\n /**\n * @return {RangeSelector}\n */\n\n }, {\n key: "toSelector",\n value: function toSelector() {\n // "Shrink" the range so that it tightly wraps its text. This ensures more\n // predictable output for a given text selection.\n var normalizedRange = TextRange.fromRange(this.range).toRange();\n var textRange = TextRange.fromRange(normalizedRange);\n var startContainer = xpathFromNode(textRange.start.element, this.root);\n var endContainer = xpathFromNode(textRange.end.element, this.root);\n return {\n type: \'RangeSelector\',\n startContainer: startContainer,\n startOffset: textRange.start.offset,\n endContainer: endContainer,\n endOffset: textRange.end.offset\n };\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n return new RangeAnchor(root, range);\n }\n /**\n * Create an anchor from a serialized `RangeSelector` selector.\n *\n * @param {Element} root - A root element from which to anchor.\n * @param {RangeSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var startContainer = nodeFromXPath(selector.startContainer, root);\n\n if (!startContainer) {\n throw new Error(\'Failed to resolve startContainer XPath\');\n }\n\n var endContainer = nodeFromXPath(selector.endContainer, root);\n\n if (!endContainer) {\n throw new Error(\'Failed to resolve endContainer XPath\');\n }\n\n var startPos = TextPosition.fromCharOffset(startContainer, selector.startOffset);\n var endPos = TextPosition.fromCharOffset(endContainer, selector.endOffset);\n var range = new TextRange(startPos, endPos).toRange();\n return new RangeAnchor(root, range);\n }\n }]);\n\n return RangeAnchor;\n}()));\n/**\n * Converts between `TextPositionSelector` selectors and `Range` objects.\n */\n\nvar TextPositionAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n function TextPositionAnchor(root, start, end) {\n types_classCallCheck(this, TextPositionAnchor);\n\n this.root = root;\n this.start = start;\n this.end = end;\n }\n /**\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextPositionAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextPositionSelector}\n */\n function toSelector() {\n return {\n type: \'TextPositionSelector\',\n start: this.start,\n end: this.end\n };\n }\n }, {\n key: "toRange",\n value: function toRange() {\n return text_range_TextRange.fromOffsets(this.root, this.start, this.end).toRange();\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n return new TextPositionAnchor(root, textRange.start.offset, textRange.end.offset);\n }\n /**\n * @param {Element} root\n * @param {TextPositionSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n return new TextPositionAnchor(root, selector.start, selector.end);\n }\n }]);\n\n return TextPositionAnchor;\n}();\n/**\n * @typedef QuoteMatchOptions\n * @prop {number} [hint] - Expected position of match in text. See `matchQuote`.\n */\n\n/**\n * Converts between `TextQuoteSelector` selectors and `Range` objects.\n */\n\nvar TextQuoteAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root - A root element from which to anchor.\n * @param {string} exact\n * @param {Object} context\n * @param {string} [context.prefix]\n * @param {string} [context.suffix]\n */\n function TextQuoteAnchor(root, exact) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n types_classCallCheck(this, TextQuoteAnchor);\n\n this.root = root;\n this.exact = exact;\n this.context = context;\n }\n /**\n * Create a `TextQuoteAnchor` from a range.\n *\n * Will throw if `range` does not contain any text nodes.\n *\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextQuoteAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextQuoteSelector}\n */\n function toSelector() {\n return {\n type: \'TextQuoteSelector\',\n exact: this.exact,\n prefix: this.context.prefix,\n suffix: this.context.suffix\n };\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return this.toPositionAnchor(options).toRange();\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toPositionAnchor",\n value: function toPositionAnchor() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var text =\n /** @type {string} */\n this.root.textContent;\n var match = matchQuote(text, this.exact, _objectSpread(_objectSpread({}, this.context), {}, {\n hint: options.hint\n }));\n\n if (!match) {\n throw new Error(\'Quote not found\');\n }\n\n return new TextPositionAnchor(this.root, match.start, match.end);\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var text =\n /** @type {string} */\n root.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n var start = textRange.start.offset;\n var end = textRange.end.offset; // Number of characters around the quote to capture as context. We currently\n // always use a fixed amount, but it would be better if this code was aware\n // of logical boundaries in the document (paragraph, article etc.) to avoid\n // capturing text unrelated to the quote.\n //\n // In regular prose the ideal content would often be the surrounding sentence.\n // This is a natural unit of meaning which enables displaying quotes in\n // context even when the document is not available. We could use `Intl.Segmenter`\n // for this when available.\n\n var contextLen = 32;\n return new TextQuoteAnchor(root, text.slice(start, end), {\n prefix: text.slice(Math.max(0, start - contextLen), start),\n suffix: text.slice(end, Math.min(text.length, end + contextLen))\n });\n }\n /**\n * @param {Element} root\n * @param {TextQuoteSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var prefix = selector.prefix,\n suffix = selector.suffix;\n return new TextQuoteAnchor(root, selector.exact, {\n prefix: prefix,\n suffix: suffix\n });\n }\n }]);\n\n return TextQuoteAnchor;\n}();\n;// CONCATENATED MODULE: ./src/utils.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = utils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction utils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return utils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return utils_arrayLikeToArray(o, minLen); }\n\nfunction utils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n // Catch JS errors to log them in the app.\n\nwindow.addEventListener("error", function (event) {\n Android.logError(event.message, event.filename, event.lineno);\n}, false);\nwindow.addEventListener("load", function () {\n var observer = new ResizeObserver(function () {\n onViewportWidthChanged();\n snapCurrentOffset();\n });\n observer.observe(document.body);\n}, false);\n/**\n * Having an odd number of columns when displaying two columns per screen causes snapping and page\n * turning issues. To fix this, we insert a blank virtual column at the end of the resource.\n */\n\nfunction appendVirtualColumnIfNeeded() {\n var id = "readium-virtual-page";\n var virtualCol = document.getElementById(id);\n\n if (isScrollModeEnabled() || getColumnCountPerScreen() != 2) {\n if (virtualCol) {\n virtualCol.remove();\n }\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var colCount = documentWidth / pageWidth;\n var hasOddColCount = Math.round(colCount * 2) / 2 % 1 > 0.1;\n\n if (hasOddColCount) {\n if (virtualCol) {\n virtualCol.remove();\n } else {\n virtualCol = document.createElement("div");\n virtualCol.setAttribute("id", id);\n virtualCol.style.breakBefore = "column";\n virtualCol.innerHTML = "​"; // zero-width space\n\n document.body.appendChild(virtualCol);\n }\n }\n }\n}\n\nvar pageWidth = 1;\n\nfunction onViewportWidthChanged() {\n // We can\'t rely on window.innerWidth for the pageWidth on Android, because if the\n // device pixel ratio is not an integer, we get rounding issues offsetting the pages.\n //\n // See https://github.com/readium/readium-css/issues/97\n // and https://github.com/readium/r2-navigator-kotlin/issues/146\n var width = Android.getViewportWidth();\n pageWidth = width / window.devicePixelRatio;\n setProperty("--RS__viewportWidth", "calc(" + width + "px / " + window.devicePixelRatio + ")");\n appendVirtualColumnIfNeeded();\n}\n\nfunction getColumnCountPerScreen() {\n return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n}\nfunction isScrollModeEnabled() {\n var style = document.documentElement.style;\n return style.getPropertyValue("--USER__view").trim() == "readium-scroll-on" || // FIXME: Will need to be removed in Readium 3.0, --USER__scroll was incorrect.\n style.getPropertyValue("--USER__scroll").trim() == "readium-scroll-on";\n}\nfunction isRTL() {\n return document.body.dir.toLowerCase() == "rtl";\n} // Scroll to the given TagId in document and snap.\n\nfunction scrollToId(id) {\n var element = document.getElementById(id);\n\n if (!element) {\n return false;\n }\n\n return scrollToRect(element.getBoundingClientRect());\n} // Position must be in the range [0 - 1], 0-100%.\n\nfunction scrollToPosition(position) {\n // Android.log("scrollToPosition " + position);\n if (position < 0 || position > 1) {\n throw "scrollToPosition() must be given a position from 0.0 to 1.0";\n }\n\n var offset;\n\n if (isScrollModeEnabled()) {\n offset = document.scrollingElement.scrollHeight * position;\n document.scrollingElement.scrollTop = offset; // window.scrollTo(0, offset);\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var factor = isRTL() ? -1 : 1;\n offset = documentWidth * position * factor;\n document.scrollingElement.scrollLeft = snapOffset(offset);\n }\n} // Scrolls to the first occurrence of the given text snippet.\n//\n// The expected text argument is a Locator Text object, as defined here:\n// https://readium.org/architecture/models/locators/\n\nfunction scrollToText(text) {\n var range = rangeFromLocator({\n text: text\n });\n\n if (!range) {\n return false;\n }\n\n scrollToRange(range);\n return true;\n}\n\nfunction scrollToRange(range) {\n return scrollToRect(range.getBoundingClientRect());\n}\n\nfunction scrollToRect(rect) {\n if (isScrollModeEnabled()) {\n document.scrollingElement.scrollTop = rect.top + window.scrollY - window.innerHeight / 2;\n } else {\n document.scrollingElement.scrollLeft = snapOffset(rect.left + window.scrollX);\n }\n\n return true;\n}\n\nfunction scrollToStart() {\n // Android.log("scrollToStart");\n if (!isScrollModeEnabled()) {\n document.scrollingElement.scrollLeft = 0;\n } else {\n document.scrollingElement.scrollTop = 0;\n window.scrollTo(0, 0);\n }\n}\nfunction scrollToEnd() {\n // Android.log("scrollToEnd");\n if (!isScrollModeEnabled()) {\n var factor = isRTL() ? -1 : 1;\n document.scrollingElement.scrollLeft = snapOffset(document.scrollingElement.scrollWidth * factor);\n } else {\n document.scrollingElement.scrollTop = document.body.scrollHeight;\n window.scrollTo(0, document.body.scrollHeight);\n }\n} // Returns false if the page is already at the left-most scroll offset.\n\nfunction scrollLeft() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX - pageWidth;\n var minOffset = isRTL() ? -(documentWidth - pageWidth) : 0;\n return scrollToOffset(Math.max(offset, minOffset));\n} // Returns false if the page is already at the right-most scroll offset.\n\nfunction scrollRight() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX + pageWidth;\n var maxOffset = isRTL() ? 0 : documentWidth - pageWidth;\n return scrollToOffset(Math.min(offset, maxOffset));\n} // Scrolls to the given left offset.\n// Returns false if the page scroll position is already close enough to the given offset.\n\nfunction scrollToOffset(offset) {\n // Android.log("scrollToOffset " + offset);\n if (isScrollModeEnabled()) {\n throw "Called scrollToOffset() with scroll mode enabled. This can only be used in paginated mode.";\n }\n\n var currentOffset = window.scrollX;\n document.scrollingElement.scrollLeft = snapOffset(offset); // In some case the scrollX cannot reach the position respecting to innerWidth\n\n var diff = Math.abs(currentOffset - offset) / pageWidth;\n return diff > 0.01;\n} // Snap the offset to the screen width (page width).\n\n\nfunction snapOffset(offset) {\n var value = offset + (isRTL() ? -1 : 1);\n return value - value % pageWidth;\n} // Snaps the current offset to the page width.\n\n\nfunction snapCurrentOffset() {\n // Android.log("snapCurrentOffset");\n if (isScrollModeEnabled()) {\n return;\n }\n\n var currentOffset = window.scrollX; // Adds half a page to make sure we don\'t snap to the previous page.\n\n var factor = isRTL() ? -1 : 1;\n var delta = factor * (pageWidth / 2);\n document.scrollingElement.scrollLeft = snapOffset(currentOffset + delta);\n}\nfunction rangeFromLocator(locator) {\n try {\n var locations = locator.locations;\n var text = locator.text;\n\n if (text && text.highlight) {\n var root;\n\n if (locations && locations.cssSelector) {\n root = document.querySelector(locations.cssSelector);\n }\n\n if (!root) {\n root = document.body;\n }\n\n var anchor = new TextQuoteAnchor(root, text.highlight, {\n prefix: text.before,\n suffix: text.after\n });\n return anchor.toRange();\n }\n\n if (locations) {\n var element = null;\n\n if (!element && locations.cssSelector) {\n element = document.querySelector(locations.cssSelector);\n }\n\n if (!element && locations.fragments) {\n var _iterator = _createForOfIteratorHelper(locations.fragments),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var htmlId = _step.value;\n element = document.getElementById(htmlId);\n\n if (element) {\n break;\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n if (element) {\n var range = document.createRange();\n range.setStartBefore(element);\n range.setEndAfter(element);\n return range;\n }\n }\n } catch (e) {\n logError(e);\n }\n\n return null;\n} /// User Settings.\n\nfunction setCSSProperties(properties) {\n for (var name in properties) {\n setProperty(name, properties[name]);\n }\n} // For setting user setting.\n\nfunction setProperty(key, value) {\n if (value === null || value === "") {\n removeProperty(key);\n } else {\n var root = document.documentElement; // The `!important` annotation is added with `setProperty()` because if it\'s part of the\n // `value`, it will be ignored by the Web View.\n\n root.style.setProperty(key, value, "important");\n }\n} // For removing user setting.\n\nfunction removeProperty(key) {\n var root = document.documentElement;\n root.style.removeProperty(key);\n} /// Toolkit\n\nfunction log() {\n var message = Array.prototype.slice.call(arguments).join(" ");\n Android.log(message);\n}\nfunction logError(message) {\n Android.logError(message, "", 0);\n}\n;// CONCATENATED MODULE: ./src/rect.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction rect_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = rect_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction rect_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return rect_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return rect_arrayLikeToArray(o, minLen); }\n\nfunction rect_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nvar debug = false;\n/**\n * Converts a DOMRect into a JSON object understandable by the native side.\n */\n\nfunction toNativeRect(rect) {\n var pixelRatio = window.devicePixelRatio;\n var width = rect.width * pixelRatio;\n var height = rect.height * pixelRatio;\n var left = rect.left * pixelRatio;\n var top = rect.top * pixelRatio;\n var right = left + width;\n var bottom = top + height;\n return {\n width: width,\n height: height,\n left: left,\n top: top,\n right: right,\n bottom: bottom\n };\n}\nfunction getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var clientRects = range.getClientRects();\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator = rect_createForOfIteratorHelper(clientRects),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var rangeClientRect = _step.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n var mergedRects = mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = removeContainedRects(mergedRects, tolerance);\n var newRects = replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n rect_log("CLIENT RECT: remove small");\n newRects.splice(j, 1);\n } else {\n rect_log("CLIENT RECT: remove small, but keep otherwise empty!");\n break;\n }\n }\n }\n\n rect_log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n return newRects;\n}\n\nfunction mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("mergeTouchingRects rect1 === rect2 ??!");\n return "continue";\n }\n\n var rectsLineUpVertically = almostEqual(rect1.top, rect2.top, tolerance) && almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = almostEqual(rect1.left, rect2.left, tolerance) && almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n rect_log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret = _loop(j);\n\n if (_ret === "continue") continue;\n if (_typeof(_ret) === "object") return _ret.v;\n }\n }\n\n return rects;\n}\n\nfunction getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator2 = rect_createForOfIteratorHelper(rects),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var rect = _step2.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n rect_log("CLIENT RECT: remove tiny");\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator3 = rect_createForOfIteratorHelper(rects),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var possiblyContainingRect = _step3.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (rectContains(possiblyContainingRect, rect, tolerance)) {\n rect_log("CLIENT RECT: remove contained");\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction rectContains(rect1, rect2, tolerance) {\n return rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || almostEqual(rect.left, x, tolerance)) && (rect.right > x || almostEqual(rect.right, x, tolerance)) && (rect.top < y || almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("replaceOverlapingRects rect1 === rect2 ??!");\n continue;\n }\n\n if (rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret2 = function () {\n var toAdd = [];\n var toRemove = void 0;\n var subtractRects1 = rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n var subtractRects2 = rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n }\n }\n\n rect_log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: replaceOverlapingRects(newRects)\n };\n }();\n\n if (_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction rectSubtract(rect1, rect2) {\n var rectIntersected = rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n return {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n}\n\nfunction rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction rect_log() {\n if (debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/decorator.js\nfunction decorator_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = decorator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction decorator_slicedToArray(arr, i) { return decorator_arrayWithHoles(arr) || decorator_iterableToArrayLimit(arr, i) || decorator_unsupportedIterableToArray(arr, i) || decorator_nonIterableRest(); }\n\nfunction decorator_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction decorator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return decorator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return decorator_arrayLikeToArray(o, minLen); }\n\nfunction decorator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction decorator_iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction decorator_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nvar styles = new Map();\nvar groups = new Map();\nvar lastGroupId = 0;\n/**\n * Registers a list of additional supported Decoration Templates.\n *\n * Each template object is indexed by the style ID.\n */\n\nfunction registerTemplates(newStyles) {\n var stylesheet = "";\n\n for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = decorator_slicedToArray(_Object$entries[_i], 2),\n id = _Object$entries$_i[0],\n style = _Object$entries$_i[1];\n\n styles.set(id, style);\n\n if (style.stylesheet) {\n stylesheet += style.stylesheet + "\\n";\n }\n }\n\n if (stylesheet) {\n var styleElement = document.createElement("style");\n styleElement.innerHTML = stylesheet;\n document.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n}\n/**\n * Returns an instance of DecorationGroup for the given group name.\n */\n\nfunction getDecorations(groupName) {\n var group = groups.get(groupName);\n\n if (!group) {\n var id = "r2-decoration-" + lastGroupId++;\n group = DecorationGroup(id, groupName);\n groups.set(groupName, group);\n }\n\n return group;\n}\n/**\n * Handles click events on a Decoration.\n * Returns whether a decoration matched this event.\n */\n\nfunction handleDecorationClickEvent(event, clickEvent) {\n if (groups.size === 0) {\n return false;\n }\n\n function findTarget() {\n var _iterator = decorator_createForOfIteratorHelper(groups),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = decorator_slicedToArray(_step.value, 2),\n group = _step$value[0],\n groupContent = _step$value[1];\n\n var _iterator2 = decorator_createForOfIteratorHelper(groupContent.items.reverse()),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var item = _step2.value;\n\n if (!item.clickableElements) {\n continue;\n }\n\n var _iterator3 = decorator_createForOfIteratorHelper(item.clickableElements),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var element = _step3.value;\n var rect = element.getBoundingClientRect().toJSON();\n\n if (rectContainsPoint(rect, event.clientX, event.clientY, 1)) {\n return {\n group: group,\n item: item,\n element: element,\n rect: rect\n };\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var target = findTarget();\n\n if (!target) {\n return false;\n }\n\n return Android.onDecorationActivated(JSON.stringify({\n id: target.item.decoration.id,\n group: target.group,\n rect: toNativeRect(target.item.range.getBoundingClientRect()),\n click: clickEvent\n }));\n}\n/**\n * Creates a DecorationGroup object from a unique HTML ID and its name.\n */\n\nfunction DecorationGroup(groupId, groupName) {\n var items = [];\n var lastItemId = 0;\n var container = null;\n /**\n * Adds a new decoration to the group.\n */\n\n function add(decoration) {\n var id = groupId + "-" + lastItemId++;\n var range = rangeFromLocator(decoration.locator);\n\n if (!range) {\n log("Can\'t locate DOM range for decoration", decoration);\n return;\n }\n\n var item = {\n id: id,\n decoration: decoration,\n range: range\n };\n items.push(item);\n layout(item);\n }\n /**\n * Removes the decoration with given ID from the group.\n */\n\n\n function remove(decorationId) {\n var index = items.findIndex(function (i) {\n return i.decoration.id === decorationId;\n });\n\n if (index === -1) {\n return;\n }\n\n var item = items[index];\n items.splice(index, 1);\n item.clickableElements = null;\n\n if (item.container) {\n item.container.remove();\n item.container = null;\n }\n }\n /**\n * Notifies that the given decoration was modified and needs to be updated.\n */\n\n\n function update(decoration) {\n remove(decoration.id);\n add(decoration);\n }\n /**\n * Removes all decorations from this group.\n */\n\n\n function clear() {\n clearContainer();\n items.length = 0;\n }\n /**\n * Recreates the decoration elements.\n *\n * To be called after reflowing the resource, for example.\n */\n\n\n function requestLayout() {\n clearContainer();\n items.forEach(function (item) {\n return layout(item);\n });\n }\n /**\n * Layouts a single Decoration item.\n */\n\n\n function layout(item) {\n var groupContainer = requireContainer();\n var style = styles.get(item.decoration.style);\n\n if (!style) {\n logError("Unknown decoration style: ".concat(item.decoration.style));\n return;\n }\n\n var itemContainer = document.createElement("div");\n itemContainer.setAttribute("id", item.id);\n itemContainer.setAttribute("data-style", item.decoration.style);\n itemContainer.style.setProperty("pointer-events", "none");\n var viewportWidth = window.innerWidth;\n var columnCount = parseInt(getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n var pageWidth = viewportWidth / (columnCount || 1);\n var scrollingElement = document.scrollingElement;\n var xOffset = scrollingElement.scrollLeft;\n var yOffset = scrollingElement.scrollTop;\n\n function positionElement(element, rect, boundingRect) {\n element.style.position = "absolute";\n\n if (style.width === "wrap") {\n element.style.width = "".concat(rect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(rect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "viewport") {\n element.style.width = "".concat(viewportWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n var left = Math.floor(rect.left / viewportWidth) * viewportWidth;\n element.style.left = "".concat(left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "bounds") {\n element.style.width = "".concat(boundingRect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(boundingRect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "page") {\n element.style.width = "".concat(pageWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n\n var _left = Math.floor(rect.left / pageWidth) * pageWidth;\n\n element.style.left = "".concat(_left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n }\n }\n\n var boundingRect = item.range.getBoundingClientRect();\n var elementTemplate;\n\n try {\n var template = document.createElement("template");\n template.innerHTML = item.decoration.element.trim();\n elementTemplate = template.content.firstElementChild;\n } catch (error) {\n logError("Invalid decoration element \\"".concat(item.decoration.element, "\\": ").concat(error.message));\n return;\n }\n\n if (style.layout === "boxes") {\n var doNotMergeHorizontallyAlignedRects = true;\n var clientRects = getClientRectsNoOverlap(item.range, doNotMergeHorizontallyAlignedRects);\n clientRects = clientRects.sort(function (r1, r2) {\n if (r1.top < r2.top) {\n return -1;\n } else if (r1.top > r2.top) {\n return 1;\n } else {\n return 0;\n }\n });\n\n var _iterator4 = decorator_createForOfIteratorHelper(clientRects),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var clientRect = _step4.value;\n var line = elementTemplate.cloneNode(true);\n line.style.setProperty("pointer-events", "none");\n positionElement(line, clientRect, boundingRect);\n itemContainer.append(line);\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n } else if (style.layout === "bounds") {\n var bounds = elementTemplate.cloneNode(true);\n bounds.style.setProperty("pointer-events", "none");\n positionElement(bounds, boundingRect, boundingRect);\n itemContainer.append(bounds);\n }\n\n groupContainer.append(itemContainer);\n item.container = itemContainer;\n item.clickableElements = Array.from(itemContainer.querySelectorAll("[data-activable=\'1\']"));\n\n if (item.clickableElements.length === 0) {\n item.clickableElements = Array.from(itemContainer.children);\n }\n }\n /**\n * Returns the group container element, after making sure it exists.\n */\n\n\n function requireContainer() {\n if (!container) {\n container = document.createElement("div");\n container.setAttribute("id", groupId);\n container.setAttribute("data-group", groupName);\n container.style.setProperty("pointer-events", "none");\n document.body.append(container);\n }\n\n return container;\n }\n /**\n * Removes the group container.\n */\n\n\n function clearContainer() {\n if (container) {\n container.remove();\n container = null;\n }\n }\n\n return {\n add: add,\n remove: remove,\n update: update,\n clear: clear,\n items: items,\n requestLayout: requestLayout\n };\n}\nwindow.addEventListener("load", function () {\n // Will relayout all the decorations when the document body is resized.\n var body = document.body;\n var lastSize = {\n width: 0,\n height: 0\n };\n var observer = new ResizeObserver(function () {\n if (lastSize.width === body.clientWidth && lastSize.height === body.clientHeight) {\n return;\n }\n\n lastSize = {\n width: body.clientWidth,\n height: body.clientHeight\n };\n groups.forEach(function (group) {\n group.requestLayout();\n });\n });\n observer.observe(body);\n}, false);\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n} // See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling\n\n\nfunction nearestInteractiveElement(element) {\n var interactiveTags = ["a", "audio", "button", "canvas", "details", "input", "label", "option", "select", "submit", "textarea", "video"];\n\n if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) {\n return element.outerHTML;\n } // Checks whether the element is editable by the user.\n\n\n if (element.hasAttribute("contenteditable") && element.getAttribute("contenteditable").toLowerCase() != "false") {\n return element.outerHTML;\n } // Checks parents recursively because the touch might be for example on an inside a .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\n;// CONCATENATED MODULE: ./src/highlight.js\nfunction highlight_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { highlight_typeof = function _typeof(obj) { return typeof obj; }; } else { highlight_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return highlight_typeof(obj); }\n\nfunction highlight_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = highlight_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction highlight_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return highlight_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return highlight_arrayLikeToArray(o, minLen); }\n\nfunction highlight_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/* eslint-disable */\n//\n// highlight.js\n// r2-navigator-kotlin\n//\n// Organized by Taehyun Kim on 6/27/19 from r2-navigator-js.\n//\n// Copyright 2019 Readium Foundation. All rights reserved.\n// Use of this source code is governed by a BSD-style license which is detailed\n// in the LICENSE file present in the project repository where this source code is maintained.\n//\nvar ROOT_CLASS_REDUCE_MOTION = "r2-reduce-motion";\nvar ROOT_CLASS_NO_FOOTNOTES = "r2-no-popup-foonotes";\nvar POPUP_DIALOG_CLASS = "r2-popup-dialog";\nvar FOOTNOTES_CONTAINER_CLASS = "r2-footnote-container";\nvar FOOTNOTES_CLOSE_BUTTON_CLASS = "r2-footnote-close";\nvar FOOTNOTE_FORCE_SHOW = "r2-footnote-force-show";\nvar TTS_ID_PREVIOUS = "r2-tts-previous";\nvar TTS_ID_NEXT = "r2-tts-next";\nvar TTS_ID_SLIDER = "r2-tts-slider";\nvar TTS_ID_ACTIVE_WORD = "r2-tts-active-word";\nvar TTS_ID_CONTAINER = "r2-tts-txt";\nvar TTS_ID_INFO = "r2-tts-info";\nvar TTS_NAV_BUTTON_CLASS = "r2-tts-button";\nvar TTS_ID_SPEAKING_DOC_ELEMENT = "r2-tts-speaking-el";\nvar TTS_CLASS_INJECTED_SPAN = "r2-tts-speaking-txt";\nvar TTS_CLASS_INJECTED_SUBSPAN = "r2-tts-speaking-word";\nvar TTS_ID_INJECTED_PARENT = "r2-tts-speaking-txt-parent";\nvar ID_HIGHLIGHTS_CONTAINER = "R2_ID_HIGHLIGHTS_CONTAINER";\nvar ID_ANNOTATION_CONTAINER = "R2_ID_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_CONTAINER = "R2_CLASS_HIGHLIGHT_CONTAINER";\nvar CLASS_ANNOTATION_CONTAINER = "R2_CLASS_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_AREA = "R2_CLASS_HIGHLIGHT_AREA";\nvar CLASS_ANNOTATION_AREA = "R2_CLASS_ANNOTATION_AREA";\nvar CLASS_HIGHLIGHT_BOUNDING_AREA = "R2_CLASS_HIGHLIGHT_BOUNDING_AREA";\nvar CLASS_ANNOTATION_BOUNDING_AREA = "R2_CLASS_ANNOTATION_BOUNDING_AREA"; // tslint:disable-next-line:max-line-length\n\nvar _blacklistIdClassForCFI = [POPUP_DIALOG_CLASS, TTS_CLASS_INJECTED_SPAN, TTS_CLASS_INJECTED_SUBSPAN, ID_HIGHLIGHTS_CONTAINER, CLASS_HIGHLIGHT_CONTAINER, CLASS_HIGHLIGHT_AREA, CLASS_HIGHLIGHT_BOUNDING_AREA, "resize-sensor"];\nvar CLASS_PAGINATED = "r2-css-paginated"; //const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");\n\nvar IS_DEV = false;\nvar _highlights = [];\n\nvar _highlightsContainer;\n\nvar _annotationContainer;\n\nvar lastMouseDownX = -1;\nvar lastMouseDownY = -1;\nvar bodyEventListenersSet = false;\nvar USE_SVG = false;\nvar DEFAULT_BACKGROUND_COLOR_OPACITY = 0.3;\nvar ALT_BACKGROUND_COLOR_OPACITY = 0.45; //const DEBUG_VISUALS = false;\n\nvar DEBUG_VISUALS = false;\nvar DEFAULT_BACKGROUND_COLOR = {\n blue: 100,\n green: 50,\n red: 230\n};\nvar ANNOTATION_WIDTH = 15;\n\nfunction resetHighlightBoundingStyle(_win, highlightBounding) {\n if (highlightBounding.getAttribute("class") == CLASS_ANNOTATION_BOUNDING_AREA) {\n return;\n }\n\n highlightBounding.style.outline = "none";\n highlightBounding.style.setProperty("background-color", "transparent", "important");\n}\n\nfunction setHighlightAreaStyle(win, highlightAreas, highlight) {\n var useSVG = !DEBUG_VISUALS && USE_SVG;\n\n var _iterator = highlight_createForOfIteratorHelper(highlightAreas),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var highlightArea = _step.value;\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var opacity = ALT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n}\n\nfunction resetHighlightAreaStyle(win, highlightArea) {\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var id = isSVG ? highlightArea.parentNode && highlightArea.parentNode.parentNode && highlightArea.parentNode.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.parentNode.getAttribute ? highlightArea.parentNode.parentNode.getAttribute("id") : undefined : highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.getAttribute ? highlightArea.parentNode.getAttribute("id") : undefined;\n\n if (id) {\n var highlight = _highlights.find(function (h) {\n return h.id === id;\n });\n\n if (highlight) {\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n }\n}\n\nfunction processTouchEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.changedTouches[0].clientX;\n var y = ev.changedTouches[0].clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect; // _highlights.sort(function(a, b) {\n // console.log(JSON.stringify(a.selectionInfo))\n // return a.selectionInfo.cleanText.length < b.selectionInfo.cleanText.length\n // })\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator2 = highlight_createForOfIteratorHelper(highlightFragments),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var highlightFragment = _step2.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator3 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var highlightBounding = _step3.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i = 0, _allHighlightAreas = allHighlightAreas; _i < _allHighlightAreas.length; _i++) {\n var highlightArea = _allHighlightAreas[_i];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas2 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator4 = highlight_createForOfIteratorHelper(_allHighlightAreas2),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var _highlightArea = _step4.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea) < 0) {\n resetHighlightAreaStyle(win, _highlightArea);\n }\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator5 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step5;\n\n try {\n for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {\n var _highlightBounding = _step5.value;\n\n if (!foundElementHighlightBounding || _highlightBounding !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding);\n }\n }\n } catch (err) {\n _iterator5.e(err);\n } finally {\n _iterator5.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "touchstart" || ev.type === "touchend") {\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight.id,\n size: size\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n console.log(foundHighlight.id.includes("R2_ANNOTATION_"));\n\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n}\n\nfunction processMouseEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.clientX;\n var y = ev.clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect;\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator6 = highlight_createForOfIteratorHelper(highlightFragments),\n _step6;\n\n try {\n for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {\n var highlightFragment = _step6.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator6.e(err);\n } finally {\n _iterator6.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator7 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step7;\n\n try {\n for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {\n var highlightBounding = _step7.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator7.e(err);\n } finally {\n _iterator7.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i2 = 0, _allHighlightAreas3 = allHighlightAreas; _i2 < _allHighlightAreas3.length; _i2++) {\n var highlightArea = _allHighlightAreas3[_i2];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas4 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator8 = highlight_createForOfIteratorHelper(_allHighlightAreas4),\n _step8;\n\n try {\n for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {\n var _highlightArea2 = _step8.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea2) < 0) {\n resetHighlightAreaStyle(win, _highlightArea2);\n }\n }\n } catch (err) {\n _iterator8.e(err);\n } finally {\n _iterator8.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator9 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step9;\n\n try {\n for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {\n var _highlightBounding2 = _step9.value;\n\n if (!foundElementHighlightBounding || _highlightBounding2 !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding2);\n }\n }\n } catch (err) {\n _iterator9.e(err);\n } finally {\n _iterator9.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "mouseup" || ev.type === "touchend") {\n var touchedPosition = {\n screenWidth: window.outerWidth,\n screenHeight: window.innerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight,\n position: touchedPosition\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n }\n }\n}\n\nfunction highlight_rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && highlight_almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && highlight_almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && highlight_almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && highlight_almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction highlight_replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("replaceOverlapingRects rect1 === rect2 ??!");\n }\n\n continue;\n }\n\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret = function () {\n var toAdd = [];\n var toRemove = void 0;\n var toPreserve = void 0;\n var subtractRects1 = highlight_rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n var subtractRects2 = highlight_rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n toPreserve = rect1;\n }\n }\n\n if (IS_DEV) {\n var toCheck = [];\n toCheck.push(toPreserve);\n Array.prototype.push.apply(toCheck, toAdd);\n checkOverlaps(toCheck);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: highlight_replaceOverlapingRects(newRects)\n };\n }();\n\n if (highlight_typeof(_ret) === "object") return _ret.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction checkOverlaps(rects) {\n var stillOverlapingRects = [];\n\n var _iterator10 = highlight_createForOfIteratorHelper(rects),\n _step10;\n\n try {\n for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {\n var rect1 = _step10.value;\n\n var _iterator11 = highlight_createForOfIteratorHelper(rects),\n _step11;\n\n try {\n for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {\n var rect2 = _step11.value;\n\n if (rect1 === rect2) {\n continue;\n }\n\n var has1 = stillOverlapingRects.indexOf(rect1) >= 0;\n var has2 = stillOverlapingRects.indexOf(rect2) >= 0;\n\n if (!has1 || !has2) {\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n if (!has1) {\n stillOverlapingRects.push(rect1);\n }\n\n if (!has2) {\n stillOverlapingRects.push(rect2);\n }\n\n console.log("CLIENT RECT: overlap ---");\n console.log("#1 TOP:".concat(rect1.top, " BOTTOM:").concat(rect1.bottom, " LEFT:").concat(rect1.left, " RIGHT:").concat(rect1.right, " WIDTH:").concat(rect1.width, " HEIGHT:").concat(rect1.height));\n console.log("#2 TOP:".concat(rect2.top, " BOTTOM:").concat(rect2.bottom, " LEFT:").concat(rect2.left, " RIGHT:").concat(rect2.right, " WIDTH:").concat(rect2.width, " HEIGHT:").concat(rect2.height));\n var xOverlap = getRectOverlapX(rect1, rect2);\n console.log("xOverlap: ".concat(xOverlap));\n var yOverlap = getRectOverlapY(rect1, rect2);\n console.log("yOverlap: ".concat(yOverlap));\n }\n }\n }\n } catch (err) {\n _iterator11.e(err);\n } finally {\n _iterator11.f();\n }\n }\n } catch (err) {\n _iterator10.e(err);\n } finally {\n _iterator10.f();\n }\n\n if (stillOverlapingRects.length) {\n console.log("CLIENT RECT: overlaps ".concat(stillOverlapingRects.length));\n }\n}\n\nfunction highlight_removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator12 = highlight_createForOfIteratorHelper(rects),\n _step12;\n\n try {\n for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {\n var rect = _step12.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove tiny");\n }\n\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator13 = highlight_createForOfIteratorHelper(rects),\n _step13;\n\n try {\n for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {\n var possiblyContainingRect = _step13.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (highlight_rectContains(possiblyContainingRect, rect, tolerance)) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove contained");\n }\n\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator13.e(err);\n } finally {\n _iterator13.f();\n }\n }\n } catch (err) {\n _iterator12.e(err);\n } finally {\n _iterator12.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction highlight_almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction highlight_rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n var rect = {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n return rect;\n}\n\nfunction highlight_rectSubtract(rect1, rect2) {\n var rectIntersected = highlight_rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction highlight_rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || highlight_almostEqual(rect.left, x, tolerance)) && (rect.right > x || highlight_almostEqual(rect.right, x, tolerance)) && (rect.top < y || highlight_almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || highlight_almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction highlight_rectContains(rect1, rect2, tolerance) {\n return highlight_rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction highlight_getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction highlight_mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("mergeTouchingRects rect1 === rect2 ??!");\n }\n\n return "continue";\n }\n\n var rectsLineUpVertically = highlight_almostEqual(rect1.top, rect2.top, tolerance) && highlight_almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = highlight_almostEqual(rect1.left, rect2.left, tolerance) && highlight_almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && highlight_rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n if (IS_DEV) {\n console.log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = highlight_getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: highlight_mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret2 = _loop(j);\n\n if (_ret2 === "continue") continue;\n if (highlight_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n\n return rects;\n}\n\nfunction highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var rangeClientRects = range.getClientRects();\n return getClientRectsNoOverlap_(rangeClientRects, doNotMergeHorizontallyAlignedRects);\n}\n\nfunction getClientRectsNoOverlap_(clientRects, doNotMergeHorizontallyAlignedRects) {\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator14 = highlight_createForOfIteratorHelper(clientRects),\n _step14;\n\n try {\n for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {\n var rangeClientRect = _step14.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator14.e(err);\n } finally {\n _iterator14.f();\n }\n\n var mergedRects = highlight_mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = highlight_removeContainedRects(mergedRects, tolerance);\n var newRects = highlight_replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small");\n }\n\n newRects.splice(j, 1);\n } else {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small, but keep otherwise empty!");\n }\n\n break;\n }\n }\n }\n\n if (IS_DEV) {\n checkOverlaps(newRects);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n }\n\n return newRects;\n}\n\nfunction isPaginated(document) {\n return document && document.documentElement && document.documentElement.classList.contains(CLASS_PAGINATED);\n}\n\nfunction getScrollingElement(document) {\n if (document.scrollingElement) {\n return document.scrollingElement;\n }\n\n return document.body;\n}\n\nfunction ensureContainer(win, annotationFlag) {\n var document = win.document;\n\n if (!_highlightsContainer) {\n if (!bodyEventListenersSet) {\n bodyEventListenersSet = true;\n document.body.addEventListener("mousedown", function (ev) {\n lastMouseDownX = ev.clientX;\n lastMouseDownY = ev.clientY;\n }, false);\n document.body.addEventListener("mouseup", function (ev) {\n if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {\n processMouseEvent(win, ev);\n }\n }, false);\n document.body.addEventListener("mousemove", function (ev) {\n processMouseEvent(win, ev);\n }, false);\n document.body.addEventListener("touchend", function touchEnd(e) {\n processTouchEvent(win, e);\n }, false);\n }\n\n _highlightsContainer = document.createElement("div");\n\n _highlightsContainer.setAttribute("id", ID_HIGHLIGHTS_CONTAINER);\n\n _highlightsContainer.style.setProperty("pointer-events", "none");\n\n document.body.append(_highlightsContainer);\n }\n\n return _highlightsContainer;\n}\n\nfunction hideAllhighlights() {\n if (_highlightsContainer) {\n _highlightsContainer.remove();\n\n _highlightsContainer = null;\n }\n}\n\nfunction destroyAllhighlights() {\n hideAllhighlights();\n\n _highlights.splice(0, _highlights.length);\n}\n\nfunction destroyHighlight(id) {\n var i = -1;\n var _document = window.document;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (highlight && i >= 0 && i < _highlights.length) {\n _highlights.splice(i, 1);\n }\n\n var highlightContainer = _document.getElementById(id);\n\n if (highlightContainer) {\n highlightContainer.remove();\n }\n}\n\nfunction isCfiTextNode(node) {\n return node.nodeType !== Node.ELEMENT_NODE;\n}\n\nfunction getChildTextNodeCfiIndex(element, child) {\n var found = -1;\n var textNodeIndex = -1;\n var previousWasElement = false;\n\n for (var i = 0; i < element.childNodes.length; i++) {\n var childNode = element.childNodes[i];\n var isText = isCfiTextNode(childNode);\n\n if (isText || previousWasElement) {\n textNodeIndex += 2;\n }\n\n if (isText) {\n if (childNode === child) {\n found = textNodeIndex;\n break;\n }\n }\n\n previousWasElement = childNode.nodeType === Node.ELEMENT_NODE;\n }\n\n return found;\n}\n\nfunction getCommonAncestorElement(node1, node2) {\n if (node1.nodeType === Node.ELEMENT_NODE && node1 === node2) {\n return node1;\n }\n\n if (node1.nodeType === Node.ELEMENT_NODE && node1.contains(node2)) {\n return node1;\n }\n\n if (node2.nodeType === Node.ELEMENT_NODE && node2.contains(node1)) {\n return node2;\n }\n\n var node1ElementAncestorChain = [];\n var parent = node1.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node1ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var node2ElementAncestorChain = [];\n parent = node2.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node2ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var commonAncestor = node1ElementAncestorChain.find(function (node1ElementAncestor) {\n return node2ElementAncestorChain.indexOf(node1ElementAncestor) >= 0;\n });\n\n if (!commonAncestor) {\n commonAncestor = node2ElementAncestorChain.find(function (node2ElementAncestor) {\n return node1ElementAncestorChain.indexOf(node2ElementAncestor) >= 0;\n });\n }\n\n return commonAncestor;\n}\n\nfunction fullQualifiedSelector(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n return lowerCaseName;\n } //return cssPath(node, justSelector);\n\n\n return cssPath(node, true);\n}\n\nfunction getCurrentSelectionInfo() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n console.log("^^^ SELECTION COLLAPSED.");\n return undefined;\n }\n\n var rawText = selection.toString();\n var cleanText = rawText.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanText.length === 0) {\n console.log("^^^ SELECTION TEXT EMPTY.");\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n console.log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var rangeInfo = convertRange(range, fullQualifiedSelector, computeCFI);\n\n if (!rangeInfo) {\n console.log("^^^ SELECTION RANGE INFO FAIL?!");\n return undefined;\n }\n\n if (IS_DEV && DEBUG_VISUALS) {\n var restoredRange = convertRangeInfo(win.document, rangeInfo);\n\n if (restoredRange) {\n if (restoredRange.startOffset === range.startOffset && restoredRange.endOffset === range.endOffset && restoredRange.startContainer === range.startContainer && restoredRange.endContainer === range.endContainer) {\n console.log("SELECTION RANGE RESTORED OKAY (dev check).");\n } else {\n console.log("SELECTION RANGE RESTORE FAIL (dev check).");\n dumpDebug("SELECTION", selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset, getCssSelector);\n dumpDebug("ORDERED RANGE FROM SELECTION", range.startContainer, range.startOffset, range.endContainer, range.endOffset, getCssSelector);\n dumpDebug("RESTORED RANGE", restoredRange.startContainer, restoredRange.startOffset, restoredRange.endContainer, restoredRange.endOffset, getCssSelector);\n }\n } else {\n console.log("CANNOT RESTORE SELECTION RANGE ??!");\n }\n } else {}\n\n return {\n locations: rangeInfo2Location(rangeInfo),\n text: {\n highlight: rawText\n }\n };\n}\n\nfunction checkBlacklisted(el) {\n var blacklistedId;\n var id = el.getAttribute("id");\n\n if (id && _blacklistIdClassForCFI.indexOf(id) >= 0) {\n console.log("checkBlacklisted ID: " + id);\n blacklistedId = id;\n }\n\n var blacklistedClass;\n\n var _iterator15 = highlight_createForOfIteratorHelper(_blacklistIdClassForCFI),\n _step15;\n\n try {\n for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {\n var item = _step15.value;\n\n if (el.classList.contains(item)) {\n console.log("checkBlacklisted CLASS: " + item);\n blacklistedClass = item;\n break;\n }\n }\n } catch (err) {\n _iterator15.e(err);\n } finally {\n _iterator15.f();\n }\n\n if (blacklistedId || blacklistedClass) {\n return true;\n }\n\n return false;\n}\n\nfunction cssPath(node, optimized) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return "";\n }\n\n var steps = [];\n var contextNode = node;\n\n while (contextNode) {\n var step = _cssPathStep(contextNode, !!optimized, contextNode === node);\n\n if (!step) {\n break; // Error - bail out early.\n }\n\n steps.push(step.value);\n\n if (step.optimized) {\n break;\n }\n\n contextNode = contextNode.parentNode;\n }\n\n steps.reverse();\n return steps.join(" > ");\n} // tslint:disable-next-line:max-line-length\n// https://chromium.googlesource.com/chromium/blink/+/master/Source/devtools/front_end/components/DOMPresentationUtils.js#316\n\n\nfunction _cssPathStep(node, optimized, isTargetNode) {\n function prefixedElementClassNames(nd) {\n var classAttribute = nd.getAttribute("class");\n\n if (!classAttribute) {\n return [];\n }\n\n return classAttribute.split(/\\s+/g).filter(Boolean).map(function (nm) {\n // The prefix is required to store "__proto__" in a object-based map.\n return "$" + nm;\n });\n }\n\n function idSelector(idd) {\n return "#" + escapeIdentifierIfNeeded(idd);\n }\n\n function escapeIdentifierIfNeeded(ident) {\n if (isCSSIdentifier(ident)) {\n return ident;\n }\n\n var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);\n var lastIndex = ident.length - 1;\n return ident.replace(/./g, function (c, ii) {\n return shouldEscapeFirst && ii === 0 || !isCSSIdentChar(c) ? escapeAsciiChar(c, ii === lastIndex) : c;\n });\n }\n\n function escapeAsciiChar(c, isLast) {\n return "\\\\" + toHexByte(c) + (isLast ? "" : " ");\n }\n\n function toHexByte(c) {\n var hexByte = c.charCodeAt(0).toString(16);\n\n if (hexByte.length === 1) {\n hexByte = "0" + hexByte;\n }\n\n return hexByte;\n }\n\n function isCSSIdentChar(c) {\n if (/[a-zA-Z0-9_-]/.test(c)) {\n return true;\n }\n\n return c.charCodeAt(0) >= 0xa0;\n }\n\n function isCSSIdentifier(value) {\n return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n var element = node;\n var id = element.getAttribute("id");\n\n if (optimized) {\n if (id) {\n return {\n optimized: true,\n value: idSelector(id)\n };\n }\n\n if (lowerCaseName === "body" || lowerCaseName === "head" || lowerCaseName === "html") {\n return {\n optimized: true,\n value: lowerCaseName // node.nodeNameInCorrectCase(),\n\n };\n }\n }\n\n var nodeName = lowerCaseName; // node.nodeNameInCorrectCase();\n\n if (id) {\n return {\n optimized: true,\n value: nodeName + idSelector(id)\n };\n }\n\n var parent = node.parentNode;\n\n if (!parent || parent.nodeType === Node.DOCUMENT_NODE) {\n return {\n optimized: true,\n value: nodeName\n };\n }\n\n var prefixedOwnClassNamesArray_ = prefixedElementClassNames(element);\n var prefixedOwnClassNamesArray = []; // .keySet()\n\n prefixedOwnClassNamesArray_.forEach(function (arrItem) {\n if (prefixedOwnClassNamesArray.indexOf(arrItem) < 0) {\n prefixedOwnClassNamesArray.push(arrItem);\n }\n });\n var needsClassNames = false;\n var needsNthChild = false;\n var ownIndex = -1;\n var elementIndex = -1;\n var siblings = parent.children;\n\n var _loop2 = function _loop2(i) {\n var sibling = siblings[i];\n\n if (sibling.nodeType !== Node.ELEMENT_NODE) {\n return "continue";\n }\n\n elementIndex += 1;\n\n if (sibling === node) {\n ownIndex = elementIndex;\n return "continue";\n }\n\n if (needsNthChild) {\n return "continue";\n } // sibling.nodeNameInCorrectCase()\n\n\n var siblingName = sibling.localName && sibling.localName.toLowerCase() || sibling.nodeName.toLowerCase();\n\n if (siblingName !== nodeName) {\n return "continue";\n }\n\n needsClassNames = true;\n var ownClassNames = [];\n prefixedOwnClassNamesArray.forEach(function (arrItem) {\n ownClassNames.push(arrItem);\n });\n var ownClassNameCount = ownClassNames.length;\n\n if (ownClassNameCount === 0) {\n needsNthChild = true;\n return "continue";\n }\n\n var siblingClassNamesArray_ = prefixedElementClassNames(sibling);\n var siblingClassNamesArray = []; // .keySet()\n\n siblingClassNamesArray_.forEach(function (arrItem) {\n if (siblingClassNamesArray.indexOf(arrItem) < 0) {\n siblingClassNamesArray.push(arrItem);\n }\n });\n\n for (var _i3 = 0, _siblingClassNamesArr = siblingClassNamesArray; _i3 < _siblingClassNamesArr.length; _i3++) {\n var siblingClass = _siblingClassNamesArr[_i3];\n var ind = ownClassNames.indexOf(siblingClass);\n\n if (ind < 0) {\n continue;\n }\n\n ownClassNames.splice(ind, 1); // delete ownClassNames[siblingClass];\n\n if (! --ownClassNameCount) {\n needsNthChild = true;\n break;\n }\n }\n };\n\n for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {\n var _ret3 = _loop2(i);\n\n if (_ret3 === "continue") continue;\n }\n\n var result = nodeName;\n\n if (isTargetNode && nodeName === "input" && element.getAttribute("type") && !element.getAttribute("id") && !element.getAttribute("class")) {\n result += \'[type="\' + element.getAttribute("type") + \'"]\';\n }\n\n if (needsNthChild) {\n result += ":nth-child(" + (ownIndex + 1) + ")";\n } else if (needsClassNames) {\n var _iterator16 = highlight_createForOfIteratorHelper(prefixedOwnClassNamesArray),\n _step16;\n\n try {\n for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {\n var prefixedName = _step16.value;\n result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));\n }\n } catch (err) {\n _iterator16.e(err);\n } finally {\n _iterator16.f();\n }\n }\n\n return {\n optimized: false,\n value: result\n };\n}\n\nfunction computeCFI(node) {\n // TODO: handle character position inside text node\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var cfi = "";\n var currentElement = node;\n\n while (currentElement.parentNode && currentElement.parentNode.nodeType === Node.ELEMENT_NODE) {\n var blacklisted = checkBlacklisted(currentElement);\n\n if (!blacklisted) {\n var currentElementParentChildren = currentElement.parentNode.children;\n var currentElementIndex = -1;\n\n for (var i = 0; i < currentElementParentChildren.length; i++) {\n if (currentElement === currentElementParentChildren[i]) {\n currentElementIndex = i;\n break;\n }\n }\n\n if (currentElementIndex >= 0) {\n var cfiIndex = (currentElementIndex + 1) * 2;\n cfi = cfiIndex + (currentElement.id ? "[" + currentElement.id + "]" : "") + (cfi.length ? "/" + cfi : "");\n }\n }\n\n currentElement = currentElement.parentNode;\n }\n\n return "/" + cfi;\n}\n\nfunction _createHighlight(locations, color, pointerInteraction, type) {\n var rangeInfo = location2RangeInfo(locations);\n var uniqueStr = "".concat(rangeInfo.cfi).concat(rangeInfo.startContainerElementCssSelector).concat(rangeInfo.startContainerChildTextNodeIndex).concat(rangeInfo.startOffset).concat(rangeInfo.endContainerElementCssSelector).concat(rangeInfo.endContainerChildTextNodeIndex).concat(rangeInfo.endOffset);\n\n var hash = __webpack_require__(3715);\n\n var sha256Hex = hash.sha256().update(uniqueStr).digest("hex");\n var id;\n\n if (type == ID_HIGHLIGHTS_CONTAINER) {\n id = "R2_HIGHLIGHT_" + sha256Hex;\n } else {\n id = "R2_ANNOTATION_" + sha256Hex;\n }\n\n destroyHighlight(id);\n var highlight = {\n color: color ? color : DEFAULT_BACKGROUND_COLOR,\n id: id,\n pointerInteraction: pointerInteraction,\n rangeInfo: rangeInfo\n };\n\n _highlights.push(highlight);\n\n createHighlightDom(window, highlight, type == ID_ANNOTATION_CONTAINER ? true : false);\n return highlight;\n}\n\nfunction createHighlight(selectionInfo, color, pointerInteraction) {\n return _createHighlight(selectionInfo, color, pointerInteraction, ID_HIGHLIGHTS_CONTAINER);\n}\nfunction createAnnotation(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (i == _highlights.length) return;\n var locations = {\n locations: rangeInfo2Location(highlight.rangeInfo)\n };\n return _createHighlight(locations, highlight.color, true, ID_ANNOTATION_CONTAINER);\n}\n\nfunction createHighlightDom(win, highlight, annotationFlag) {\n var document = win.document;\n var scale = 1 / (win.READIUM2 && win.READIUM2.isFixedLayout ? win.READIUM2.fxlViewportScale : 1);\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var paginated = isPaginated(document);\n var highlightsContainer = ensureContainer(win, annotationFlag);\n var highlightParent = document.createElement("div");\n highlightParent.setAttribute("id", highlight.id);\n highlightParent.setAttribute("class", CLASS_HIGHLIGHT_CONTAINER);\n document.body.style.position = "relative";\n highlightParent.style.setProperty("pointer-events", "none");\n\n if (highlight.pointerInteraction) {\n highlightParent.setAttribute("data-click", "1");\n }\n\n var bodyRect = document.body.getBoundingClientRect();\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var highlightAreaSVGDocFrag;\n var roundedCorner = 3;\n var underlineThickness = 2;\n var strikeThroughLineThickness = 3;\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n var extra = "";\n var rangeAnnotationBoundingClientRect = frameForHighlightAnnotationMarkWithID(win, highlight.id);\n var xOffset;\n var yOffset;\n var annotationOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n annotationOffset = parseInt((rangeAnnotationBoundingClientRect.right - xOffset) / window.innerWidth) + 1;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n annotationOffset = parseInt(rangeAnnotationBoundingClientRect.right / window.innerWidth + 1);\n }\n\n var _iterator17 = highlight_createForOfIteratorHelper(clientRects),\n _step17;\n\n try {\n for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {\n var clientRect = _step17.value;\n\n if (useSVG) {\n var borderThickness = 0;\n\n if (!highlightAreaSVGDocFrag) {\n highlightAreaSVGDocFrag = document.createDocumentFragment();\n }\n\n var highlightAreaSVGRect = document.createElementNS(SVG_XML_NAMESPACE, "rect");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGRect.setAttribute("style", "fill: rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; fill-opacity: ").concat(opacity, " !important; stroke-width: 0;"));\n highlightAreaSVGRect.scale = scale;\n /*\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGRect.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaSVGRect.setAttribute("rx", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("ry", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("x", "".concat((highlightAreaSVGRect.rect.left - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("y", "".concat((highlightAreaSVGRect.rect.top - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("height", "".concat((highlightAreaSVGRect.rect.height + borderThickness * 2) * scale));\n highlightAreaSVGRect.setAttribute("width", "".concat((highlightAreaSVGRect.rect.width + borderThickness * 2) * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGRect);\n\n if (drawUnderline) {\n var highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGLine.setAttribute("style", "stroke-linecap: round; stroke-width: ".concat(underlineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n var lineOffset = highlightAreaSVGLine.rect.width > roundedCorner ? roundedCorner : 0;\n highlightAreaSVGLine.setAttribute("x1", "".concat((highlightAreaSVGLine.rect.left + lineOffset) * scale));\n highlightAreaSVGLine.setAttribute("x2", "".concat((highlightAreaSVGLine.rect.left + highlightAreaSVGLine.rect.width - lineOffset) * scale));\n var y = (highlightAreaSVGLine.rect.top + highlightAreaSVGLine.rect.height - underlineThickness / 2) * scale;\n highlightAreaSVGLine.setAttribute("y1", "".concat(y));\n highlightAreaSVGLine.setAttribute("y2", "".concat(y));\n highlightAreaSVGLine.setAttribute("height", "".concat(highlightAreaSVGLine.rect.height * scale));\n highlightAreaSVGLine.setAttribute("width", "".concat(highlightAreaSVGLine.rect.width * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGLine);\n }\n\n if (drawStrikeThrough) {\n var _highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n _highlightAreaSVGLine.setAttribute("style", "stroke-linecap: butt; stroke-width: ".concat(strikeThroughLineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n\n _highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n _highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n _highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n _highlightAreaSVGLine.setAttribute("x1", "".concat(_highlightAreaSVGLine.rect.left * scale));\n\n _highlightAreaSVGLine.setAttribute("x2", "".concat((_highlightAreaSVGLine.rect.left + _highlightAreaSVGLine.rect.width) * scale));\n\n var _lineOffset = _highlightAreaSVGLine.rect.height / 2;\n\n var _y = (_highlightAreaSVGLine.rect.top + _lineOffset) * scale;\n\n _highlightAreaSVGLine.setAttribute("y1", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("y2", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("height", "".concat(_highlightAreaSVGLine.rect.height * scale));\n\n _highlightAreaSVGLine.setAttribute("width", "".concat(_highlightAreaSVGLine.rect.width * scale));\n\n highlightAreaSVGDocFrag.appendChild(_highlightAreaSVGLine);\n }\n } else {\n var highlightArea = document.createElement("div");\n highlightArea.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n if (DEBUG_VISUALS) {\n var rgb = Math.round(0xffffff * Math.random());\n var r = rgb >> 16;\n var g = rgb >> 8 & 255;\n var b = rgb & 255;\n extra = "outline-color: rgb(".concat(r, ", ").concat(g, ", ").concat(b, "); outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n } else {\n if (drawUnderline) {\n extra += "border-bottom: ".concat(underlineThickness * scale, "px solid rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important");\n }\n }\n\n highlightArea.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n highlightArea.style.setProperty("pointer-events", "none");\n highlightArea.style.position = paginated ? "fixed" : "absolute";\n highlightArea.scale = scale;\n /*\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightArea.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightArea.style.width = "".concat(highlightArea.rect.width * scale, "px");\n highlightArea.style.height = "".concat(highlightArea.rect.height * scale, "px");\n highlightArea.style.left = "".concat(highlightArea.rect.left * scale, "px");\n highlightArea.style.top = "".concat(highlightArea.rect.top * scale, "px");\n highlightParent.append(highlightArea);\n\n if (!DEBUG_VISUALS && drawStrikeThrough) {\n //if (drawStrikeThrough) {\n var highlightAreaLine = document.createElement("div");\n highlightAreaLine.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaLine.setAttribute("style", "background-color: rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important;"));\n highlightAreaLine.style.setProperty("pointer-events", "none");\n highlightAreaLine.style.position = paginated ? "fixed" : "absolute";\n highlightAreaLine.scale = scale;\n /*\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaLine.style.width = "".concat(highlightAreaLine.rect.width * scale, "px");\n highlightAreaLine.style.height = "".concat(strikeThroughLineThickness * scale, "px");\n highlightAreaLine.style.left = "".concat(highlightAreaLine.rect.left * scale, "px");\n highlightAreaLine.style.top = "".concat((highlightAreaLine.rect.top + highlightAreaLine.rect.height / 2 - strikeThroughLineThickness / 2) * scale, "px");\n highlightParent.append(highlightAreaLine);\n }\n }\n\n if (annotationFlag) {\n break;\n }\n }\n } catch (err) {\n _iterator17.e(err);\n } finally {\n _iterator17.f();\n }\n\n if (useSVG && highlightAreaSVGDocFrag) {\n var highlightAreaSVG = document.createElementNS(SVG_XML_NAMESPACE, "svg");\n highlightAreaSVG.setAttribute("pointer-events", "none");\n highlightAreaSVG.style.position = paginated ? "fixed" : "absolute";\n highlightAreaSVG.style.overflow = "visible";\n highlightAreaSVG.style.left = "0";\n highlightAreaSVG.style.top = "0";\n highlightAreaSVG.append(highlightAreaSVGDocFrag);\n highlightParent.append(highlightAreaSVG);\n }\n\n var highlightBounding = document.createElement("div");\n\n if (annotationFlag) {\n highlightBounding.setAttribute("class", CLASS_ANNOTATION_BOUNDING_AREA);\n highlightBounding.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n } else {\n highlightBounding.setAttribute("class", CLASS_HIGHLIGHT_BOUNDING_AREA);\n }\n\n highlightBounding.style.setProperty("pointer-events", "none");\n highlightBounding.style.position = paginated ? "fixed" : "absolute";\n highlightBounding.scale = scale;\n\n if (DEBUG_VISUALS) {\n highlightBounding.setAttribute("style", "outline-color: magenta; outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n }\n\n if (annotationFlag) {\n highlightBounding.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n var rangeBoundingClientRect = range.getBoundingClientRect();\n highlightBounding.rect = {\n height: rangeBoundingClientRect.height,\n left: rangeBoundingClientRect.left - xOffset,\n top: rangeBoundingClientRect.top - yOffset,\n width: rangeBoundingClientRect.width\n };\n }\n\n highlightBounding.style.width = "".concat(highlightBounding.rect.width * scale, "px");\n highlightBounding.style.height = "".concat(highlightBounding.rect.height * scale, "px");\n highlightBounding.style.left = "".concat(highlightBounding.rect.left * scale, "px");\n highlightBounding.style.top = "".concat(highlightBounding.rect.top * scale, "px");\n highlightParent.append(highlightBounding);\n highlightsContainer.append(highlightParent);\n return highlightParent;\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n console.log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n console.log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n console.log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRange(range, getCssSelector, computeElementCFI) {\n var startIsElement = range.startContainer.nodeType === Node.ELEMENT_NODE;\n var startContainerElement = startIsElement ? range.startContainer : range.startContainer.parentNode && range.startContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.startContainer.parentNode : undefined;\n\n if (!startContainerElement) {\n return undefined;\n }\n\n var startContainerChildTextNodeIndex = startIsElement ? -1 : Array.from(startContainerElement.childNodes).indexOf(range.startContainer);\n\n if (startContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var startContainerElementCssSelector = getCssSelector(startContainerElement);\n var endIsElement = range.endContainer.nodeType === Node.ELEMENT_NODE;\n var endContainerElement = endIsElement ? range.endContainer : range.endContainer.parentNode && range.endContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.endContainer.parentNode : undefined;\n\n if (!endContainerElement) {\n return undefined;\n }\n\n var endContainerChildTextNodeIndex = endIsElement ? -1 : Array.from(endContainerElement.childNodes).indexOf(range.endContainer);\n\n if (endContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var endContainerElementCssSelector = getCssSelector(endContainerElement);\n var commonElementAncestor = getCommonAncestorElement(range.startContainer, range.endContainer);\n\n if (!commonElementAncestor) {\n console.log("^^^ NO RANGE COMMON ANCESTOR?!");\n return undefined;\n }\n\n if (range.commonAncestorContainer) {\n var rangeCommonAncestorElement = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? range.commonAncestorContainer : range.commonAncestorContainer.parentNode;\n\n if (rangeCommonAncestorElement && rangeCommonAncestorElement.nodeType === Node.ELEMENT_NODE) {\n if (commonElementAncestor !== rangeCommonAncestorElement) {\n console.log(">>>>>> COMMON ANCESTOR CONTAINER DIFF??!");\n console.log(getCssSelector(commonElementAncestor));\n console.log(getCssSelector(rangeCommonAncestorElement));\n }\n }\n }\n\n var rootElementCfi = computeElementCFI(commonElementAncestor);\n var startElementCfi = computeElementCFI(startContainerElement);\n var endElementCfi = computeElementCFI(endContainerElement);\n var cfi;\n\n if (rootElementCfi && startElementCfi && endElementCfi) {\n var startElementOrTextCfi = startElementCfi;\n\n if (!startIsElement) {\n var startContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(startContainerElement, range.startContainer);\n startElementOrTextCfi = startElementCfi + "/" + startContainerChildTextNodeIndexForCfi + ":" + range.startOffset;\n } else {\n if (range.startOffset >= 0 && range.startOffset < startContainerElement.childNodes.length) {\n var childNode = startContainerElement.childNodes[range.startOffset];\n\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (range.startOffset + 1) * 2;\n } else {\n var cfiTextNodeIndex = getChildTextNodeCfiIndex(startContainerElement, childNode);\n startElementOrTextCfi = startElementCfi + "/" + cfiTextNodeIndex;\n }\n } else {\n var cfiIndexOfLastElement = startContainerElement.childElementCount * 2;\n var lastChildNode = startContainerElement.childNodes[startContainerElement.childNodes.length - 1];\n\n if (lastChildNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 1);\n } else {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 2);\n }\n }\n }\n\n var endElementOrTextCfi = endElementCfi;\n\n if (!endIsElement) {\n var endContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(endContainerElement, range.endContainer);\n endElementOrTextCfi = endElementCfi + "/" + endContainerChildTextNodeIndexForCfi + ":" + range.endOffset;\n } else {\n if (range.endOffset >= 0 && range.endOffset < endContainerElement.childNodes.length) {\n var _childNode = endContainerElement.childNodes[range.endOffset];\n\n if (_childNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (range.endOffset + 1) * 2;\n } else {\n var _cfiTextNodeIndex = getChildTextNodeCfiIndex(endContainerElement, _childNode);\n\n endElementOrTextCfi = endElementCfi + "/" + _cfiTextNodeIndex;\n }\n } else {\n var _cfiIndexOfLastElement = endContainerElement.childElementCount * 2;\n\n var _lastChildNode = endContainerElement.childNodes[endContainerElement.childNodes.length - 1];\n\n if (_lastChildNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 1);\n } else {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 2);\n }\n }\n }\n\n cfi = rootElementCfi + "," + startElementOrTextCfi.replace(rootElementCfi, "") + "," + endElementOrTextCfi.replace(rootElementCfi, "");\n }\n\n return {\n cfi: cfi,\n endContainerChildTextNodeIndex: endContainerChildTextNodeIndex,\n endContainerElementCssSelector: endContainerElementCssSelector,\n endOffset: range.endOffset,\n startContainerChildTextNodeIndex: startContainerChildTextNodeIndex,\n startContainerElementCssSelector: startContainerElementCssSelector,\n startOffset: range.startOffset\n };\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n console.log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n console.log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\n\nfunction frameForHighlightAnnotationMarkWithID(win, id) {\n var clientRects = frameForHighlightWithID(id);\n if (!clientRects) return;\n var topClientRect = clientRects[0];\n var maxHeight = topClientRect.height;\n\n var _iterator18 = highlight_createForOfIteratorHelper(clientRects),\n _step18;\n\n try {\n for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {\n var clientRect = _step18.value;\n if (clientRect.top < topClientRect.top) topClientRect = clientRect;\n if (clientRect.height > maxHeight) maxHeight = clientRect.height;\n }\n } catch (err) {\n _iterator18.e(err);\n } finally {\n _iterator18.f();\n }\n\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var newTop = topClientRect.top;\n\n if (_highlightsContainer) {\n do {\n var boundingAreas = document.getElementsByClassName(CLASS_ANNOTATION_BOUNDING_AREA);\n var found = false; //for (let i = 0, length = boundingAreas.snapshotLength; i < length; ++i) {\n\n for (var i = 0, len = boundingAreas.length | 0; i < len; i = i + 1 | 0) {\n var boundingArea = boundingAreas[i];\n\n if (Math.abs(boundingArea.rect.top - (newTop - yOffset)) < 3) {\n newTop += boundingArea.rect.height;\n found = true;\n break;\n }\n }\n } while (found);\n }\n\n topClientRect.top = newTop;\n topClientRect.height = maxHeight;\n return topClientRect;\n}\n\nfunction highlightWithID(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n return highlight;\n}\n\nfunction frameForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n return clientRects;\n}\n\nfunction rangeInfo2Location(rangeInfo) {\n return {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n partialCfi: rangeInfo.cfi,\n domRange: {\n start: {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n textNodeIndex: rangeInfo.startContainerChildTextNodeIndex,\n offset: rangeInfo.startOffset\n },\n end: {\n cssSelector: rangeInfo.endContainerElementCssSelector,\n textNodeIndex: rangeInfo.endContainerChildTextNodeIndex,\n offset: rangeInfo.endOffset\n }\n }\n };\n}\n\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n cfi: location.partialCfi,\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction rectangleForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRects[0].left,\n width: clientRects[0].width,\n top: clientRects[0].top,\n height: clientRects[0].height\n };\n return size;\n}\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n var clientRect = range.getBoundingClientRect();\n var handleBounds = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRect.left,\n width: clientRect.width,\n top: clientRect.top,\n height: clientRect.height\n };\n return handleBounds;\n } catch (e) {\n return null;\n }\n}\nfunction setScrollMode(flag) {\n if (!flag) {\n document.documentElement.classList.add(CLASS_PAGINATED);\n } else {\n document.documentElement.classList.remove(CLASS_PAGINATED);\n }\n}\n/*\n if (document.addEventListener) { // IE >= 9; other browsers\n document.addEventListener(\'contextmenu\', function(e) {\n //alert("You\'ve tried to open context menu"); //here you draw your own menu\n //e.preventDefault();\n //let getCssSelector = fullQualifiedSelector;\n \n\t\t\tlet str = window.getSelection();\n\t\t\tlet selectionInfo = getCurrentSelectionInfo();\n\t\t\tlet pos = createHighlight(selectionInfo,{red:10,green:50,blue:230},true);\n\t\t\tlet ret2 = createAnnotation(pos.id);\n\t\t\t\n }, false);\n } else { // IE < 9\n document.attachEvent(\'oncontextmenu\', function() {\n alert("You\'ve tried to open context menu");\n window.event.returnValue = false;\n });\n }\n*/\n// EXTERNAL MODULE: ./node_modules/css-selector-generator/build/index.js\nvar build = __webpack_require__(4766);\n;// CONCATENATED MODULE: ./src/dom.js\n//\n// Copyright 2022 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = selection_getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction selection_getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : selection_createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction selection_createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction selection_convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return selection_createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction selection_location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n}; // Legacy highlights API.\n\nwindow.createAnnotation = createAnnotation;\nwindow.createHighlight = createHighlight;\nwindow.destroyHighlight = destroyHighlight;\nwindow.getCurrentSelectionInfo = getCurrentSelectionInfo;\nwindow.getSelectionRect = getSelectionRect;\nwindow.rectangleForHighlightWithID = rectangleForHighlightWithID;\nwindow.setScrollMode = setScrollMode;\n;// CONCATENATED MODULE: ./src/index-reflowable.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for reflowable resources.\n\nwindow.readium.isReflowable = true;\ndocument.addEventListener("DOMContentLoaded", function () {\n // Setups the `viewport` meta tag to disable zooming.\n var meta = document.createElement("meta");\n meta.setAttribute("name", "viewport");\n meta.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no");\n document.head.appendChild(meta);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q0FBQzRZLGdCQUFQLEdBQTBCQSxnQkFBMUI7QUFDQTVZLE1BQU0sQ0FBQ21hLHVCQUFQLEdBQWlDQSx1QkFBakM7QUFDQW5hLE1BQU0sQ0FBQ29rQixnQkFBUCxHQUEwQkEsZ0JBQTFCO0FBQ0Fwa0IsTUFBTSxDQUFDbWtCLDJCQUFQLEdBQXFDQSwyQkFBckM7QUFDQW5rQixNQUFNLENBQUN1a0IsYUFBUCxHQUF1QkEsYUFBdkIsQzs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQXZrQixNQUFNLENBQUMra0IsT0FBUCxDQUFlZ0IsWUFBZixHQUE4QixJQUE5QjtBQUVBdG9CLFFBQVEsQ0FBQ3dDLGdCQUFULENBQTBCLGtCQUExQixFQUE4QyxZQUFZO0FBQ3hEO0FBQ0EsTUFBSStsQixJQUFJLEdBQUd2b0IsUUFBUSxDQUFDbUUsYUFBVCxDQUF1QixNQUF2QixDQUFYO0FBQ0Fva0IsRUFBQUEsSUFBSSxDQUFDbmtCLFlBQUwsQ0FBa0IsTUFBbEIsRUFBMEIsVUFBMUI7QUFDQW1rQixFQUFBQSxJQUFJLENBQUNua0IsWUFBTCxDQUNFLFNBREYsRUFFRSw4RkFGRjtBQUlBcEUsRUFBQUEsUUFBUSxDQUFDd29CLElBQVQsQ0FBY2hrQixXQUFkLENBQTBCK2pCLElBQTFCO0FBQ0QsQ0FURCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL21hdGNoLXF1b3RlLmpzP2RkNmEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZS5qcz9mZGVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzLmpzPzQwMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy91dGlscy5qcz8wMjVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvcmVjdC5qcz80ZDVhIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZGVjb3JhdG9yLmpzPzFiMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9nZXN0dXJlcy5qcz8xNGMyIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaGlnaGxpZ2h0LmpzPzhkYTgiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kb20uanM/Y2JmMCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL3NlbGVjdGlvbi5qcz81OWFjIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaW5kZXguanM/YjYzNSIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LXJlZmxvd2FibGUuanM/MzkyNSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXBwcm94U2VhcmNoIGZyb20gJ2FwcHJveC1zdHJpbmctbWF0Y2gnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ2FwcHJveC1zdHJpbmctbWF0Y2gnKS5NYXRjaH0gU3RyaW5nTWF0Y2hcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIE1hdGNoXG4gKiBAcHJvcCB7bnVtYmVyfSBzdGFydCAtIFN0YXJ0IG9mZnNldCBvZiBtYXRjaCBpbiB0ZXh0XG4gKiBAcHJvcCB7bnVtYmVyfSBlbmQgLSBFbmQgb2Zmc2V0IG9mIG1hdGNoIGluIHRleHRcbiAqIEBwcm9wIHtudW1iZXJ9IHNjb3JlIC1cbiAqICAgU2NvcmUgZm9yIHRoZSBtYXRjaCBiZXR3ZWVuIDAgYW5kIDEuMCwgd2hlcmUgMS4wIGluZGljYXRlcyBhIHBlcmZlY3QgbWF0Y2hcbiAqICAgZm9yIHRoZSBxdW90ZSBhbmQgY29udGV4dC5cbiAqL1xuXG4vKipcbiAqIEZpbmQgdGhlIGJlc3QgYXBwcm94aW1hdGUgbWF0Y2hlcyBmb3IgYHN0cmAgaW4gYHRleHRgIGFsbG93aW5nIHVwIHRvIGBtYXhFcnJvcnNgIGVycm9ycy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICogQHBhcmFtIHtudW1iZXJ9IG1heEVycm9yc1xuICogQHJldHVybiB7U3RyaW5nTWF0Y2hbXX1cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHN0ciwgbWF4RXJyb3JzKSB7XG4gIC8vIERvIGEgZmFzdCBzZWFyY2ggZm9yIGV4YWN0IG1hdGNoZXMuIFRoZSBgYXBwcm94LXN0cmluZy1tYXRjaGAgbGlicmFyeVxuICAvLyBkb2Vzbid0IGN1cnJlbnRseSBpbmNvcnBvcmF0ZSB0aGlzIG9wdGltaXphdGlvbiBpdHNlbGYuXG4gIGxldCBtYXRjaFBvcyA9IDA7XG4gIGxldCBleGFjdE1hdGNoZXMgPSBbXTtcbiAgd2hpbGUgKG1hdGNoUG9zICE9PSAtMSkge1xuICAgIG1hdGNoUG9zID0gdGV4dC5pbmRleE9mKHN0ciwgbWF0Y2hQb3MpO1xuICAgIGlmIChtYXRjaFBvcyAhPT0gLTEpIHtcbiAgICAgIGV4YWN0TWF0Y2hlcy5wdXNoKHtcbiAgICAgICAgc3RhcnQ6IG1hdGNoUG9zLFxuICAgICAgICBlbmQ6IG1hdGNoUG9zICsgc3RyLmxlbmd0aCxcbiAgICAgICAgZXJyb3JzOiAwLFxuICAgICAgfSk7XG4gICAgICBtYXRjaFBvcyArPSAxO1xuICAgIH1cbiAgfVxuICBpZiAoZXhhY3RNYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gZXhhY3RNYXRjaGVzO1xuICB9XG5cbiAgLy8gSWYgdGhlcmUgYXJlIG5vIGV4YWN0IG1hdGNoZXMsIGRvIGEgbW9yZSBleHBlbnNpdmUgc2VhcmNoIGZvciBtYXRjaGVzXG4gIC8vIHdpdGggZXJyb3JzLlxuICByZXR1cm4gYXBwcm94U2VhcmNoKHRleHQsIHN0ciwgbWF4RXJyb3JzKTtcbn1cblxuLyoqXG4gKiBDb21wdXRlIGEgc2NvcmUgYmV0d2VlbiAwIGFuZCAxLjAgZm9yIHRoZSBzaW1pbGFyaXR5IGJldHdlZW4gYHRleHRgIGFuZCBgc3RyYC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICovXG5mdW5jdGlvbiB0ZXh0TWF0Y2hTY29yZSh0ZXh0LCBzdHIpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgLSBgc2NvcmVNYXRjaGAgd2lsbCBuZXZlciBwYXNzIGFuIGVtcHR5IHN0cmluZyAqL1xuICBpZiAoc3RyLmxlbmd0aCA9PT0gMCB8fCB0ZXh0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiAwLjA7XG4gIH1cbiAgY29uc3QgbWF0Y2hlcyA9IHNlYXJjaCh0ZXh0LCBzdHIsIHN0ci5sZW5ndGgpO1xuXG4gIC8vIHByZXR0aWVyLWlnbm9yZVxuICByZXR1cm4gMSAtIChtYXRjaGVzWzBdLmVycm9ycyAvIHN0ci5sZW5ndGgpO1xufVxuXG4vKipcbiAqIEZpbmQgdGhlIGJlc3QgYXBwcm94aW1hdGUgbWF0Y2ggZm9yIGBxdW90ZWAgaW4gYHRleHRgLlxuICpcbiAqIFJldHVybnMgYG51bGxgIGlmIG5vIG1hdGNoIGV4Y2VlZGluZyB0aGUgbWluaW11bSBxdWFsaXR5IHRocmVzaG9sZCB3YXMgZm91bmQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBEb2N1bWVudCB0ZXh0IHRvIHNlYXJjaFxuICogQHBhcmFtIHtzdHJpbmd9IHF1b3RlIC0gU3RyaW5nIHRvIGZpbmQgd2l0aGluIGB0ZXh0YFxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLVxuICogICBDb250ZXh0IGluIHdoaWNoIHRoZSBxdW90ZSBvcmlnaW5hbGx5IGFwcGVhcmVkLiBUaGlzIGlzIHVzZWQgdG8gY2hvb3NlIHRoZVxuICogICBiZXN0IG1hdGNoLlxuICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQucHJlZml4XSAtIEV4cGVjdGVkIHRleHQgYmVmb3JlIHRoZSBxdW90ZVxuICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQuc3VmZml4XSAtIEV4cGVjdGVkIHRleHQgYWZ0ZXIgdGhlIHF1b3RlXG4gKiAgIEBwYXJhbSB7bnVtYmVyfSBbY29udGV4dC5oaW50XSAtIEV4cGVjdGVkIG9mZnNldCBvZiBtYXRjaCB3aXRoaW4gdGV4dFxuICogQHJldHVybiB7TWF0Y2h8bnVsbH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoUXVvdGUodGV4dCwgcXVvdGUsIGNvbnRleHQgPSB7fSkge1xuICBpZiAocXVvdGUubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBDaG9vc2UgdGhlIG1heGltdW0gbnVtYmVyIG9mIGVycm9ycyB0byBhbGxvdyBmb3IgdGhlIGluaXRpYWwgc2VhcmNoLlxuICAvLyBUaGlzIGNob2ljZSBpbnZvbHZlcyBhIHRyYWRlb2ZmIGJldHdlZW46XG4gIC8vXG4gIC8vICAtIFJlY2FsbCAocHJvcG9ydGlvbiBvZiBcImdvb2RcIiBtYXRjaGVzIGZvdW5kKVxuICAvLyAgLSBQcmVjaXNpb24gKHByb3BvcnRpb24gb2YgbWF0Y2hlcyBmb3VuZCB3aGljaCBhcmUgXCJnb29kXCIpXG4gIC8vICAtIENvc3Qgb2YgdGhlIGluaXRpYWwgc2VhcmNoIGFuZCBvZiBwcm9jZXNzaW5nIHRoZSBjYW5kaWRhdGUgbWF0Y2hlcyBbMV1cbiAgLy9cbiAgLy8gWzFdIFNwZWNpZmljYWxseSwgdGhlIGV4cGVjdGVkLXRpbWUgY29tcGxleGl0eSBvZiB0aGUgaW5pdGlhbCBzZWFyY2ggaXNcbiAgLy8gICAgIGBPKChtYXhFcnJvcnMgLyAzMikgKiB0ZXh0Lmxlbmd0aClgLiBTZWUgYGFwcHJveC1zdHJpbmctbWF0Y2hgIGRvY3MuXG4gIGNvbnN0IG1heEVycm9ycyA9IE1hdGgubWluKDI1NiwgcXVvdGUubGVuZ3RoIC8gMik7XG5cbiAgLy8gRmluZCBjbG9zZXN0IG1hdGNoZXMgZm9yIGBxdW90ZWAgaW4gYHRleHRgIGJhc2VkIG9uIGVkaXQgZGlzdGFuY2UuXG4gIGNvbnN0IG1hdGNoZXMgPSBzZWFyY2godGV4dCwgcXVvdGUsIG1heEVycm9ycyk7XG5cbiAgaWYgKG1hdGNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZSBhIHNjb3JlIGJldHdlZW4gMCBhbmQgMS4wIGZvciBhIG1hdGNoIGNhbmRpZGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmdNYXRjaH0gbWF0Y2hcbiAgICovXG4gIGNvbnN0IHNjb3JlTWF0Y2ggPSBtYXRjaCA9PiB7XG4gICAgY29uc3QgcXVvdGVXZWlnaHQgPSA1MDsgLy8gU2ltaWxhcml0eSBvZiBtYXRjaGVkIHRleHQgdG8gcXVvdGUuXG4gICAgY29uc3QgcHJlZml4V2VpZ2h0ID0gMjA7IC8vIFNpbWlsYXJpdHkgb2YgdGV4dCBiZWZvcmUgbWF0Y2hlZCB0ZXh0IHRvIGBjb250ZXh0LnByZWZpeGAuXG4gICAgY29uc3Qgc3VmZml4V2VpZ2h0ID0gMjA7IC8vIFNpbWlsYXJpdHkgb2YgdGV4dCBhZnRlciBtYXRjaGVkIHRleHQgdG8gYGNvbnRleHQuc3VmZml4YC5cbiAgICBjb25zdCBwb3NXZWlnaHQgPSAyOyAvLyBQcm94aW1pdHkgdG8gZXhwZWN0ZWQgbG9jYXRpb24uIFVzZWQgYXMgYSB0aWUtYnJlYWtlci5cblxuICAgIGNvbnN0IHF1b3RlU2NvcmUgPSAxIC0gbWF0Y2guZXJyb3JzIC8gcXVvdGUubGVuZ3RoO1xuXG4gICAgY29uc3QgcHJlZml4U2NvcmUgPSBjb250ZXh0LnByZWZpeFxuICAgICAgPyB0ZXh0TWF0Y2hTY29yZShcbiAgICAgICAgICB0ZXh0LnNsaWNlKE1hdGgubWF4KDAsIG1hdGNoLnN0YXJ0IC0gY29udGV4dC5wcmVmaXgubGVuZ3RoKSwgbWF0Y2guc3RhcnQpLFxuICAgICAgICAgIGNvbnRleHQucHJlZml4XG4gICAgICAgIClcbiAgICAgIDogMS4wO1xuICAgIGNvbnN0IHN1ZmZpeFNjb3JlID0gY29udGV4dC5zdWZmaXhcbiAgICAgID8gdGV4dE1hdGNoU2NvcmUoXG4gICAgICAgICAgdGV4dC5zbGljZShtYXRjaC5lbmQsIG1hdGNoLmVuZCArIGNvbnRleHQuc3VmZml4Lmxlbmd0aCksXG4gICAgICAgICAgY29udGV4dC5zdWZmaXhcbiAgICAgICAgKVxuICAgICAgOiAxLjA7XG5cbiAgICBsZXQgcG9zU2NvcmUgPSAxLjA7XG4gICAgaWYgKHR5cGVvZiBjb250ZXh0LmhpbnQgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25zdCBvZmZzZXQgPSBNYXRoLmFicyhtYXRjaC5zdGFydCAtIGNvbnRleHQuaGludCk7XG4gICAgICBwb3NTY29yZSA9IDEuMCAtIG9mZnNldCAvIHRleHQubGVuZ3RoO1xuICAgIH1cblxuICAgIGNvbnN0IHJhd1Njb3JlID1cbiAgICAgIHF1b3RlV2VpZ2h0ICogcXVvdGVTY29yZSArXG4gICAgICBwcmVmaXhXZWlnaHQgKiBwcmVmaXhTY29yZSArXG4gICAgICBzdWZmaXhXZWlnaHQgKiBzdWZmaXhTY29yZSArXG4gICAgICBwb3NXZWlnaHQgKiBwb3NTY29yZTtcbiAgICBjb25zdCBtYXhTY29yZSA9IHF1b3RlV2VpZ2h0ICsgcHJlZml4V2VpZ2h0ICsgc3VmZml4V2VpZ2h0ICsgcG9zV2VpZ2h0O1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRTY29yZSA9IHJhd1Njb3JlIC8gbWF4U2NvcmU7XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFNjb3JlO1xuICB9O1xuXG4gIC8vIFJhbmsgbWF0Y2hlcyBiYXNlZCBvbiBzaW1pbGFyaXR5IG9mIGFjdHVhbCBhbmQgZXhwZWN0ZWQgc3Vycm91bmRpbmcgdGV4dFxuICAvLyBhbmQgYWN0dWFsL2V4cGVjdGVkIG9mZnNldCBpbiB0aGUgZG9jdW1lbnQgdGV4dC5cbiAgY29uc3Qgc2NvcmVkTWF0Y2hlcyA9IG1hdGNoZXMubWFwKG0gPT4gKHtcbiAgICBzdGFydDogbS5zdGFydCxcbiAgICBlbmQ6IG0uZW5kLFxuICAgIHNjb3JlOiBzY29yZU1hdGNoKG0pLFxuICB9KSk7XG5cbiAgLy8gQ2hvb3NlIG1hdGNoIHdpdGggaGlnaGVzdCBzY29yZS5cbiAgc2NvcmVkTWF0Y2hlcy5zb3J0KChhLCBiKSA9PiBiLnNjb3JlIC0gYS5zY29yZSk7XG4gIHJldHVybiBzY29yZWRNYXRjaGVzWzBdO1xufVxuIiwiLyoqXG4gKiBSZXR1cm4gdGhlIGNvbWJpbmVkIGxlbmd0aCBvZiB0ZXh0IG5vZGVzIGNvbnRhaW5lZCBpbiBgbm9kZWAuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKi9cbmZ1bmN0aW9uIG5vZGVUZXh0TGVuZ3RoKG5vZGUpIHtcbiAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7XG4gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTpcbiAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOlxuICAgICAgLy8gbmIuIGB0ZXh0Q29udGVudGAgZXhjbHVkZXMgdGV4dCBpbiBjb21tZW50cyBhbmQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnNcbiAgICAgIC8vIHdoZW4gY2FsbGVkIG9uIGEgcGFyZW50IGVsZW1lbnQsIHNvIHdlIGRvbid0IG5lZWQgdG8gc3VidHJhY3QgdGhhdCBoZXJlLlxuXG4gICAgICByZXR1cm4gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChub2RlLnRleHRDb250ZW50KS5sZW5ndGg7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAwO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSB0b3RhbCBsZW5ndGggb2YgdGhlIHRleHQgb2YgYWxsIHByZXZpb3VzIHNpYmxpbmdzIG9mIGBub2RlYC5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqL1xuZnVuY3Rpb24gcHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgobm9kZSkge1xuICBsZXQgc2libGluZyA9IG5vZGUucHJldmlvdXNTaWJsaW5nO1xuICBsZXQgbGVuZ3RoID0gMDtcbiAgd2hpbGUgKHNpYmxpbmcpIHtcbiAgICBsZW5ndGggKz0gbm9kZVRleHRMZW5ndGgoc2libGluZyk7XG4gICAgc2libGluZyA9IHNpYmxpbmcucHJldmlvdXNTaWJsaW5nO1xuICB9XG4gIHJldHVybiBsZW5ndGg7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBvbmUgb3IgbW9yZSBjaGFyYWN0ZXIgb2Zmc2V0cyB3aXRoaW4gYW4gZWxlbWVudCB0byAodGV4dCBub2RlLCBwb3NpdGlvbilcbiAqIHBhaXJzLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtudW1iZXJbXX0gb2Zmc2V0cyAtIE9mZnNldHMsIHdoaWNoIG11c3QgYmUgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlclxuICogQHJldHVybiB7eyBub2RlOiBUZXh0LCBvZmZzZXQ6IG51bWJlciB9W119XG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVPZmZzZXRzKGVsZW1lbnQsIC4uLm9mZnNldHMpIHtcbiAgbGV0IG5leHRPZmZzZXQgPSBvZmZzZXRzLnNoaWZ0KCk7XG4gIGNvbnN0IG5vZGVJdGVyID0gLyoqIEB0eXBlIHtEb2N1bWVudH0gKi8gKFxuICAgIGVsZW1lbnQub3duZXJEb2N1bWVudFxuICApLmNyZWF0ZU5vZGVJdGVyYXRvcihlbGVtZW50LCBOb2RlRmlsdGVyLlNIT1dfVEVYVCk7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcblxuICBsZXQgY3VycmVudE5vZGUgPSBub2RlSXRlci5uZXh0Tm9kZSgpO1xuICBsZXQgdGV4dE5vZGU7XG4gIGxldCBsZW5ndGggPSAwO1xuXG4gIC8vIEZpbmQgdGhlIHRleHQgbm9kZSBjb250YWluaW5nIHRoZSBgbmV4dE9mZnNldGB0aCBjaGFyYWN0ZXIgZnJvbSB0aGUgc3RhcnRcbiAgLy8gb2YgYGVsZW1lbnRgLlxuICB3aGlsZSAobmV4dE9mZnNldCAhPT0gdW5kZWZpbmVkICYmIGN1cnJlbnROb2RlKSB7XG4gICAgdGV4dE5vZGUgPSAvKiogQHR5cGUge1RleHR9ICovIChjdXJyZW50Tm9kZSk7XG4gICAgaWYgKGxlbmd0aCArIHRleHROb2RlLmRhdGEubGVuZ3RoID4gbmV4dE9mZnNldCkge1xuICAgICAgcmVzdWx0cy5wdXNoKHsgbm9kZTogdGV4dE5vZGUsIG9mZnNldDogbmV4dE9mZnNldCAtIGxlbmd0aCB9KTtcbiAgICAgIG5leHRPZmZzZXQgPSBvZmZzZXRzLnNoaWZ0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnROb2RlID0gbm9kZUl0ZXIubmV4dE5vZGUoKTtcbiAgICAgIGxlbmd0aCArPSB0ZXh0Tm9kZS5kYXRhLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICAvLyBCb3VuZGFyeSBjYXNlLlxuICB3aGlsZSAobmV4dE9mZnNldCAhPT0gdW5kZWZpbmVkICYmIHRleHROb2RlICYmIGxlbmd0aCA9PT0gbmV4dE9mZnNldCkge1xuICAgIHJlc3VsdHMucHVzaCh7IG5vZGU6IHRleHROb2RlLCBvZmZzZXQ6IHRleHROb2RlLmRhdGEubGVuZ3RoIH0pO1xuICAgIG5leHRPZmZzZXQgPSBvZmZzZXRzLnNoaWZ0KCk7XG4gIH1cblxuICBpZiAobmV4dE9mZnNldCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ09mZnNldCBleGNlZWRzIHRleHQgbGVuZ3RoJyk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0cztcbn1cblxuZXhwb3J0IGxldCBSRVNPTFZFX0ZPUldBUkRTID0gMTtcbmV4cG9ydCBsZXQgUkVTT0xWRV9CQUNLV0FSRFMgPSAyO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gb2Zmc2V0IHdpdGhpbiB0aGUgdGV4dCBjb250ZW50IG9mIGFuIGVsZW1lbnQuXG4gKlxuICogVGhpcyBwb3NpdGlvbiBjYW4gYmUgcmVzb2x2ZWQgdG8gYSBzcGVjaWZpYyBkZXNjZW5kYW50IG5vZGUgaW4gdGhlIGN1cnJlbnRcbiAqIERPTSBzdWJ0cmVlIG9mIHRoZSBlbGVtZW50IHVzaW5nIHRoZSBgcmVzb2x2ZWAgbWV0aG9kLlxuICovXG5leHBvcnQgY2xhc3MgVGV4dFBvc2l0aW9uIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIGBUZXh0UG9zaXRpb25gIHRoYXQgcmVmZXJzIHRvIHRoZSB0ZXh0IHBvc2l0aW9uIGBvZmZzZXRgIHdpdGhpblxuICAgKiB0aGUgdGV4dCBjb250ZW50IG9mIGBlbGVtZW50YC5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICovXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9mZnNldCkge1xuICAgIGlmIChvZmZzZXQgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09mZnNldCBpcyBpbnZhbGlkJyk7XG4gICAgfVxuXG4gICAgLyoqIEVsZW1lbnQgdGhhdCBgb2Zmc2V0YCBpcyByZWxhdGl2ZSB0by4gKi9cbiAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuXG4gICAgLyoqIENoYXJhY3RlciBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGVsZW1lbnQncyBgdGV4dENvbnRlbnRgLiAqL1xuICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGNvcHkgb2YgdGhpcyBwb3NpdGlvbiB3aXRoIG9mZnNldCByZWxhdGl2ZSB0byBhIGdpdmVuIGFuY2VzdG9yXG4gICAqIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcGFyZW50IC0gQW5jZXN0b3Igb2YgYHRoaXMuZWxlbWVudGBcbiAgICogQHJldHVybiB7VGV4dFBvc2l0aW9ufVxuICAgKi9cbiAgcmVsYXRpdmVUbyhwYXJlbnQpIHtcbiAgICBpZiAoIXBhcmVudC5jb250YWlucyh0aGlzLmVsZW1lbnQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmVudCBpcyBub3QgYW4gYW5jZXN0b3Igb2YgY3VycmVudCBlbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgbGV0IGVsID0gdGhpcy5lbGVtZW50O1xuICAgIGxldCBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICB3aGlsZSAoZWwgIT09IHBhcmVudCkge1xuICAgICAgb2Zmc2V0ICs9IHByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoKGVsKTtcbiAgICAgIGVsID0gLyoqIEB0eXBlIHtFbGVtZW50fSAqLyAoZWwucGFyZW50RWxlbWVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb24oZWwsIG9mZnNldCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGUgcG9zaXRpb24gdG8gYSBzcGVjaWZpYyB0ZXh0IG5vZGUgYW5kIG9mZnNldCB3aXRoaW4gdGhhdCBub2RlLlxuICAgKlxuICAgKiBUaHJvd3MgaWYgYHRoaXMub2Zmc2V0YCBleGNlZWRzIHRoZSBsZW5ndGggb2YgdGhlIGVsZW1lbnQncyB0ZXh0LiBJbiB0aGVcbiAgICogY2FzZSB3aGVyZSB0aGUgZWxlbWVudCBoYXMgbm8gdGV4dCBhbmQgYHRoaXMub2Zmc2V0YCBpcyAwLCB0aGUgYGRpcmVjdGlvbmBcbiAgICogb3B0aW9uIGRldGVybWluZXMgd2hhdCBoYXBwZW5zLlxuICAgKlxuICAgKiBPZmZzZXRzIGF0IHRoZSBib3VuZGFyeSBiZXR3ZWVuIHR3byBub2RlcyBhcmUgcmVzb2x2ZWQgdG8gdGhlIHN0YXJ0IG9mIHRoZVxuICAgKiBub2RlIHRoYXQgYmVnaW5zIGF0IHRoZSBib3VuZGFyeS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIEBwYXJhbSB7UkVTT0xWRV9GT1JXQVJEU3xSRVNPTFZFX0JBQ0tXQVJEU30gW29wdGlvbnMuZGlyZWN0aW9uXSAtXG4gICAqICAgICBTcGVjaWZpZXMgaW4gd2hpY2ggZGlyZWN0aW9uIHRvIHNlYXJjaCBmb3IgdGhlIG5lYXJlc3QgdGV4dCBub2RlIGlmXG4gICAqICAgICBgdGhpcy5vZmZzZXRgIGlzIGAwYCBhbmQgYHRoaXMuZWxlbWVudGAgaGFzIG5vIHRleHQuIElmIG5vdCBzcGVjaWZpZWRcbiAgICogICAgIGFuIGVycm9yIGlzIHRocm93bi5cbiAgICogQHJldHVybiB7eyBub2RlOiBUZXh0LCBvZmZzZXQ6IG51bWJlciB9fVxuICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfVxuICAgKi9cbiAgcmVzb2x2ZShvcHRpb25zID0ge30pIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHJlc29sdmVPZmZzZXRzKHRoaXMuZWxlbWVudCwgdGhpcy5vZmZzZXQpWzBdO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKHRoaXMub2Zmc2V0ID09PSAwICYmIG9wdGlvbnMuZGlyZWN0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdHcgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKFxuICAgICAgICAgIHRoaXMuZWxlbWVudC5nZXRSb290Tm9kZSgpLFxuICAgICAgICAgIE5vZGVGaWx0ZXIuU0hPV19URVhUXG4gICAgICAgICk7XG4gICAgICAgIHR3LmN1cnJlbnROb2RlID0gdGhpcy5lbGVtZW50O1xuICAgICAgICBjb25zdCBmb3J3YXJkcyA9IG9wdGlvbnMuZGlyZWN0aW9uID09PSBSRVNPTFZFX0ZPUldBUkRTO1xuICAgICAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtUZXh0fG51bGx9ICovIChcbiAgICAgICAgICBmb3J3YXJkcyA/IHR3Lm5leHROb2RlKCkgOiB0dy5wcmV2aW91c05vZGUoKVxuICAgICAgICApO1xuICAgICAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbm9kZTogdGV4dCwgb2Zmc2V0OiBmb3J3YXJkcyA/IDAgOiB0ZXh0LmRhdGEubGVuZ3RoIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIGBUZXh0UG9zaXRpb25gIHRoYXQgcmVmZXJzIHRvIHRoZSBgb2Zmc2V0YHRoIGNoYXJhY3RlciB3aXRoaW5cbiAgICogYG5vZGVgLlxuICAgKlxuICAgKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb259XG4gICAqL1xuICBzdGF0aWMgZnJvbUNoYXJPZmZzZXQobm9kZSwgb2Zmc2V0KSB7XG4gICAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7XG4gICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOlxuICAgICAgICByZXR1cm4gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChub2RlLCBvZmZzZXQpO1xuICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTpcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb24oLyoqIEB0eXBlIHtFbGVtZW50fSAqLyAobm9kZSksIG9mZnNldCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vZGUgaXMgbm90IGFuIGVsZW1lbnQgb3IgdGV4dCBub2RlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIGBUZXh0UG9zaXRpb25gIHJlcHJlc2VudGluZyB0aGUgcmFuZ2Ugc3RhcnQgb3IgZW5kIHBvaW50IChub2RlLCBvZmZzZXQpLlxuICAgKlxuICAgKiBAcGFyYW0ge05vZGV9IG5vZGUgLSBUZXh0IG9yIEVsZW1lbnQgbm9kZVxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IC0gT2Zmc2V0IHdpdGhpbiB0aGUgbm9kZS5cbiAgICogQHJldHVybiB7VGV4dFBvc2l0aW9ufVxuICAgKi9cbiAgc3RhdGljIGZyb21Qb2ludChub2RlLCBvZmZzZXQpIHtcbiAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6IHtcbiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gLyoqIEB0eXBlIHtUZXh0fSAqLyAobm9kZSkuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RleHQgbm9kZSBvZmZzZXQgaXMgb3V0IG9mIHJhbmdlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW5vZGUucGFyZW50RWxlbWVudCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGV4dCBub2RlIGhhcyBubyBwYXJlbnQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBwYXJlbnQgZWxlbWVudC5cbiAgICAgICAgY29uc3QgdGV4dE9mZnNldCA9IHByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoKG5vZGUpICsgb2Zmc2V0O1xuXG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKG5vZGUucGFyZW50RWxlbWVudCwgdGV4dE9mZnNldCk7XG4gICAgICB9XG4gICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOiB7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoaWxkIG5vZGUgb2Zmc2V0IGlzIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHRoZSB0ZXh0IGxlbmd0aCBiZWZvcmUgdGhlIGBvZmZzZXRgdGggY2hpbGQgb2YgZWxlbWVudC5cbiAgICAgICAgbGV0IHRleHRPZmZzZXQgPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9mZnNldDsgaSsrKSB7XG4gICAgICAgICAgdGV4dE9mZnNldCArPSBub2RlVGV4dExlbmd0aChub2RlLmNoaWxkTm9kZXNbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb24oLyoqIEB0eXBlIHtFbGVtZW50fSAqLyAobm9kZSksIHRleHRPZmZzZXQpO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb2ludCBpcyBub3QgaW4gYW4gZWxlbWVudCBvciB0ZXh0IG5vZGUnKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgcmVnaW9uIG9mIGEgZG9jdW1lbnQgYXMgYSAoc3RhcnQsIGVuZCkgcGFpciBvZiBgVGV4dFBvc2l0aW9uYCBwb2ludHMuXG4gKlxuICogUmVwcmVzZW50aW5nIGEgcmFuZ2UgaW4gdGhpcyB3YXkgYWxsb3dzIGZvciBjaGFuZ2VzIGluIHRoZSBET00gY29udGVudCBvZiB0aGVcbiAqIHJhbmdlIHdoaWNoIGRvbid0IGFmZmVjdCBpdHMgdGV4dCBjb250ZW50LCB3aXRob3V0IGFmZmVjdGluZyB0aGUgdGV4dCBjb250ZW50XG4gKiBvZiB0aGUgcmFuZ2UgaXRzZWxmLlxuICovXG5leHBvcnQgY2xhc3MgVGV4dFJhbmdlIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhbiBpbW11dGFibGUgYFRleHRSYW5nZWAgZnJvbSBhIGBzdGFydGAgYW5kIGBlbmRgIHBvaW50LlxuICAgKlxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvbn0gc3RhcnRcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb259IGVuZFxuICAgKi9cbiAgY29uc3RydWN0b3Ioc3RhcnQsIGVuZCkge1xuICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICB0aGlzLmVuZCA9IGVuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgcmFuZ2Ugd2l0aCBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyByZWxhdGl2ZSB0byBhXG4gICAqIGdpdmVuIGFuY2VzdG9yLiBTZWUgYFRleHRQb3NpdGlvbi5yZWxhdGl2ZVRvYC5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqL1xuICByZWxhdGl2ZVRvKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gbmV3IFRleHRSYW5nZShcbiAgICAgIHRoaXMuc3RhcnQucmVsYXRpdmVUbyhlbGVtZW50KSxcbiAgICAgIHRoaXMuZW5kLnJlbGF0aXZlVG8oZWxlbWVudClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIGBUZXh0UmFuZ2VgIHRvIGEgRE9NIHJhbmdlLlxuICAgKlxuICAgKiBUaGUgcmVzdWx0aW5nIERPTSBSYW5nZSB3aWxsIGFsd2F5cyBzdGFydCBhbmQgZW5kIGluIGEgYFRleHRgIG5vZGUuXG4gICAqIEhlbmNlIGBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS50b1JhbmdlKClgIGNhbiBiZSB1c2VkIHRvIFwic2hyaW5rXCIgYVxuICAgKiByYW5nZSB0byB0aGUgdGV4dCBpdCBjb250YWlucy5cbiAgICpcbiAgICogTWF5IHRocm93IGlmIHRoZSBgc3RhcnRgIG9yIGBlbmRgIHBvc2l0aW9ucyBjYW5ub3QgYmUgcmVzb2x2ZWQgdG8gYSByYW5nZS5cbiAgICpcbiAgICogQHJldHVybiB7UmFuZ2V9XG4gICAqL1xuICB0b1JhbmdlKCkge1xuICAgIGxldCBzdGFydDtcbiAgICBsZXQgZW5kO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGFydC5lbGVtZW50ID09PSB0aGlzLmVuZC5lbGVtZW50ICYmXG4gICAgICB0aGlzLnN0YXJ0Lm9mZnNldCA8PSB0aGlzLmVuZC5vZmZzZXRcbiAgICApIHtcbiAgICAgIC8vIEZhc3QgcGF0aCBmb3Igc3RhcnQgYW5kIGVuZCBwb2ludHMgaW4gc2FtZSBlbGVtZW50LlxuICAgICAgW3N0YXJ0LCBlbmRdID0gcmVzb2x2ZU9mZnNldHMoXG4gICAgICAgIHRoaXMuc3RhcnQuZWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGFydC5vZmZzZXQsXG4gICAgICAgIHRoaXMuZW5kLm9mZnNldFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhcnQgPSB0aGlzLnN0YXJ0LnJlc29sdmUoeyBkaXJlY3Rpb246IFJFU09MVkVfRk9SV0FSRFMgfSk7XG4gICAgICBlbmQgPSB0aGlzLmVuZC5yZXNvbHZlKHsgZGlyZWN0aW9uOiBSRVNPTFZFX0JBQ0tXQVJEUyB9KTtcbiAgICB9XG5cbiAgICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICAgIHJhbmdlLnNldFN0YXJ0KHN0YXJ0Lm5vZGUsIHN0YXJ0Lm9mZnNldCk7XG4gICAgcmFuZ2Uuc2V0RW5kKGVuZC5ub2RlLCBlbmQub2Zmc2V0KTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBhbiBleGlzdGluZyBET00gYFJhbmdlYCB0byBhIGBUZXh0UmFuZ2VgXG4gICAqXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gICAqIEByZXR1cm4ge1RleHRSYW5nZX1cbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2UocmFuZ2UpIHtcbiAgICBjb25zdCBzdGFydCA9IFRleHRQb3NpdGlvbi5mcm9tUG9pbnQoXG4gICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0XG4gICAgKTtcbiAgICBjb25zdCBlbmQgPSBUZXh0UG9zaXRpb24uZnJvbVBvaW50KHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICByZXR1cm4gbmV3IFRleHRSYW5nZShzdGFydCwgZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBgVGV4dFJhbmdlYCBmcm9tIHRoZSBgc3RhcnRgdGggdG8gYGVuZGB0aCBjaGFyYWN0ZXJzIGluIGByb290YC5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydFxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kXG4gICAqL1xuICBzdGF0aWMgZnJvbU9mZnNldHMocm9vdCwgc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiBuZXcgVGV4dFJhbmdlKFxuICAgICAgbmV3IFRleHRQb3NpdGlvbihyb290LCBzdGFydCksXG4gICAgICBuZXcgVGV4dFBvc2l0aW9uKHJvb3QsIGVuZClcbiAgICApO1xuICB9XG59XG4iLCIvKipcbiAqIFRoaXMgbW9kdWxlIGV4cG9ydHMgYSBzZXQgb2YgY2xhc3NlcyBmb3IgY29udmVydGluZyBiZXR3ZWVuIERPTSBgUmFuZ2VgXG4gKiBvYmplY3RzIGFuZCBkaWZmZXJlbnQgdHlwZXMgb2Ygc2VsZWN0b3JzLiBJdCBpcyBtb3N0bHkgYSB0aGluIHdyYXBwZXIgYXJvdW5kIGFcbiAqIHNldCBvZiBhbmNob3JpbmcgbGlicmFyaWVzLiBJdCBzZXJ2ZXMgdHdvIG1haW4gcHVycG9zZXM6XG4gKlxuICogIDEuIFByb3ZpZGluZyBhIGNvbnNpc3RlbnQgaW50ZXJmYWNlIGFjcm9zcyBkaWZmZXJlbnQgdHlwZXMgb2YgYW5jaG9ycy5cbiAqICAyLiBJbnN1bGF0aW5nIHRoZSByZXN0IG9mIHRoZSBjb2RlIGZyb20gQVBJIGNoYW5nZXMgaW4gdGhlIHVuZGVybHlpbmcgYW5jaG9yaW5nXG4gKiAgICAgbGlicmFyaWVzLlxuICovXG5cbmltcG9ydCB7IG1hdGNoUXVvdGUgfSBmcm9tICcuL21hdGNoLXF1b3RlJztcbmltcG9ydCB7IFRleHRSYW5nZSwgVGV4dFBvc2l0aW9uIH0gZnJvbSAnLi90ZXh0LXJhbmdlJztcbmltcG9ydCB7IG5vZGVGcm9tWFBhdGgsIHhwYXRoRnJvbU5vZGUgfSBmcm9tICcuL3hwYXRoJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi8uLi90eXBlcy9hcGknKS5SYW5nZVNlbGVjdG9yfSBSYW5nZVNlbGVjdG9yXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi8uLi90eXBlcy9hcGknKS5UZXh0UG9zaXRpb25TZWxlY3Rvcn0gVGV4dFBvc2l0aW9uU2VsZWN0b3JcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uLy4uL3R5cGVzL2FwaScpLlRleHRRdW90ZVNlbGVjdG9yfSBUZXh0UXVvdGVTZWxlY3RvclxuICovXG5cbi8qKlxuICogQ29udmVydHMgYmV0d2VlbiBgUmFuZ2VTZWxlY3RvcmAgc2VsZWN0b3JzIGFuZCBgUmFuZ2VgIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBSYW5nZUFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge05vZGV9IHJvb3QgLSBBIHJvb3QgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGFuY2hvci5cbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgLSAgQSByYW5nZSBkZXNjcmliaW5nIHRoZSBhbmNob3IuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCByYW5nZSkge1xuICAgIHRoaXMucm9vdCA9IHJvb3Q7XG4gICAgdGhpcy5yYW5nZSA9IHJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Tm9kZX0gcm9vdCAtICBBIHJvb3QgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGFuY2hvci5cbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgLSAgQSByYW5nZSBkZXNjcmliaW5nIHRoZSBhbmNob3IuXG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJvb3QsIHJhbmdlKSB7XG4gICAgcmV0dXJuIG5ldyBSYW5nZUFuY2hvcihyb290LCByYW5nZSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGFuY2hvciBmcm9tIGEgc2VyaWFsaXplZCBgUmFuZ2VTZWxlY3RvcmAgc2VsZWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdCAtICBBIHJvb3QgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGFuY2hvci5cbiAgICogQHBhcmFtIHtSYW5nZVNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIGNvbnN0IHN0YXJ0Q29udGFpbmVyID0gbm9kZUZyb21YUGF0aChzZWxlY3Rvci5zdGFydENvbnRhaW5lciwgcm9vdCk7XG4gICAgaWYgKCFzdGFydENvbnRhaW5lcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzb2x2ZSBzdGFydENvbnRhaW5lciBYUGF0aCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGVuZENvbnRhaW5lciA9IG5vZGVGcm9tWFBhdGgoc2VsZWN0b3IuZW5kQ29udGFpbmVyLCByb290KTtcbiAgICBpZiAoIWVuZENvbnRhaW5lcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzb2x2ZSBlbmRDb250YWluZXIgWFBhdGgnKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydFBvcyA9IFRleHRQb3NpdGlvbi5mcm9tQ2hhck9mZnNldChcbiAgICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgICAgc2VsZWN0b3Iuc3RhcnRPZmZzZXRcbiAgICApO1xuICAgIGNvbnN0IGVuZFBvcyA9IFRleHRQb3NpdGlvbi5mcm9tQ2hhck9mZnNldChcbiAgICAgIGVuZENvbnRhaW5lcixcbiAgICAgIHNlbGVjdG9yLmVuZE9mZnNldFxuICAgICk7XG5cbiAgICBjb25zdCByYW5nZSA9IG5ldyBUZXh0UmFuZ2Uoc3RhcnRQb3MsIGVuZFBvcykudG9SYW5nZSgpO1xuICAgIHJldHVybiBuZXcgUmFuZ2VBbmNob3Iocm9vdCwgcmFuZ2UpO1xuICB9XG5cbiAgdG9SYW5nZSgpIHtcbiAgICByZXR1cm4gdGhpcy5yYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtSYW5nZVNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICAvLyBcIlNocmlua1wiIHRoZSByYW5nZSBzbyB0aGF0IGl0IHRpZ2h0bHkgd3JhcHMgaXRzIHRleHQuIFRoaXMgZW5zdXJlcyBtb3JlXG4gICAgLy8gcHJlZGljdGFibGUgb3V0cHV0IGZvciBhIGdpdmVuIHRleHQgc2VsZWN0aW9uLlxuICAgIGNvbnN0IG5vcm1hbGl6ZWRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2UodGhpcy5yYW5nZSkudG9SYW5nZSgpO1xuXG4gICAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShub3JtYWxpemVkUmFuZ2UpO1xuICAgIGNvbnN0IHN0YXJ0Q29udGFpbmVyID0geHBhdGhGcm9tTm9kZSh0ZXh0UmFuZ2Uuc3RhcnQuZWxlbWVudCwgdGhpcy5yb290KTtcbiAgICBjb25zdCBlbmRDb250YWluZXIgPSB4cGF0aEZyb21Ob2RlKHRleHRSYW5nZS5lbmQuZWxlbWVudCwgdGhpcy5yb290KTtcblxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnUmFuZ2VTZWxlY3RvcicsXG4gICAgICBzdGFydENvbnRhaW5lcixcbiAgICAgIHN0YXJ0T2Zmc2V0OiB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0LFxuICAgICAgZW5kQ29udGFpbmVyLFxuICAgICAgZW5kT2Zmc2V0OiB0ZXh0UmFuZ2UuZW5kLm9mZnNldCxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgYmV0d2VlbiBgVGV4dFBvc2l0aW9uU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgVGV4dFBvc2l0aW9uQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZFxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgc3RhcnQsIGVuZCkge1xuICAgIHRoaXMucm9vdCA9IHJvb3Q7XG4gICAgdGhpcy5zdGFydCA9IHN0YXJ0O1xuICAgIHRoaXMuZW5kID0gZW5kO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZVxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyb290LCByYW5nZSkge1xuICAgIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2UocmFuZ2UpLnJlbGF0aXZlVG8ocm9vdCk7XG4gICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb25BbmNob3IoXG4gICAgICByb290LFxuICAgICAgdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldCxcbiAgICAgIHRleHRSYW5nZS5lbmQub2Zmc2V0XG4gICAgKTtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9uU2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBzdGF0aWMgZnJvbVNlbGVjdG9yKHJvb3QsIHNlbGVjdG9yKSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb25BbmNob3Iocm9vdCwgc2VsZWN0b3Iuc3RhcnQsIHNlbGVjdG9yLmVuZCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7VGV4dFBvc2l0aW9uU2VsZWN0b3J9XG4gICAqL1xuICB0b1NlbGVjdG9yKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnVGV4dFBvc2l0aW9uU2VsZWN0b3InLFxuICAgICAgc3RhcnQ6IHRoaXMuc3RhcnQsXG4gICAgICBlbmQ6IHRoaXMuZW5kLFxuICAgIH07XG4gIH1cblxuICB0b1JhbmdlKCkge1xuICAgIHJldHVybiBUZXh0UmFuZ2UuZnJvbU9mZnNldHModGhpcy5yb290LCB0aGlzLnN0YXJ0LCB0aGlzLmVuZCkudG9SYW5nZSgpO1xuICB9XG59XG5cbi8qKlxuICogQHR5cGVkZWYgUXVvdGVNYXRjaE9wdGlvbnNcbiAqIEBwcm9wIHtudW1iZXJ9IFtoaW50XSAtIEV4cGVjdGVkIHBvc2l0aW9uIG9mIG1hdGNoIGluIHRleHQuIFNlZSBgbWF0Y2hRdW90ZWAuXG4gKi9cblxuLyoqXG4gKiBDb252ZXJ0cyBiZXR3ZWVuIGBUZXh0UXVvdGVTZWxlY3RvcmAgc2VsZWN0b3JzIGFuZCBgUmFuZ2VgIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UXVvdGVBbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290IC0gQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBleGFjdFxuICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICAgKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5wcmVmaXhdXG4gICAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnN1ZmZpeF1cbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIGV4YWN0LCBjb250ZXh0ID0ge30pIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMuZXhhY3QgPSBleGFjdDtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGBUZXh0UXVvdGVBbmNob3JgIGZyb20gYSByYW5nZS5cbiAgICpcbiAgICogV2lsbCB0aHJvdyBpZiBgcmFuZ2VgIGRvZXMgbm90IGNvbnRhaW4gYW55IHRleHQgbm9kZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZVxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyb290LCByYW5nZSkge1xuICAgIGNvbnN0IHRleHQgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKHJvb3QudGV4dENvbnRlbnQpO1xuICAgIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2UocmFuZ2UpLnJlbGF0aXZlVG8ocm9vdCk7XG5cbiAgICBjb25zdCBzdGFydCA9IHRleHRSYW5nZS5zdGFydC5vZmZzZXQ7XG4gICAgY29uc3QgZW5kID0gdGV4dFJhbmdlLmVuZC5vZmZzZXQ7XG5cbiAgICAvLyBOdW1iZXIgb2YgY2hhcmFjdGVycyBhcm91bmQgdGhlIHF1b3RlIHRvIGNhcHR1cmUgYXMgY29udGV4dC4gV2UgY3VycmVudGx5XG4gICAgLy8gYWx3YXlzIHVzZSBhIGZpeGVkIGFtb3VudCwgYnV0IGl0IHdvdWxkIGJlIGJldHRlciBpZiB0aGlzIGNvZGUgd2FzIGF3YXJlXG4gICAgLy8gb2YgbG9naWNhbCBib3VuZGFyaWVzIGluIHRoZSBkb2N1bWVudCAocGFyYWdyYXBoLCBhcnRpY2xlIGV0Yy4pIHRvIGF2b2lkXG4gICAgLy8gY2FwdHVyaW5nIHRleHQgdW5yZWxhdGVkIHRvIHRoZSBxdW90ZS5cbiAgICAvL1xuICAgIC8vIEluIHJlZ3VsYXIgcHJvc2UgdGhlIGlkZWFsIGNvbnRlbnQgd291bGQgb2Z0ZW4gYmUgdGhlIHN1cnJvdW5kaW5nIHNlbnRlbmNlLlxuICAgIC8vIFRoaXMgaXMgYSBuYXR1cmFsIHVuaXQgb2YgbWVhbmluZyB3aGljaCBlbmFibGVzIGRpc3BsYXlpbmcgcXVvdGVzIGluXG4gICAgLy8gY29udGV4dCBldmVuIHdoZW4gdGhlIGRvY3VtZW50IGlzIG5vdCBhdmFpbGFibGUuIFdlIGNvdWxkIHVzZSBgSW50bC5TZWdtZW50ZXJgXG4gICAgLy8gZm9yIHRoaXMgd2hlbiBhdmFpbGFibGUuXG4gICAgY29uc3QgY29udGV4dExlbiA9IDMyO1xuXG4gICAgcmV0dXJuIG5ldyBUZXh0UXVvdGVBbmNob3Iocm9vdCwgdGV4dC5zbGljZShzdGFydCwgZW5kKSwge1xuICAgICAgcHJlZml4OiB0ZXh0LnNsaWNlKE1hdGgubWF4KDAsIHN0YXJ0IC0gY29udGV4dExlbiksIHN0YXJ0KSxcbiAgICAgIHN1ZmZpeDogdGV4dC5zbGljZShlbmQsIE1hdGgubWluKHRleHQubGVuZ3RoLCBlbmQgKyBjb250ZXh0TGVuKSksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7VGV4dFF1b3RlU2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBzdGF0aWMgZnJvbVNlbGVjdG9yKHJvb3QsIHNlbGVjdG9yKSB7XG4gICAgY29uc3QgeyBwcmVmaXgsIHN1ZmZpeCB9ID0gc2VsZWN0b3I7XG4gICAgcmV0dXJuIG5ldyBUZXh0UXVvdGVBbmNob3Iocm9vdCwgc2VsZWN0b3IuZXhhY3QsIHsgcHJlZml4LCBzdWZmaXggfSk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7VGV4dFF1b3RlU2VsZWN0b3J9XG4gICAqL1xuICB0b1NlbGVjdG9yKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnVGV4dFF1b3RlU2VsZWN0b3InLFxuICAgICAgZXhhY3Q6IHRoaXMuZXhhY3QsXG4gICAgICBwcmVmaXg6IHRoaXMuY29udGV4dC5wcmVmaXgsXG4gICAgICBzdWZmaXg6IHRoaXMuY29udGV4dC5zdWZmaXgsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1b3RlTWF0Y2hPcHRpb25zfSBbb3B0aW9uc11cbiAgICovXG4gIHRvUmFuZ2Uob3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIHRoaXMudG9Qb3NpdGlvbkFuY2hvcihvcHRpb25zKS50b1JhbmdlKCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtRdW90ZU1hdGNoT3B0aW9uc30gW29wdGlvbnNdXG4gICAqL1xuICB0b1Bvc2l0aW9uQW5jaG9yKG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHRleHQgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKHRoaXMucm9vdC50ZXh0Q29udGVudCk7XG4gICAgY29uc3QgbWF0Y2ggPSBtYXRjaFF1b3RlKHRleHQsIHRoaXMuZXhhY3QsIHtcbiAgICAgIC4uLnRoaXMuY29udGV4dCxcbiAgICAgIGhpbnQ6IG9wdGlvbnMuaGludCxcbiAgICB9KTtcbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1F1b3RlIG5vdCBmb3VuZCcpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbkFuY2hvcih0aGlzLnJvb3QsIG1hdGNoLnN0YXJ0LCBtYXRjaC5lbmQpO1xuICB9XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBUZXh0UXVvdGVBbmNob3IgfSBmcm9tIFwiLi92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdHlwZXNcIjtcblxuLy8gQ2F0Y2ggSlMgZXJyb3JzIHRvIGxvZyB0aGVtIGluIHRoZSBhcHAuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJlcnJvclwiLFxuICBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBBbmRyb2lkLmxvZ0Vycm9yKGV2ZW50Lm1lc3NhZ2UsIGV2ZW50LmZpbGVuYW1lLCBldmVudC5saW5lbm8pO1xuICB9LFxuICBmYWxzZVxuKTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwibG9hZFwiLFxuICBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgb25WaWV3cG9ydFdpZHRoQ2hhbmdlZCgpO1xuICAgICAgc25hcEN1cnJlbnRPZmZzZXQoKTtcbiAgICB9KTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHkpO1xuICB9LFxuICBmYWxzZVxuKTtcblxuLyoqXG4gKiBIYXZpbmcgYW4gb2RkIG51bWJlciBvZiBjb2x1bW5zIHdoZW4gZGlzcGxheWluZyB0d28gY29sdW1ucyBwZXIgc2NyZWVuIGNhdXNlcyBzbmFwcGluZyBhbmQgcGFnZVxuICogdHVybmluZyBpc3N1ZXMuIFRvIGZpeCB0aGlzLCB3ZSBpbnNlcnQgYSBibGFuayB2aXJ0dWFsIGNvbHVtbiBhdCB0aGUgZW5kIG9mIHRoZSByZXNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkKCkge1xuICBjb25zdCBpZCA9IFwicmVhZGl1bS12aXJ0dWFsLXBhZ2VcIjtcbiAgdmFyIHZpcnR1YWxDb2wgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gIGlmIChpc1Njcm9sbE1vZGVFbmFibGVkKCkgfHwgZ2V0Q29sdW1uQ291bnRQZXJTY3JlZW4oKSAhPSAyKSB7XG4gICAgaWYgKHZpcnR1YWxDb2wpIHtcbiAgICAgIHZpcnR1YWxDb2wucmVtb3ZlKCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgICB2YXIgY29sQ291bnQgPSBkb2N1bWVudFdpZHRoIC8gcGFnZVdpZHRoO1xuICAgIHZhciBoYXNPZGRDb2xDb3VudCA9IChNYXRoLnJvdW5kKGNvbENvdW50ICogMikgLyAyKSAlIDEgPiAwLjE7XG4gICAgaWYgKGhhc09kZENvbENvdW50KSB7XG4gICAgICBpZiAodmlydHVhbENvbCkge1xuICAgICAgICB2aXJ0dWFsQ29sLnJlbW92ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlydHVhbENvbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgIHZpcnR1YWxDb2wuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuICAgICAgICB2aXJ0dWFsQ29sLnN0eWxlLmJyZWFrQmVmb3JlID0gXCJjb2x1bW5cIjtcbiAgICAgICAgdmlydHVhbENvbC5pbm5lckhUTUwgPSBcIiYjODIwMztcIjsgLy8gemVyby13aWR0aCBzcGFjZVxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHZpcnR1YWxDb2wpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgdmFyIHBhZ2VXaWR0aCA9IDE7XG5cbmZ1bmN0aW9uIG9uVmlld3BvcnRXaWR0aENoYW5nZWQoKSB7XG4gIC8vIFdlIGNhbid0IHJlbHkgb24gd2luZG93LmlubmVyV2lkdGggZm9yIHRoZSBwYWdlV2lkdGggb24gQW5kcm9pZCwgYmVjYXVzZSBpZiB0aGVcbiAgLy8gZGV2aWNlIHBpeGVsIHJhdGlvIGlzIG5vdCBhbiBpbnRlZ2VyLCB3ZSBnZXQgcm91bmRpbmcgaXNzdWVzIG9mZnNldHRpbmcgdGhlIHBhZ2VzLlxuICAvL1xuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3JlYWRpdW0vcmVhZGl1bS1jc3MvaXNzdWVzLzk3XG4gIC8vIGFuZCBodHRwczovL2dpdGh1Yi5jb20vcmVhZGl1bS9yMi1uYXZpZ2F0b3Ita290bGluL2lzc3Vlcy8xNDZcbiAgdmFyIHdpZHRoID0gQW5kcm9pZC5nZXRWaWV3cG9ydFdpZHRoKCk7XG4gIHBhZ2VXaWR0aCA9IHdpZHRoIC8gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gIHNldFByb3BlcnR5KFxuICAgIFwiLS1SU19fdmlld3BvcnRXaWR0aFwiLFxuICAgIFwiY2FsYyhcIiArIHdpZHRoICsgXCJweCAvIFwiICsgd2luZG93LmRldmljZVBpeGVsUmF0aW8gKyBcIilcIlxuICApO1xuXG4gIGFwcGVuZFZpcnR1YWxDb2x1bW5JZk5lZWRlZCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29sdW1uQ291bnRQZXJTY3JlZW4oKSB7XG4gIHJldHVybiBwYXJzZUludChcbiAgICB3aW5kb3dcbiAgICAgIC5nZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudClcbiAgICAgIC5nZXRQcm9wZXJ0eVZhbHVlKFwiY29sdW1uLWNvdW50XCIpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1Njcm9sbE1vZGVFbmFibGVkKCkge1xuICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZTtcbiAgcmV0dXJuIChcbiAgICBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1VU0VSX192aWV3XCIpLnRyaW0oKSA9PSBcInJlYWRpdW0tc2Nyb2xsLW9uXCIgfHxcbiAgICAvLyBGSVhNRTogV2lsbCBuZWVkIHRvIGJlIHJlbW92ZWQgaW4gUmVhZGl1bSAzLjAsIC0tVVNFUl9fc2Nyb2xsIHdhcyBpbmNvcnJlY3QuXG4gICAgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tVVNFUl9fc2Nyb2xsXCIpLnRyaW0oKSA9PSBcInJlYWRpdW0tc2Nyb2xsLW9uXCJcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUlRMKCkge1xuICByZXR1cm4gZG9jdW1lbnQuYm9keS5kaXIudG9Mb3dlckNhc2UoKSA9PSBcInJ0bFwiO1xufVxuXG4vLyBTY3JvbGwgdG8gdGhlIGdpdmVuIFRhZ0lkIGluIGRvY3VtZW50IGFuZCBzbmFwLlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvSWQoaWQpIHtcbiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gIGlmICghZWxlbWVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBzY3JvbGxUb1JlY3QoZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XG59XG5cbi8vIFBvc2l0aW9uIG11c3QgYmUgaW4gdGhlIHJhbmdlIFswIC0gMV0sIDAtMTAwJS5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb1Bvc2l0aW9uKHBvc2l0aW9uKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvUG9zaXRpb24gXCIgKyBwb3NpdGlvbik7XG4gIGlmIChwb3NpdGlvbiA8IDAgfHwgcG9zaXRpb24gPiAxKSB7XG4gICAgdGhyb3cgXCJzY3JvbGxUb1Bvc2l0aW9uKCkgbXVzdCBiZSBnaXZlbiBhIHBvc2l0aW9uIGZyb20gMC4wIHRvICAxLjBcIjtcbiAgfVxuXG4gIGxldCBvZmZzZXQ7XG4gIGlmIChpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICBvZmZzZXQgPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbEhlaWdodCAqIHBvc2l0aW9uO1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gb2Zmc2V0O1xuICAgIC8vIHdpbmRvdy5zY3JvbGxUbygwLCBvZmZzZXQpO1xuICB9IGVsc2Uge1xuICAgIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgICBvZmZzZXQgPSBkb2N1bWVudFdpZHRoICogcG9zaXRpb24gKiBmYWN0b3I7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChvZmZzZXQpO1xuICB9XG59XG5cbi8vIFNjcm9sbHMgdG8gdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGdpdmVuIHRleHQgc25pcHBldC5cbi8vXG4vLyBUaGUgZXhwZWN0ZWQgdGV4dCBhcmd1bWVudCBpcyBhIExvY2F0b3IgVGV4dCBvYmplY3QsIGFzIGRlZmluZWQgaGVyZTpcbi8vIGh0dHBzOi8vcmVhZGl1bS5vcmcvYXJjaGl0ZWN0dXJlL21vZGVscy9sb2NhdG9ycy9cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb1RleHQodGV4dCkge1xuICBsZXQgcmFuZ2UgPSByYW5nZUZyb21Mb2NhdG9yKHsgdGV4dCB9KTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBzY3JvbGxUb1JhbmdlKHJhbmdlKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHNjcm9sbFRvUmFuZ2UocmFuZ2UpIHtcbiAgcmV0dXJuIHNjcm9sbFRvUmVjdChyYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XG59XG5cbmZ1bmN0aW9uIHNjcm9sbFRvUmVjdChyZWN0KSB7XG4gIGlmIChpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9XG4gICAgICByZWN0LnRvcCArIHdpbmRvdy5zY3JvbGxZIC0gd2luZG93LmlubmVySGVpZ2h0IC8gMjtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KFxuICAgICAgcmVjdC5sZWZ0ICsgd2luZG93LnNjcm9sbFhcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb1N0YXJ0KCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb1N0YXJ0XCIpO1xuICBpZiAoIWlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSAwO1xuICAgIHdpbmRvdy5zY3JvbGxUbygwLCAwKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9FbmQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvRW5kXCIpO1xuICBpZiAoIWlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoXG4gICAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoICogZmFjdG9yXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IGRvY3VtZW50LmJvZHkuc2Nyb2xsSGVpZ2h0O1xuICAgIHdpbmRvdy5zY3JvbGxUbygwLCBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCk7XG4gIH1cbn1cblxuLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgcGFnZSBpcyBhbHJlYWR5IGF0IHRoZSBsZWZ0LW1vc3Qgc2Nyb2xsIG9mZnNldC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxMZWZ0KCkge1xuICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gIHZhciBvZmZzZXQgPSB3aW5kb3cuc2Nyb2xsWCAtIHBhZ2VXaWR0aDtcbiAgdmFyIG1pbk9mZnNldCA9IGlzUlRMKCkgPyAtKGRvY3VtZW50V2lkdGggLSBwYWdlV2lkdGgpIDogMDtcbiAgcmV0dXJuIHNjcm9sbFRvT2Zmc2V0KE1hdGgubWF4KG9mZnNldCwgbWluT2Zmc2V0KSk7XG59XG5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2UgaXMgYWxyZWFkeSBhdCB0aGUgcmlnaHQtbW9zdCBzY3JvbGwgb2Zmc2V0LlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFJpZ2h0KCkge1xuICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gIHZhciBvZmZzZXQgPSB3aW5kb3cuc2Nyb2xsWCArIHBhZ2VXaWR0aDtcbiAgdmFyIG1heE9mZnNldCA9IGlzUlRMKCkgPyAwIDogZG9jdW1lbnRXaWR0aCAtIHBhZ2VXaWR0aDtcbiAgcmV0dXJuIHNjcm9sbFRvT2Zmc2V0KE1hdGgubWluKG9mZnNldCwgbWF4T2Zmc2V0KSk7XG59XG5cbi8vIFNjcm9sbHMgdG8gdGhlIGdpdmVuIGxlZnQgb2Zmc2V0LlxuLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgcGFnZSBzY3JvbGwgcG9zaXRpb24gaXMgYWxyZWFkeSBjbG9zZSBlbm91Z2ggdG8gdGhlIGdpdmVuIG9mZnNldC5cbmZ1bmN0aW9uIHNjcm9sbFRvT2Zmc2V0KG9mZnNldCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb09mZnNldCBcIiArIG9mZnNldCk7XG4gIGlmIChpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICB0aHJvdyBcIkNhbGxlZCBzY3JvbGxUb09mZnNldCgpIHdpdGggc2Nyb2xsIG1vZGUgZW5hYmxlZC4gVGhpcyBjYW4gb25seSBiZSB1c2VkIGluIHBhZ2luYXRlZCBtb2RlLlwiO1xuICB9XG5cbiAgdmFyIGN1cnJlbnRPZmZzZXQgPSB3aW5kb3cuc2Nyb2xsWDtcbiAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChvZmZzZXQpO1xuICAvLyBJbiBzb21lIGNhc2UgdGhlIHNjcm9sbFggY2Fubm90IHJlYWNoIHRoZSBwb3NpdGlvbiByZXNwZWN0aW5nIHRvIGlubmVyV2lkdGhcbiAgdmFyIGRpZmYgPSBNYXRoLmFicyhjdXJyZW50T2Zmc2V0IC0gb2Zmc2V0KSAvIHBhZ2VXaWR0aDtcbiAgcmV0dXJuIGRpZmYgPiAwLjAxO1xufVxuXG4vLyBTbmFwIHRoZSBvZmZzZXQgdG8gdGhlIHNjcmVlbiB3aWR0aCAocGFnZSB3aWR0aCkuXG5mdW5jdGlvbiBzbmFwT2Zmc2V0KG9mZnNldCkge1xuICB2YXIgdmFsdWUgPSBvZmZzZXQgKyAoaXNSVEwoKSA/IC0xIDogMSk7XG4gIHJldHVybiB2YWx1ZSAtICh2YWx1ZSAlIHBhZ2VXaWR0aCk7XG59XG5cbi8vIFNuYXBzIHRoZSBjdXJyZW50IG9mZnNldCB0byB0aGUgcGFnZSB3aWR0aC5cbmV4cG9ydCBmdW5jdGlvbiBzbmFwQ3VycmVudE9mZnNldCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic25hcEN1cnJlbnRPZmZzZXRcIik7XG4gIGlmIChpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGN1cnJlbnRPZmZzZXQgPSB3aW5kb3cuc2Nyb2xsWDtcbiAgLy8gQWRkcyBoYWxmIGEgcGFnZSB0byBtYWtlIHN1cmUgd2UgZG9uJ3Qgc25hcCB0byB0aGUgcHJldmlvdXMgcGFnZS5cbiAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gIHZhciBkZWx0YSA9IGZhY3RvciAqIChwYWdlV2lkdGggLyAyKTtcbiAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChjdXJyZW50T2Zmc2V0ICsgZGVsdGEpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2VGcm9tTG9jYXRvcihsb2NhdG9yKSB7XG4gIHRyeSB7XG4gICAgbGV0IGxvY2F0aW9ucyA9IGxvY2F0b3IubG9jYXRpb25zO1xuICAgIGxldCB0ZXh0ID0gbG9jYXRvci50ZXh0O1xuICAgIGlmICh0ZXh0ICYmIHRleHQuaGlnaGxpZ2h0KSB7XG4gICAgICB2YXIgcm9vdDtcbiAgICAgIGlmIChsb2NhdGlvbnMgJiYgbG9jYXRpb25zLmNzc1NlbGVjdG9yKSB7XG4gICAgICAgIHJvb3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGxvY2F0aW9ucy5jc3NTZWxlY3Rvcik7XG4gICAgICB9XG4gICAgICBpZiAoIXJvb3QpIHtcbiAgICAgICAgcm9vdCA9IGRvY3VtZW50LmJvZHk7XG4gICAgICB9XG5cbiAgICAgIGxldCBhbmNob3IgPSBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHRleHQuaGlnaGxpZ2h0LCB7XG4gICAgICAgIHByZWZpeDogdGV4dC5iZWZvcmUsXG4gICAgICAgIHN1ZmZpeDogdGV4dC5hZnRlcixcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFuY2hvci50b1JhbmdlKCk7XG4gICAgfVxuXG4gICAgaWYgKGxvY2F0aW9ucykge1xuICAgICAgdmFyIGVsZW1lbnQgPSBudWxsO1xuXG4gICAgICBpZiAoIWVsZW1lbnQgJiYgbG9jYXRpb25zLmNzc1NlbGVjdG9yKSB7XG4gICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGxvY2F0aW9ucy5jc3NTZWxlY3Rvcik7XG4gICAgICB9XG5cbiAgICAgIGlmICghZWxlbWVudCAmJiBsb2NhdGlvbnMuZnJhZ21lbnRzKSB7XG4gICAgICAgIGZvciAoY29uc3QgaHRtbElkIG9mIGxvY2F0aW9ucy5mcmFnbWVudHMpIHtcbiAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaHRtbElkKTtcbiAgICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIGxldCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0QmVmb3JlKGVsZW1lbnQpO1xuICAgICAgICByYW5nZS5zZXRFbmRBZnRlcihlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIHJhbmdlO1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ0Vycm9yKGUpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8vLyBVc2VyIFNldHRpbmdzLlxuXG5leHBvcnQgZnVuY3Rpb24gc2V0Q1NTUHJvcGVydGllcyhwcm9wZXJ0aWVzKSB7XG4gIGZvciAoY29uc3QgbmFtZSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgc2V0UHJvcGVydHkobmFtZSwgcHJvcGVydGllc1tuYW1lXSk7XG4gIH1cbn1cblxuLy8gRm9yIHNldHRpbmcgdXNlciBzZXR0aW5nLlxuZXhwb3J0IGZ1bmN0aW9uIHNldFByb3BlcnR5KGtleSwgdmFsdWUpIHtcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSBcIlwiKSB7XG4gICAgcmVtb3ZlUHJvcGVydHkoa2V5KTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICAvLyBUaGUgYCFpbXBvcnRhbnRgIGFubm90YXRpb24gaXMgYWRkZWQgd2l0aCBgc2V0UHJvcGVydHkoKWAgYmVjYXVzZSBpZiBpdCdzIHBhcnQgb2YgdGhlXG4gICAgLy8gYHZhbHVlYCwgaXQgd2lsbCBiZSBpZ25vcmVkIGJ5IHRoZSBXZWIgVmlldy5cbiAgICByb290LnN0eWxlLnNldFByb3BlcnR5KGtleSwgdmFsdWUsIFwiaW1wb3J0YW50XCIpO1xuICB9XG59XG5cbi8vIEZvciByZW1vdmluZyB1c2VyIHNldHRpbmcuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlUHJvcGVydHkoa2V5KSB7XG4gIHZhciByb290ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4gIHJvb3Quc3R5bGUucmVtb3ZlUHJvcGVydHkoa2V5KTtcbn1cblxuLy8vIFRvb2xraXRcblxuZXhwb3J0IGZ1bmN0aW9uIGxvZygpIHtcbiAgdmFyIG1lc3NhZ2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLmpvaW4oXCIgXCIpO1xuICBBbmRyb2lkLmxvZyhtZXNzYWdlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvZ0Vycm9yKG1lc3NhZ2UpIHtcbiAgQW5kcm9pZC5sb2dFcnJvcihtZXNzYWdlLCBcIlwiLCAwKTtcbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IGxvZyBhcyBsb2dOYXRpdmUgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCBkZWJ1ZyA9IGZhbHNlO1xuXG4vKipcbiAqIENvbnZlcnRzIGEgRE9NUmVjdCBpbnRvIGEgSlNPTiBvYmplY3QgdW5kZXJzdGFuZGFibGUgYnkgdGhlIG5hdGl2ZSBzaWRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9OYXRpdmVSZWN0KHJlY3QpIHtcbiAgY29uc3QgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBjb25zdCB3aWR0aCA9IHJlY3Qud2lkdGggKiBwaXhlbFJhdGlvO1xuICBjb25zdCBoZWlnaHQgPSByZWN0LmhlaWdodCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IGxlZnQgPSByZWN0LmxlZnQgKiBwaXhlbFJhdGlvO1xuICBjb25zdCB0b3AgPSByZWN0LnRvcCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IHJpZ2h0ID0gbGVmdCArIHdpZHRoO1xuICBjb25zdCBib3R0b20gPSB0b3AgKyBoZWlnaHQ7XG4gIHJldHVybiB7IHdpZHRoLCBoZWlnaHQsIGxlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gIHJhbmdlLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgbGV0IGNsaWVudFJlY3RzID0gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKTtcblxuICBjb25zdCB0b2xlcmFuY2UgPSAxO1xuICBjb25zdCBvcmlnaW5hbFJlY3RzID0gW107XG4gIGZvciAoY29uc3QgcmFuZ2VDbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgb3JpZ2luYWxSZWN0cy5wdXNoKHtcbiAgICAgIGJvdHRvbTogcmFuZ2VDbGllbnRSZWN0LmJvdHRvbSxcbiAgICAgIGhlaWdodDogcmFuZ2VDbGllbnRSZWN0LmhlaWdodCxcbiAgICAgIGxlZnQ6IHJhbmdlQ2xpZW50UmVjdC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5yaWdodCxcbiAgICAgIHRvcDogcmFuZ2VDbGllbnRSZWN0LnRvcCxcbiAgICAgIHdpZHRoOiByYW5nZUNsaWVudFJlY3Qud2lkdGgsXG4gICAgfSk7XG4gIH1cbiAgY29uc3QgbWVyZ2VkUmVjdHMgPSBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gICAgb3JpZ2luYWxSZWN0cyxcbiAgICB0b2xlcmFuY2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICBjb25zdCBub0NvbnRhaW5lZFJlY3RzID0gcmVtb3ZlQ29udGFpbmVkUmVjdHMobWVyZ2VkUmVjdHMsIHRvbGVyYW5jZSk7XG4gIGNvbnN0IG5ld1JlY3RzID0gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhub0NvbnRhaW5lZFJlY3RzKTtcbiAgY29uc3QgbWluQXJlYSA9IDIgKiAyO1xuICBmb3IgKGxldCBqID0gbmV3UmVjdHMubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICBjb25zdCByZWN0ID0gbmV3UmVjdHNbal07XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCAqIHJlY3QuaGVpZ2h0ID4gbWluQXJlYTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgaWYgKG5ld1JlY3RzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgbG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBzbWFsbFwiKTtcbiAgICAgICAgbmV3UmVjdHMuc3BsaWNlKGosIDEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBzbWFsbCwgYnV0IGtlZXAgb3RoZXJ3aXNlIGVtcHR5IVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGxvZyhgQ0xJRU5UIFJFQ1Q6IHJlZHVjZWQgJHtvcmlnaW5hbFJlY3RzLmxlbmd0aH0gLS0+ICR7bmV3UmVjdHMubGVuZ3RofWApO1xuICByZXR1cm4gbmV3UmVjdHM7XG59XG5cbmZ1bmN0aW9uIG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgcmVjdHMsXG4gIHRvbGVyYW5jZSxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCByZWN0cy5sZW5ndGg7IGorKykge1xuICAgICAgY29uc3QgcmVjdDEgPSByZWN0c1tpXTtcbiAgICAgIGNvbnN0IHJlY3QyID0gcmVjdHNbal07XG4gICAgICBpZiAocmVjdDEgPT09IHJlY3QyKSB7XG4gICAgICAgIGxvZyhcIm1lcmdlVG91Y2hpbmdSZWN0cyByZWN0MSA9PT0gcmVjdDIgPz8hXCIpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwVmVydGljYWxseSA9XG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpO1xuICAgICAgY29uc3QgcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0LCB0b2xlcmFuY2UpICYmXG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IGhvcml6b250YWxBbGxvd2VkID0gIWRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHM7XG4gICAgICBjb25zdCBhbGlnbmVkID1cbiAgICAgICAgKHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ICYmIGhvcml6b250YWxBbGxvd2VkKSB8fFxuICAgICAgICAocmVjdHNMaW5lVXBWZXJ0aWNhbGx5ICYmICFyZWN0c0xpbmVVcEhvcml6b250YWxseSk7XG4gICAgICBjb25zdCBjYW5NZXJnZSA9IGFsaWduZWQgJiYgcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSk7XG4gICAgICBpZiAoY2FuTWVyZ2UpIHtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIGBDTElFTlQgUkVDVDogbWVyZ2luZyB0d28gaW50byBvbmUsIFZFUlRJQ0FMOiAke3JlY3RzTGluZVVwVmVydGljYWxseX0gSE9SSVpPTlRBTDogJHtyZWN0c0xpbmVVcEhvcml6b250YWxseX0gKCR7ZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c30pYFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSByZWN0MSAmJiByZWN0ICE9PSByZWN0MjtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcGxhY2VtZW50Q2xpZW50UmVjdCA9IGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpO1xuICAgICAgICBuZXdSZWN0cy5wdXNoKHJlcGxhY2VtZW50Q2xpZW50UmVjdCk7XG4gICAgICAgIHJldHVybiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gICAgICAgICAgbmV3UmVjdHMsXG4gICAgICAgICAgdG9sZXJhbmNlLFxuICAgICAgICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IGxlZnQgPSBNYXRoLm1pbihyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgcmlnaHQgPSBNYXRoLm1heChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCB0b3AgPSBNYXRoLm1pbihyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IGJvdHRvbSA9IE1hdGgubWF4KHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgcmV0dXJuIHtcbiAgICBib3R0b20sXG4gICAgaGVpZ2h0OiBib3R0b20gLSB0b3AsXG4gICAgbGVmdCxcbiAgICByaWdodCxcbiAgICB0b3AsXG4gICAgd2lkdGg6IHJpZ2h0IC0gbGVmdCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlQ29udGFpbmVkUmVjdHMocmVjdHMsIHRvbGVyYW5jZSkge1xuICBjb25zdCByZWN0c1RvS2VlcCA9IG5ldyBTZXQocmVjdHMpO1xuICBmb3IgKGNvbnN0IHJlY3Qgb2YgcmVjdHMpIHtcbiAgICBjb25zdCBiaWdFbm91Z2ggPSByZWN0LndpZHRoID4gMSAmJiByZWN0LmhlaWdodCA+IDE7XG4gICAgaWYgKCFiaWdFbm91Z2gpIHtcbiAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgdGlueVwiKTtcbiAgICAgIHJlY3RzVG9LZWVwLmRlbGV0ZShyZWN0KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHBvc3NpYmx5Q29udGFpbmluZ1JlY3Qgb2YgcmVjdHMpIHtcbiAgICAgIGlmIChyZWN0ID09PSBwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFyZWN0c1RvS2VlcC5oYXMocG9zc2libHlDb250YWluaW5nUmVjdCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdENvbnRhaW5zKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QsIHJlY3QsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgbG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBjb250YWluZWRcIik7XG4gICAgICAgIHJlY3RzVG9LZWVwLmRlbGV0ZShyZWN0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBBcnJheS5mcm9tKHJlY3RzVG9LZWVwKTtcbn1cblxuZnVuY3Rpb24gcmVjdENvbnRhaW5zKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLmxlZnQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5yaWdodCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLmxlZnQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5yaWdodCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWN0Q29udGFpbnNQb2ludChyZWN0LCB4LCB5LCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICAocmVjdC5sZWZ0IDwgeCB8fCBhbG1vc3RFcXVhbChyZWN0LmxlZnQsIHgsIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QucmlnaHQgPiB4IHx8IGFsbW9zdEVxdWFsKHJlY3QucmlnaHQsIHgsIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QudG9wIDwgeSB8fCBhbG1vc3RFcXVhbChyZWN0LnRvcCwgeSwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5ib3R0b20gPiB5IHx8IGFsbW9zdEVxdWFsKHJlY3QuYm90dG9tLCB5LCB0b2xlcmFuY2UpKVxuICApO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKHJlY3RzKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCByZWN0cy5sZW5ndGg7IGorKykge1xuICAgICAgY29uc3QgcmVjdDEgPSByZWN0c1tpXTtcbiAgICAgIGNvbnN0IHJlY3QyID0gcmVjdHNbal07XG4gICAgICBpZiAocmVjdDEgPT09IHJlY3QyKSB7XG4gICAgICAgIGxvZyhcInJlcGxhY2VPdmVybGFwaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIC0xKSkge1xuICAgICAgICBsZXQgdG9BZGQgPSBbXTtcbiAgICAgICAgbGV0IHRvUmVtb3ZlO1xuICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMSA9IHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpO1xuICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMTtcbiAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHN1YnRyYWN0UmVjdHMyID0gcmVjdFN1YnRyYWN0KHJlY3QyLCByZWN0MSk7XG4gICAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA8IHN1YnRyYWN0UmVjdHMyLmxlbmd0aCkge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMTtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czI7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsb2coYENMSUVOVCBSRUNUOiBvdmVybGFwLCBjdXQgb25lIHJlY3QgaW50byAke3RvQWRkLmxlbmd0aH1gKTtcbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gdG9SZW1vdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShuZXdSZWN0cywgdG9BZGQpO1xuICAgICAgICByZXR1cm4gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhuZXdSZWN0cyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gcmVjdFN1YnRyYWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCByZWN0SW50ZXJzZWN0ZWQgPSByZWN0SW50ZXJzZWN0KHJlY3QyLCByZWN0MSk7XG4gIGlmIChyZWN0SW50ZXJzZWN0ZWQuaGVpZ2h0ID09PSAwIHx8IHJlY3RJbnRlcnNlY3RlZC53aWR0aCA9PT0gMCkge1xuICAgIHJldHVybiBbcmVjdDFdO1xuICB9XG4gIGNvbnN0IHJlY3RzID0gW107XG4gIHtcbiAgICBjb25zdCByZWN0QSA9IHtcbiAgICAgIGJvdHRvbTogcmVjdDEuYm90dG9tLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdDEubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0QS53aWR0aCA9IHJlY3RBLnJpZ2h0IC0gcmVjdEEubGVmdDtcbiAgICByZWN0QS5oZWlnaHQgPSByZWN0QS5ib3R0b20gLSByZWN0QS50b3A7XG4gICAgaWYgKHJlY3RBLmhlaWdodCAhPT0gMCAmJiByZWN0QS53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0QSk7XG4gICAgfVxuICB9XG4gIHtcbiAgICBjb25zdCByZWN0QiA9IHtcbiAgICAgIGJvdHRvbTogcmVjdEludGVyc2VjdGVkLnRvcCxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0Qi53aWR0aCA9IHJlY3RCLnJpZ2h0IC0gcmVjdEIubGVmdDtcbiAgICByZWN0Qi5oZWlnaHQgPSByZWN0Qi5ib3R0b20gLSByZWN0Qi50b3A7XG4gICAgaWYgKHJlY3RCLmhlaWdodCAhPT0gMCAmJiByZWN0Qi53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0Qik7XG4gICAgfVxuICB9XG4gIHtcbiAgICBjb25zdCByZWN0QyA9IHtcbiAgICAgIGJvdHRvbTogcmVjdDEuYm90dG9tLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0SW50ZXJzZWN0ZWQuYm90dG9tLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0Qy53aWR0aCA9IHJlY3RDLnJpZ2h0IC0gcmVjdEMubGVmdDtcbiAgICByZWN0Qy5oZWlnaHQgPSByZWN0Qy5ib3R0b20gLSByZWN0Qy50b3A7XG4gICAgaWYgKHJlY3RDLmhlaWdodCAhPT0gMCAmJiByZWN0Qy53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0Qyk7XG4gICAgfVxuICB9XG4gIHtcbiAgICBjb25zdCByZWN0RCA9IHtcbiAgICAgIGJvdHRvbTogcmVjdDEuYm90dG9tLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgcmlnaHQ6IHJlY3QxLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RELndpZHRoID0gcmVjdEQucmlnaHQgLSByZWN0RC5sZWZ0O1xuICAgIHJlY3RELmhlaWdodCA9IHJlY3RELmJvdHRvbSAtIHJlY3RELnRvcDtcbiAgICBpZiAocmVjdEQuaGVpZ2h0ICE9PSAwICYmIHJlY3RELndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3REKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiByZWN0SW50ZXJzZWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCBtYXhMZWZ0ID0gTWF0aC5tYXgocmVjdDEubGVmdCwgcmVjdDIubGVmdCk7XG4gIGNvbnN0IG1pblJpZ2h0ID0gTWF0aC5taW4ocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0KTtcbiAgY29uc3QgbWF4VG9wID0gTWF0aC5tYXgocmVjdDEudG9wLCByZWN0Mi50b3ApO1xuICBjb25zdCBtaW5Cb3R0b20gPSBNYXRoLm1pbihyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSk7XG4gIHJldHVybiB7XG4gICAgYm90dG9tOiBtaW5Cb3R0b20sXG4gICAgaGVpZ2h0OiBNYXRoLm1heCgwLCBtaW5Cb3R0b20gLSBtYXhUb3ApLFxuICAgIGxlZnQ6IG1heExlZnQsXG4gICAgcmlnaHQ6IG1pblJpZ2h0LFxuICAgIHRvcDogbWF4VG9wLFxuICAgIHdpZHRoOiBNYXRoLm1heCgwLCBtaW5SaWdodCAtIG1heExlZnQpLFxuICB9O1xufVxuXG5mdW5jdGlvbiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QxLmxlZnQgPCByZWN0Mi5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIubGVmdCA8IHJlY3QxLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIubGVmdCwgcmVjdDEucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0MS50b3AgPCByZWN0Mi5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLnRvcCA8IHJlY3QxLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLnRvcCwgcmVjdDEuYm90dG9tLCB0b2xlcmFuY2UpKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gYWxtb3N0RXF1YWwoYSwgYiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiBNYXRoLmFicyhhIC0gYikgPD0gdG9sZXJhbmNlO1xufVxuXG5mdW5jdGlvbiBsb2coKSB7XG4gIGlmIChkZWJ1Zykge1xuICAgIGxvZ05hdGl2ZS5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICB9XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQge1xuICBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcCxcbiAgcmVjdENvbnRhaW5zUG9pbnQsXG4gIHRvTmF0aXZlUmVjdCxcbn0gZnJvbSBcIi4vcmVjdFwiO1xuaW1wb3J0IHsgbG9nLCBsb2dFcnJvciwgcmFuZ2VGcm9tTG9jYXRvciB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmxldCBzdHlsZXMgPSBuZXcgTWFwKCk7XG5sZXQgZ3JvdXBzID0gbmV3IE1hcCgpO1xudmFyIGxhc3RHcm91cElkID0gMDtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBsaXN0IG9mIGFkZGl0aW9uYWwgc3VwcG9ydGVkIERlY29yYXRpb24gVGVtcGxhdGVzLlxuICpcbiAqIEVhY2ggdGVtcGxhdGUgb2JqZWN0IGlzIGluZGV4ZWQgYnkgdGhlIHN0eWxlIElELlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJUZW1wbGF0ZXMobmV3U3R5bGVzKSB7XG4gIHZhciBzdHlsZXNoZWV0ID0gXCJcIjtcblxuICBmb3IgKGNvbnN0IFtpZCwgc3R5bGVdIG9mIE9iamVjdC5lbnRyaWVzKG5ld1N0eWxlcykpIHtcbiAgICBzdHlsZXMuc2V0KGlkLCBzdHlsZSk7XG4gICAgaWYgKHN0eWxlLnN0eWxlc2hlZXQpIHtcbiAgICAgIHN0eWxlc2hlZXQgKz0gc3R5bGUuc3R5bGVzaGVldCArIFwiXFxuXCI7XG4gICAgfVxuICB9XG5cbiAgaWYgKHN0eWxlc2hlZXQpIHtcbiAgICBsZXQgc3R5bGVFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgIHN0eWxlRWxlbWVudC5pbm5lckhUTUwgPSBzdHlsZXNoZWV0O1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaGVhZFwiKVswXS5hcHBlbmRDaGlsZChzdHlsZUVsZW1lbnQpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiBEZWNvcmF0aW9uR3JvdXAgZm9yIHRoZSBnaXZlbiBncm91cCBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVjb3JhdGlvbnMoZ3JvdXBOYW1lKSB7XG4gIHZhciBncm91cCA9IGdyb3Vwcy5nZXQoZ3JvdXBOYW1lKTtcbiAgaWYgKCFncm91cCkge1xuICAgIGxldCBpZCA9IFwicjItZGVjb3JhdGlvbi1cIiArIGxhc3RHcm91cElkKys7XG4gICAgZ3JvdXAgPSBEZWNvcmF0aW9uR3JvdXAoaWQsIGdyb3VwTmFtZSk7XG4gICAgZ3JvdXBzLnNldChncm91cE5hbWUsIGdyb3VwKTtcbiAgfVxuICByZXR1cm4gZ3JvdXA7XG59XG5cbi8qKlxuICogSGFuZGxlcyBjbGljayBldmVudHMgb24gYSBEZWNvcmF0aW9uLlxuICogUmV0dXJucyB3aGV0aGVyIGEgZGVjb3JhdGlvbiBtYXRjaGVkIHRoaXMgZXZlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudChldmVudCwgY2xpY2tFdmVudCkge1xuICBpZiAoZ3JvdXBzLnNpemUgPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kVGFyZ2V0KCkge1xuICAgIGZvciAoY29uc3QgW2dyb3VwLCBncm91cENvbnRlbnRdIG9mIGdyb3Vwcykge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGdyb3VwQ29udGVudC5pdGVtcy5yZXZlcnNlKCkpIHtcbiAgICAgICAgaWYgKCFpdGVtLmNsaWNrYWJsZUVsZW1lbnRzKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGl0ZW0uY2xpY2thYmxlRWxlbWVudHMpIHtcbiAgICAgICAgICBsZXQgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9KU09OKCk7XG4gICAgICAgICAgaWYgKHJlY3RDb250YWluc1BvaW50KHJlY3QsIGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIDEpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBncm91cCwgaXRlbSwgZWxlbWVudCwgcmVjdCB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGxldCB0YXJnZXQgPSBmaW5kVGFyZ2V0KCk7XG4gIGlmICghdGFyZ2V0KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIEFuZHJvaWQub25EZWNvcmF0aW9uQWN0aXZhdGVkKFxuICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGlkOiB0YXJnZXQuaXRlbS5kZWNvcmF0aW9uLmlkLFxuICAgICAgZ3JvdXA6IHRhcmdldC5ncm91cCxcbiAgICAgIHJlY3Q6IHRvTmF0aXZlUmVjdCh0YXJnZXQuaXRlbS5yYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSksXG4gICAgICBjbGljazogY2xpY2tFdmVudCxcbiAgICB9KVxuICApO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBEZWNvcmF0aW9uR3JvdXAgb2JqZWN0IGZyb20gYSB1bmlxdWUgSFRNTCBJRCBhbmQgaXRzIG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBEZWNvcmF0aW9uR3JvdXAoZ3JvdXBJZCwgZ3JvdXBOYW1lKSB7XG4gIHZhciBpdGVtcyA9IFtdO1xuICB2YXIgbGFzdEl0ZW1JZCA9IDA7XG4gIHZhciBjb250YWluZXIgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgbmV3IGRlY29yYXRpb24gdG8gdGhlIGdyb3VwLlxuICAgKi9cbiAgZnVuY3Rpb24gYWRkKGRlY29yYXRpb24pIHtcbiAgICBsZXQgaWQgPSBncm91cElkICsgXCItXCIgKyBsYXN0SXRlbUlkKys7XG5cbiAgICBsZXQgcmFuZ2UgPSByYW5nZUZyb21Mb2NhdG9yKGRlY29yYXRpb24ubG9jYXRvcik7XG4gICAgaWYgKCFyYW5nZSkge1xuICAgICAgbG9nKFwiQ2FuJ3QgbG9jYXRlIERPTSByYW5nZSBmb3IgZGVjb3JhdGlvblwiLCBkZWNvcmF0aW9uKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgaXRlbSA9IHsgaWQsIGRlY29yYXRpb24sIHJhbmdlIH07XG4gICAgaXRlbXMucHVzaChpdGVtKTtcbiAgICBsYXlvdXQoaXRlbSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgZGVjb3JhdGlvbiB3aXRoIGdpdmVuIElEIGZyb20gdGhlIGdyb3VwLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVtb3ZlKGRlY29yYXRpb25JZCkge1xuICAgIGxldCBpbmRleCA9IGl0ZW1zLmZpbmRJbmRleCgoaSkgPT4gaS5kZWNvcmF0aW9uLmlkID09PSBkZWNvcmF0aW9uSWQpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgaXRlbSA9IGl0ZW1zW2luZGV4XTtcbiAgICBpdGVtcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIGl0ZW0uY2xpY2thYmxlRWxlbWVudHMgPSBudWxsO1xuICAgIGlmIChpdGVtLmNvbnRhaW5lcikge1xuICAgICAgaXRlbS5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICBpdGVtLmNvbnRhaW5lciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5vdGlmaWVzIHRoYXQgdGhlIGdpdmVuIGRlY29yYXRpb24gd2FzIG1vZGlmaWVkIGFuZCBuZWVkcyB0byBiZSB1cGRhdGVkLlxuICAgKi9cbiAgZnVuY3Rpb24gdXBkYXRlKGRlY29yYXRpb24pIHtcbiAgICByZW1vdmUoZGVjb3JhdGlvbi5pZCk7XG4gICAgYWRkKGRlY29yYXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYWxsIGRlY29yYXRpb25zIGZyb20gdGhpcyBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgIGNsZWFyQ29udGFpbmVyKCk7XG4gICAgaXRlbXMubGVuZ3RoID0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNyZWF0ZXMgdGhlIGRlY29yYXRpb24gZWxlbWVudHMuXG4gICAqXG4gICAqIFRvIGJlIGNhbGxlZCBhZnRlciByZWZsb3dpbmcgdGhlIHJlc291cmNlLCBmb3IgZXhhbXBsZS5cbiAgICovXG4gIGZ1bmN0aW9uIHJlcXVlc3RMYXlvdXQoKSB7XG4gICAgY2xlYXJDb250YWluZXIoKTtcbiAgICBpdGVtcy5mb3JFYWNoKChpdGVtKSA9PiBsYXlvdXQoaXRlbSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExheW91dHMgYSBzaW5nbGUgRGVjb3JhdGlvbiBpdGVtLlxuICAgKi9cbiAgZnVuY3Rpb24gbGF5b3V0KGl0ZW0pIHtcbiAgICBsZXQgZ3JvdXBDb250YWluZXIgPSByZXF1aXJlQ29udGFpbmVyKCk7XG5cbiAgICBsZXQgc3R5bGUgPSBzdHlsZXMuZ2V0KGl0ZW0uZGVjb3JhdGlvbi5zdHlsZSk7XG4gICAgaWYgKCFzdHlsZSkge1xuICAgICAgbG9nRXJyb3IoYFVua25vd24gZGVjb3JhdGlvbiBzdHlsZTogJHtpdGVtLmRlY29yYXRpb24uc3R5bGV9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW1Db250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIGl0ZW1Db250YWluZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgaXRlbS5pZCk7XG4gICAgaXRlbUNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJkYXRhLXN0eWxlXCIsIGl0ZW0uZGVjb3JhdGlvbi5zdHlsZSk7XG4gICAgaXRlbUNvbnRhaW5lci5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcblxuICAgIGxldCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgbGV0IGNvbHVtbkNvdW50ID0gcGFyc2VJbnQoXG4gICAgICBnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuZ2V0UHJvcGVydHlWYWx1ZShcbiAgICAgICAgXCJjb2x1bW4tY291bnRcIlxuICAgICAgKVxuICAgICk7XG4gICAgbGV0IHBhZ2VXaWR0aCA9IHZpZXdwb3J0V2lkdGggLyAoY29sdW1uQ291bnQgfHwgMSk7XG4gICAgbGV0IHNjcm9sbGluZ0VsZW1lbnQgPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50O1xuICAgIGxldCB4T2Zmc2V0ID0gc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIGxldCB5T2Zmc2V0ID0gc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3A7XG5cbiAgICBmdW5jdGlvbiBwb3NpdGlvbkVsZW1lbnQoZWxlbWVudCwgcmVjdCwgYm91bmRpbmdSZWN0KSB7XG4gICAgICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuXG4gICAgICBpZiAoc3R5bGUud2lkdGggPT09IFwid3JhcFwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtyZWN0LndpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke3JlY3QubGVmdCArIHhPZmZzZXR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3JlY3QudG9wICsgeU9mZnNldH1weGA7XG4gICAgICB9IGVsc2UgaWYgKHN0eWxlLndpZHRoID09PSBcInZpZXdwb3J0XCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke3ZpZXdwb3J0V2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgbGV0IGxlZnQgPSBNYXRoLmZsb29yKHJlY3QubGVmdCAvIHZpZXdwb3J0V2lkdGgpICogdmlld3BvcnRXaWR0aDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7bGVmdCArIHhPZmZzZXR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3JlY3QudG9wICsgeU9mZnNldH1weGA7XG4gICAgICB9IGVsc2UgaWYgKHN0eWxlLndpZHRoID09PSBcImJvdW5kc1wiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtib3VuZGluZ1JlY3Qud2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7Ym91bmRpbmdSZWN0LmxlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJwYWdlXCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke3BhZ2VXaWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBsZXQgbGVmdCA9IE1hdGguZmxvb3IocmVjdC5sZWZ0IC8gcGFnZVdpZHRoKSAqIHBhZ2VXaWR0aDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7bGVmdCArIHhPZmZzZXR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3JlY3QudG9wICsgeU9mZnNldH1weGA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGJvdW5kaW5nUmVjdCA9IGl0ZW0ucmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBsZXQgZWxlbWVudFRlbXBsYXRlO1xuICAgIHRyeSB7XG4gICAgICBsZXQgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gICAgICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBpdGVtLmRlY29yYXRpb24uZWxlbWVudC50cmltKCk7XG4gICAgICBlbGVtZW50VGVtcGxhdGUgPSB0ZW1wbGF0ZS5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dFcnJvcihcbiAgICAgICAgYEludmFsaWQgZGVjb3JhdGlvbiBlbGVtZW50IFwiJHtpdGVtLmRlY29yYXRpb24uZWxlbWVudH1cIjogJHtlcnJvci5tZXNzYWdlfWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHN0eWxlLmxheW91dCA9PT0gXCJib3hlc1wiKSB7XG4gICAgICBsZXQgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cyA9IHRydWU7XG4gICAgICBsZXQgY2xpZW50UmVjdHMgPSBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgICAgICAgaXRlbS5yYW5nZSxcbiAgICAgICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICAgICAgKTtcblxuICAgICAgY2xpZW50UmVjdHMgPSBjbGllbnRSZWN0cy5zb3J0KChyMSwgcjIpID0+IHtcbiAgICAgICAgaWYgKHIxLnRvcCA8IHIyLnRvcCkge1xuICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfSBlbHNlIGlmIChyMS50b3AgPiByMi50b3ApIHtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGZvciAobGV0IGNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICAgICAgY29uc3QgbGluZSA9IGVsZW1lbnRUZW1wbGF0ZS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICAgIGxpbmUuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICAgIHBvc2l0aW9uRWxlbWVudChsaW5lLCBjbGllbnRSZWN0LCBib3VuZGluZ1JlY3QpO1xuICAgICAgICBpdGVtQ29udGFpbmVyLmFwcGVuZChsaW5lKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHN0eWxlLmxheW91dCA9PT0gXCJib3VuZHNcIikge1xuICAgICAgY29uc3QgYm91bmRzID0gZWxlbWVudFRlbXBsYXRlLmNsb25lTm9kZSh0cnVlKTtcbiAgICAgIGJvdW5kcy5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgIHBvc2l0aW9uRWxlbWVudChib3VuZHMsIGJvdW5kaW5nUmVjdCwgYm91bmRpbmdSZWN0KTtcblxuICAgICAgaXRlbUNvbnRhaW5lci5hcHBlbmQoYm91bmRzKTtcbiAgICB9XG5cbiAgICBncm91cENvbnRhaW5lci5hcHBlbmQoaXRlbUNvbnRhaW5lcik7XG4gICAgaXRlbS5jb250YWluZXIgPSBpdGVtQ29udGFpbmVyO1xuICAgIGl0ZW0uY2xpY2thYmxlRWxlbWVudHMgPSBBcnJheS5mcm9tKFxuICAgICAgaXRlbUNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtYWN0aXZhYmxlPScxJ11cIilcbiAgICApO1xuICAgIGlmIChpdGVtLmNsaWNrYWJsZUVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaXRlbS5jbGlja2FibGVFbGVtZW50cyA9IEFycmF5LmZyb20oaXRlbUNvbnRhaW5lci5jaGlsZHJlbik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGdyb3VwIGNvbnRhaW5lciBlbGVtZW50LCBhZnRlciBtYWtpbmcgc3VyZSBpdCBleGlzdHMuXG4gICAqL1xuICBmdW5jdGlvbiByZXF1aXJlQ29udGFpbmVyKCkge1xuICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgY29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIGdyb3VwSWQpO1xuICAgICAgY29udGFpbmVyLnNldEF0dHJpYnV0ZShcImRhdGEtZ3JvdXBcIiwgZ3JvdXBOYW1lKTtcbiAgICAgIGNvbnRhaW5lci5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKGNvbnRhaW5lcik7XG4gICAgfVxuICAgIHJldHVybiBjb250YWluZXI7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgZ3JvdXAgY29udGFpbmVyLlxuICAgKi9cbiAgZnVuY3Rpb24gY2xlYXJDb250YWluZXIoKSB7XG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgY29udGFpbmVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBhZGQsIHJlbW92ZSwgdXBkYXRlLCBjbGVhciwgaXRlbXMsIHJlcXVlc3RMYXlvdXQgfTtcbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwibG9hZFwiLFxuICBmdW5jdGlvbiAoKSB7XG4gICAgLy8gV2lsbCByZWxheW91dCBhbGwgdGhlIGRlY29yYXRpb25zIHdoZW4gdGhlIGRvY3VtZW50IGJvZHkgaXMgcmVzaXplZC5cbiAgICBjb25zdCBib2R5ID0gZG9jdW1lbnQuYm9keTtcbiAgICB2YXIgbGFzdFNpemUgPSB7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfTtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGxhc3RTaXplLndpZHRoID09PSBib2R5LmNsaWVudFdpZHRoICYmXG4gICAgICAgIGxhc3RTaXplLmhlaWdodCA9PT0gYm9keS5jbGllbnRIZWlnaHRcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsYXN0U2l6ZSA9IHtcbiAgICAgICAgd2lkdGg6IGJvZHkuY2xpZW50V2lkdGgsXG4gICAgICAgIGhlaWdodDogYm9keS5jbGllbnRIZWlnaHQsXG4gICAgICB9O1xuXG4gICAgICBncm91cHMuZm9yRWFjaChmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgZ3JvdXAucmVxdWVzdExheW91dCgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShib2R5KTtcbiAgfSxcbiAgZmFsc2Vcbik7XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIG9uQ2xpY2ssIGZhbHNlKTtcbiAgYmluZERyYWdHZXN0dXJlKGRvY3VtZW50KTtcbn0pO1xuXG5mdW5jdGlvbiBvbkNsaWNrKGV2ZW50KSB7XG4gIGlmICghd2luZG93LmdldFNlbGVjdGlvbigpLmlzQ29sbGFwc2VkKSB7XG4gICAgLy8gVGhlcmUncyBhbiBvbi1nb2luZyBzZWxlY3Rpb24sIHRoZSB0YXAgd2lsbCBkaXNtaXNzIGl0IHNvIHdlIGRvbid0IGZvcndhcmQgaXQuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgbGV0IGNsaWNrRXZlbnQgPSB7XG4gICAgZGVmYXVsdFByZXZlbnRlZDogZXZlbnQuZGVmYXVsdFByZXZlbnRlZCxcbiAgICB4OiBldmVudC5jbGllbnRYICogcGl4ZWxSYXRpbyxcbiAgICB5OiBldmVudC5jbGllbnRZICogcGl4ZWxSYXRpbyxcbiAgICB0YXJnZXRFbGVtZW50OiBldmVudC50YXJnZXQub3V0ZXJIVE1MLFxuICAgIGludGVyYWN0aXZlRWxlbWVudDogbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChldmVudC50YXJnZXQpLFxuICB9O1xuXG4gIGlmIChoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudChldmVudCwgY2xpY2tFdmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBTZW5kIHRoZSB0YXAgZGF0YSBvdmVyIHRoZSBKUyBicmlkZ2UgZXZlbiBpZiBpdCdzIGJlZW4gaGFuZGxlZCB3aXRoaW4gdGhlIHdlYiB2aWV3LCBzbyB0aGF0XG4gIC8vIGl0IGNhbiBiZSBwcmVzZXJ2ZWQgYW5kIHVzZWQgYnkgdGhlIHRvb2xraXQgaWYgbmVlZGVkLlxuICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uVGFwKEpTT04uc3RyaW5naWZ5KGNsaWNrRXZlbnQpKTtcblxuICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJpbmREcmFnR2VzdHVyZShlbGVtZW50KSB7XG4gIC8vIHBhc3NpdmU6IGZhbHNlIGlzIG5lY2Vzc2FyeSB0byBiZSBhYmxlIHRvIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IuXG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIiwgb25TdGFydCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgb25FbmQsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCBvbk1vdmUsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG5cbiAgdmFyIHN0YXRlID0gdW5kZWZpbmVkO1xuICB2YXIgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgY29uc3QgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuXG4gIGZ1bmN0aW9uIG9uU3RhcnQoZXZlbnQpIHtcbiAgICBpc1N0YXJ0aW5nRHJhZyA9IHRydWU7XG5cbiAgICBjb25zdCBzdGFydFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIGNvbnN0IHN0YXJ0WSA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUgPSB7XG4gICAgICBkZWZhdWx0UHJldmVudGVkOiBldmVudC5kZWZhdWx0UHJldmVudGVkLFxuICAgICAgc3RhcnRYOiBzdGFydFgsXG4gICAgICBzdGFydFk6IHN0YXJ0WSxcbiAgICAgIGN1cnJlbnRYOiBzdGFydFgsXG4gICAgICBjdXJyZW50WTogc3RhcnRZLFxuICAgICAgb2Zmc2V0WDogMCxcbiAgICAgIG9mZnNldFk6IDAsXG4gICAgICBpbnRlcmFjdGl2ZUVsZW1lbnQ6IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSxcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gb25Nb3ZlKGV2ZW50KSB7XG4gICAgaWYgKCFzdGF0ZSkgcmV0dXJuO1xuXG4gICAgc3RhdGUuY3VycmVudFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlLmN1cnJlbnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZS5vZmZzZXRYID0gc3RhdGUuY3VycmVudFggLSBzdGF0ZS5zdGFydFg7XG4gICAgc3RhdGUub2Zmc2V0WSA9IHN0YXRlLmN1cnJlbnRZIC0gc3RhdGUuc3RhcnRZO1xuXG4gICAgdmFyIHNob3VsZFByZXZlbnREZWZhdWx0ID0gZmFsc2U7XG4gICAgLy8gV2FpdCBmb3IgYSBtb3ZlbWVudCBvZiBhdCBsZWFzdCA2IHBpeGVscyBiZWZvcmUgcmVwb3J0aW5nIGEgZHJhZy5cbiAgICBpZiAoaXNTdGFydGluZ0RyYWcpIHtcbiAgICAgIGlmIChNYXRoLmFicyhzdGF0ZS5vZmZzZXRYKSA+PSA2IHx8IE1hdGguYWJzKHN0YXRlLm9mZnNldFkpID49IDYpIHtcbiAgICAgICAgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgICAgICAgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ1N0YXJ0KEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdNb3ZlKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25FbmQoZXZlbnQpIHtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG5cbiAgICBjb25zdCBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnRW5kKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHN0YXRlID0gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8vIFNlZS4gaHR0cHM6Ly9naXRodWIuY29tL0pheVBhbm96L2FyY2hpdGVjdHVyZS90cmVlL3RvdWNoLWhhbmRsaW5nL21pc2MvdG91Y2gtaGFuZGxpbmdcbmZ1bmN0aW9uIG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZWxlbWVudCkge1xuICB2YXIgaW50ZXJhY3RpdmVUYWdzID0gW1xuICAgIFwiYVwiLFxuICAgIFwiYXVkaW9cIixcbiAgICBcImJ1dHRvblwiLFxuICAgIFwiY2FudmFzXCIsXG4gICAgXCJkZXRhaWxzXCIsXG4gICAgXCJpbnB1dFwiLFxuICAgIFwibGFiZWxcIixcbiAgICBcIm9wdGlvblwiLFxuICAgIFwic2VsZWN0XCIsXG4gICAgXCJzdWJtaXRcIixcbiAgICBcInRleHRhcmVhXCIsXG4gICAgXCJ2aWRlb1wiLFxuICBdO1xuICBpZiAoaW50ZXJhY3RpdmVUYWdzLmluZGV4T2YoZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSAhPSAtMSkge1xuICAgIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgfVxuXG4gIC8vIENoZWNrcyB3aGV0aGVyIHRoZSBlbGVtZW50IGlzIGVkaXRhYmxlIGJ5IHRoZSB1c2VyLlxuICBpZiAoXG4gICAgZWxlbWVudC5oYXNBdHRyaWJ1dGUoXCJjb250ZW50ZWRpdGFibGVcIikgJiZcbiAgICBlbGVtZW50LmdldEF0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKS50b0xvd2VyQ2FzZSgpICE9IFwiZmFsc2VcIlxuICApIHtcbiAgICByZXR1cm4gZWxlbWVudC5vdXRlckhUTUw7XG4gIH1cblxuICAvLyBDaGVja3MgcGFyZW50cyByZWN1cnNpdmVseSBiZWNhdXNlIHRoZSB0b3VjaCBtaWdodCBiZSBmb3IgZXhhbXBsZSBvbiBhbiA8ZW0+IGluc2lkZSBhIDxhPi5cbiAgaWYgKGVsZW1lbnQucGFyZW50RWxlbWVudCkge1xuICAgIHJldHVybiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQucGFyZW50RWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlICovXG4vL1xuLy8gIGhpZ2hsaWdodC5qc1xuLy8gIHIyLW5hdmlnYXRvci1rb3RsaW5cbi8vXG4vLyAgT3JnYW5pemVkIGJ5IFRhZWh5dW4gS2ltIG9uIDYvMjcvMTkgZnJvbSByMi1uYXZpZ2F0b3ItanMuXG4vL1xuLy8gIENvcHlyaWdodCAyMDE5IFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHdoaWNoIGlzIGRldGFpbGVkXG4vLyAgaW4gdGhlIExJQ0VOU0UgZmlsZSBwcmVzZW50IGluIHRoZSBwcm9qZWN0IHJlcG9zaXRvcnkgd2hlcmUgdGhpcyBzb3VyY2UgY29kZSBpcyBtYWludGFpbmVkLlxuLy9cblxuY29uc3QgUk9PVF9DTEFTU19SRURVQ0VfTU9USU9OID0gXCJyMi1yZWR1Y2UtbW90aW9uXCI7XG5jb25zdCBST09UX0NMQVNTX05PX0ZPT1ROT1RFUyA9IFwicjItbm8tcG9wdXAtZm9vbm90ZXNcIjtcbmNvbnN0IFBPUFVQX0RJQUxPR19DTEFTUyA9IFwicjItcG9wdXAtZGlhbG9nXCI7XG5jb25zdCBGT09UTk9URVNfQ09OVEFJTkVSX0NMQVNTID0gXCJyMi1mb290bm90ZS1jb250YWluZXJcIjtcbmNvbnN0IEZPT1ROT1RFU19DTE9TRV9CVVRUT05fQ0xBU1MgPSBcInIyLWZvb3Rub3RlLWNsb3NlXCI7XG5jb25zdCBGT09UTk9URV9GT1JDRV9TSE9XID0gXCJyMi1mb290bm90ZS1mb3JjZS1zaG93XCI7XG5jb25zdCBUVFNfSURfUFJFVklPVVMgPSBcInIyLXR0cy1wcmV2aW91c1wiO1xuY29uc3QgVFRTX0lEX05FWFQgPSBcInIyLXR0cy1uZXh0XCI7XG5jb25zdCBUVFNfSURfU0xJREVSID0gXCJyMi10dHMtc2xpZGVyXCI7XG5jb25zdCBUVFNfSURfQUNUSVZFX1dPUkQgPSBcInIyLXR0cy1hY3RpdmUtd29yZFwiO1xuY29uc3QgVFRTX0lEX0NPTlRBSU5FUiA9IFwicjItdHRzLXR4dFwiO1xuY29uc3QgVFRTX0lEX0lORk8gPSBcInIyLXR0cy1pbmZvXCI7XG5jb25zdCBUVFNfTkFWX0JVVFRPTl9DTEFTUyA9IFwicjItdHRzLWJ1dHRvblwiO1xuY29uc3QgVFRTX0lEX1NQRUFLSU5HX0RPQ19FTEVNRU5UID0gXCJyMi10dHMtc3BlYWtpbmctZWxcIjtcbmNvbnN0IFRUU19DTEFTU19JTkpFQ1RFRF9TUEFOID0gXCJyMi10dHMtc3BlYWtpbmctdHh0XCI7XG5jb25zdCBUVFNfQ0xBU1NfSU5KRUNURURfU1VCU1BBTiA9IFwicjItdHRzLXNwZWFraW5nLXdvcmRcIjtcbmNvbnN0IFRUU19JRF9JTkpFQ1RFRF9QQVJFTlQgPSBcInIyLXR0cy1zcGVha2luZy10eHQtcGFyZW50XCI7XG5jb25zdCBJRF9ISUdITElHSFRTX0NPTlRBSU5FUiA9IFwiUjJfSURfSElHSExJR0hUU19DT05UQUlORVJcIjtcbmNvbnN0IElEX0FOTk9UQVRJT05fQ09OVEFJTkVSID0gXCJSMl9JRF9BTk5PVEFUSU9OX0NPTlRBSU5FUlwiO1xuY29uc3QgQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUiA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUlwiO1xuY29uc3QgQ0xBU1NfQU5OT1RBVElPTl9DT05UQUlORVIgPSBcIlIyX0NMQVNTX0FOTk9UQVRJT05fQ09OVEFJTkVSXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQVJFQSA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0FSRUFcIjtcbmNvbnN0IENMQVNTX0FOTk9UQVRJT05fQVJFQSA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9BUkVBXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUFcIjtcbmNvbnN0IENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQSA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBXCI7XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG5jb25zdCBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSA9IFtcbiAgUE9QVVBfRElBTE9HX0NMQVNTLFxuICBUVFNfQ0xBU1NfSU5KRUNURURfU1BBTixcbiAgVFRTX0NMQVNTX0lOSkVDVEVEX1NVQlNQQU4sXG4gIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSLFxuICBDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSLFxuICBDTEFTU19ISUdITElHSFRfQVJFQSxcbiAgQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEsXG4gIFwicmVzaXplLXNlbnNvclwiLFxuXTtcbmNvbnN0IENMQVNTX1BBR0lOQVRFRCA9IFwicjItY3NzLXBhZ2luYXRlZFwiO1xuXG4vL2NvbnN0IElTX0RFViA9IChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJkZXZlbG9wbWVudFwiIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcImRldlwiKTtcbmNvbnN0IElTX0RFViA9IGZhbHNlO1xuY29uc3QgX2hpZ2hsaWdodHMgPSBbXTtcblxubGV0IF9oaWdobGlnaHRzQ29udGFpbmVyO1xubGV0IF9hbm5vdGF0aW9uQ29udGFpbmVyO1xubGV0IGxhc3RNb3VzZURvd25YID0gLTE7XG5sZXQgbGFzdE1vdXNlRG93blkgPSAtMTtcbmxldCBib2R5RXZlbnRMaXN0ZW5lcnNTZXQgPSBmYWxzZTtcblxuY29uc3QgVVNFX1NWRyA9IGZhbHNlO1xuY29uc3QgREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkgPSAwLjM7XG5jb25zdCBBTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZID0gMC40NTtcblxuLy9jb25zdCBERUJVR19WSVNVQUxTID0gZmFsc2U7XG5jb25zdCBERUJVR19WSVNVQUxTID0gZmFsc2U7XG5jb25zdCBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IgPSB7XG4gIGJsdWU6IDEwMCxcbiAgZ3JlZW46IDUwLFxuICByZWQ6IDIzMCxcbn07XG5cbmNvbnN0IEFOTk9UQVRJT05fV0lEVEggPSAxNTtcblxuZnVuY3Rpb24gcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKF93aW4sIGhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gIGlmIChcbiAgICBoaWdobGlnaHRCb3VuZGluZy5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSA9PSBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcbiAgKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLm91dGxpbmUgPSBcIm5vbmVcIjtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCIsXG4gICAgXCJ0cmFuc3BhcmVudFwiLFxuICAgIFwiaW1wb3J0YW50XCJcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYXMsIGhpZ2hsaWdodCkge1xuICBjb25zdCB1c2VTVkcgPSAhREVCVUdfVklTVUFMUyAmJiBVU0VfU1ZHO1xuICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgaGlnaGxpZ2h0QXJlYXMpIHtcbiAgICBjb25zdCBpc1NWRyA9IHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhLm5hbWVzcGFjZVVSSSA9PT0gU1ZHX1hNTF9OQU1FU1BBQ0U7XG4gICAgY29uc3Qgb3BhY2l0eSA9IEFMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFk7XG4gICAgaWYgKGlzU1ZHKSB7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImZpbGxcIixcbiAgICAgICAgYHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImZpbGwtb3BhY2l0eVwiLFxuICAgICAgICBgJHtvcGFjaXR5fWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcInN0cm9rZVwiLFxuICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwic3Ryb2tlLW9wYWNpdHlcIixcbiAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIixcbiAgICAgICAgYHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSlgLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpIHtcbiAgY29uc3QgdXNlU1ZHID0gIURFQlVHX1ZJU1VBTFMgJiYgVVNFX1NWRztcbiAgLy9jb25zdCB1c2VTVkcgPSBVU0VfU1ZHO1xuICBjb25zdCBpc1NWRyA9IHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhLm5hbWVzcGFjZVVSSSA9PT0gU1ZHX1hNTF9OQU1FU1BBQ0U7XG4gIGNvbnN0IGlkID0gaXNTVkdcbiAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlXG4gICAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImlkXCIpXG4gICAgICA6IHVuZGVmaW5lZFxuICAgIDogaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlXG4gICAgPyBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKFwiaWRcIilcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKGlkKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCkgPT4ge1xuICAgICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICAgIH0pO1xuICAgIGlmIChoaWdobGlnaHQpIHtcbiAgICAgIGNvbnN0IG9wYWNpdHkgPSBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWTtcbiAgICAgIGlmIChpc1NWRykge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiZmlsbFwiLFxuICAgICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcImZpbGwtb3BhY2l0eVwiLFxuICAgICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJzdHJva2VcIixcbiAgICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiLFxuICAgICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiLFxuICAgICAgICAgIGByZ2JhKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0sICR7b3BhY2l0eX0pYCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwcm9jZXNzVG91Y2hFdmVudCh3aW4sIGV2KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHggPSBldi5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRYO1xuICBjb25zdCB5ID0gZXYuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WTtcbiAgaWYgKCFfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBwYWdpbmF0ZWQgPSBpc1BhZ2luYXRlZChkb2N1bWVudCk7XG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgbGV0IHhPZmZzZXQ7XG4gIGxldCB5T2Zmc2V0O1xuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0IDogYm9keVJlY3QubGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiBib2R5UmVjdC50b3A7XG4gIH1cbiAgbGV0IGZvdW5kSGlnaGxpZ2h0O1xuICBsZXQgZm91bmRFbGVtZW50O1xuICBsZXQgZm91bmRSZWN0O1xuICAvLyAgICBfaGlnaGxpZ2h0cy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgLy8gICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGEuc2VsZWN0aW9uSW5mbykpXG4gIC8vICAgICAgICByZXR1cm4gYS5zZWxlY3Rpb25JbmZvLmNsZWFuVGV4dC5sZW5ndGggPCBiLnNlbGVjdGlvbkluZm8uY2xlYW5UZXh0Lmxlbmd0aFxuICAvLyAgICB9KVxuICBmb3IgKGxldCBpID0gX2hpZ2hsaWdodHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0c1tpXTtcbiAgICBsZXQgaGlnaGxpZ2h0UGFyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYCR7aGlnaGxpZ2h0LmlkfWApO1xuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBoaWdobGlnaHRQYXJlbnQgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGAjJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgfVxuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbGV0IGhpdCA9IGZhbHNlO1xuICAgIGNvbnN0IGhpZ2hsaWdodEZyYWdtZW50cyA9IGhpZ2hsaWdodFBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnQgb2YgaGlnaGxpZ2h0RnJhZ21lbnRzKSB7XG4gICAgICBjb25zdCB3aXRoUmVjdCA9IGhpZ2hsaWdodEZyYWdtZW50O1xuICAgICAgY29uc3QgbGVmdCA9IHdpdGhSZWN0LnJlY3QubGVmdCArIHhPZmZzZXQ7XG4gICAgICBjb25zdCB0b3AgPSB3aXRoUmVjdC5yZWN0LnRvcCArIHlPZmZzZXQ7XG4gICAgICBmb3VuZFJlY3QgPSB3aXRoUmVjdC5yZWN0O1xuICAgICAgaWYgKFxuICAgICAgICB4ID49IGxlZnQgJiZcbiAgICAgICAgeCA8IGxlZnQgKyB3aXRoUmVjdC5yZWN0LndpZHRoICYmXG4gICAgICAgIHkgPj0gdG9wICYmXG4gICAgICAgIHkgPCB0b3AgKyB3aXRoUmVjdC5yZWN0LmhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIGhpdCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaGl0KSB7XG4gICAgICBmb3VuZEhpZ2hsaWdodCA9IGhpZ2hsaWdodDtcbiAgICAgIGZvdW5kRWxlbWVudCA9IGhpZ2hsaWdodFBhcmVudDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoIWZvdW5kSGlnaGxpZ2h0IHx8ICFmb3VuZEVsZW1lbnQpIHtcbiAgICBjb25zdCBoaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgaGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgfVxuICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmb3VuZEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jbGlja1wiKSkge1xuICAgIGlmIChldi50eXBlID09PSBcIm1vdXNlbW92ZVwiKSB7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICAgIGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLmluZGV4T2YoaGlnaGxpZ2h0QXJlYSkgPCAwKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMsIGZvdW5kSGlnaGxpZ2h0KTtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nID0gZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGFsbEhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIHx8XG4gICAgICAgICAgaGlnaGxpZ2h0Qm91bmRpbmcgIT09IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nXG4gICAgICAgICkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gICAgICAgIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgICAgICAgc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZShcbiAgICAgICAgICAgIHdpbixcbiAgICAgICAgICAgIGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nLFxuICAgICAgICAgICAgZm91bmRIaWdobGlnaHRcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChldi50eXBlID09PSBcInRvdWNoc3RhcnRcIiB8fCBldi50eXBlID09PSBcInRvdWNoZW5kXCIpIHtcbiAgICAgIGNvbnN0IHNpemUgPSB7XG4gICAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cub3V0ZXJIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGZvdW5kUmVjdC5sZWZ0LFxuICAgICAgICB3aWR0aDogZm91bmRSZWN0LndpZHRoLFxuICAgICAgICB0b3A6IGZvdW5kUmVjdC50b3AsXG4gICAgICAgIGhlaWdodDogZm91bmRSZWN0LmhlaWdodCxcbiAgICAgIH07XG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBoaWdobGlnaHQ6IGZvdW5kSGlnaGxpZ2h0LmlkLFxuICAgICAgICBzaXplOiBzaXplLFxuICAgICAgfTtcblxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgIHR5cGVvZiB3aW5kb3cucHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICB3aW5kb3cucHJvY2Vzcy50eXBlID09PSBcInJlbmRlcmVyXCJcbiAgICAgICkge1xuICAgICAgICBlbGVjdHJvbl8xLmlwY1JlbmRlcmVyLnNlbmRUb0hvc3QoUjJfRVZFTlRfSElHSExJR0hUX0NMSUNLLCBwYXlsb2FkKTtcbiAgICAgIH0gZWxzZSBpZiAod2luZG93LndlYmtpdFVSTCkge1xuICAgICAgICBjb25zb2xlLmxvZyhmb3VuZEhpZ2hsaWdodC5pZC5pbmNsdWRlcyhcIlIyX0FOTk9UQVRJT05fXCIpKTtcbiAgICAgICAgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0FOTk9UQVRJT05fXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfSElHSExJR0hUX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHggPSBldi5jbGllbnRYO1xuICBjb25zdCB5ID0gZXYuY2xpZW50WTtcbiAgaWYgKCFfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeE9mZnNldDtcbiAgbGV0IHlPZmZzZXQ7XG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBib2R5UmVjdC5sZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICBsZXQgZm91bmRIaWdobGlnaHQ7XG4gIGxldCBmb3VuZEVsZW1lbnQ7XG4gIGxldCBmb3VuZFJlY3Q7XG4gIGZvciAobGV0IGkgPSBfaGlnaGxpZ2h0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzW2ldO1xuICAgIGxldCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGhpZ2hsaWdodFBhcmVudCA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYCMke2hpZ2hsaWdodC5pZH1gKTtcbiAgICB9XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBsZXQgaGl0ID0gZmFsc2U7XG4gICAgY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnRzID0gaGlnaGxpZ2h0UGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRGcmFnbWVudCBvZiBoaWdobGlnaHRGcmFnbWVudHMpIHtcbiAgICAgIGNvbnN0IHdpdGhSZWN0ID0gaGlnaGxpZ2h0RnJhZ21lbnQ7XG4gICAgICBjb25zdCBsZWZ0ID0gd2l0aFJlY3QucmVjdC5sZWZ0ICsgeE9mZnNldDtcbiAgICAgIGNvbnN0IHRvcCA9IHdpdGhSZWN0LnJlY3QudG9wICsgeU9mZnNldDtcbiAgICAgIGZvdW5kUmVjdCA9IHdpdGhSZWN0LnJlY3Q7XG4gICAgICBpZiAoXG4gICAgICAgIHggPj0gbGVmdCAmJlxuICAgICAgICB4IDwgbGVmdCArIHdpdGhSZWN0LnJlY3Qud2lkdGggJiZcbiAgICAgICAgeSA+PSB0b3AgJiZcbiAgICAgICAgeSA8IHRvcCArIHdpdGhSZWN0LnJlY3QuaGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgaGl0ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChoaXQpIHtcbiAgICAgIGZvdW5kSGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgZm91bmRFbGVtZW50ID0gaGlnaGxpZ2h0UGFyZW50O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFmb3VuZEhpZ2hsaWdodCB8fCAhZm91bmRFbGVtZW50KSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKHdpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICAgIH1cbiAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoZm91bmRFbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtY2xpY2tcIikpIHtcbiAgICBpZiAoZXYudHlwZSA9PT0gXCJtb3VzZW1vdmVcIikge1xuICAgICAgY29uc3QgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBmb3VuZEVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YClcbiAgICAgICk7XG4gICAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcy5pbmRleE9mKGhpZ2hsaWdodEFyZWEpIDwgMCkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLCBmb3VuZEhpZ2hsaWdodCk7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyA9IGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEJvdW5kaW5ncyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRCb3VuZGluZyBvZiBhbGxIaWdobGlnaHRCb3VuZGluZ3MpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyB8fFxuICAgICAgICAgIGhpZ2hsaWdodEJvdW5kaW5nICE9PSBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZ1xuICAgICAgICApIHtcbiAgICAgICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZykge1xuICAgICAgICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgICAgICAgIHNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUoXG4gICAgICAgICAgICB3aW4sXG4gICAgICAgICAgICBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyxcbiAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXYudHlwZSA9PT0gXCJtb3VzZXVwXCIgfHwgZXYudHlwZSA9PT0gXCJ0b3VjaGVuZFwiKSB7XG4gICAgICBjb25zdCB0b3VjaGVkUG9zaXRpb24gPSB7XG4gICAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGZvdW5kUmVjdC5sZWZ0LFxuICAgICAgICB3aWR0aDogZm91bmRSZWN0LndpZHRoLFxuICAgICAgICB0b3A6IGZvdW5kUmVjdC50b3AsXG4gICAgICAgIGhlaWdodDogZm91bmRSZWN0LmhlaWdodCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGhpZ2hsaWdodDogZm91bmRIaWdobGlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB0b3VjaGVkUG9zaXRpb24sXG4gICAgICB9O1xuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIHdpbmRvdy5wcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHdpbmRvdy5wcm9jZXNzLnR5cGUgPT09IFwicmVuZGVyZXJcIlxuICAgICAgKSB7XG4gICAgICAgIGVsZWN0cm9uXzEuaXBjUmVuZGVyZXIuc2VuZFRvSG9zdChSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0ssIHBheWxvYWQpO1xuICAgICAgfSBlbHNlIGlmICh3aW5kb3cud2Via2l0VVJMKSB7XG4gICAgICAgIGlmIChmb3VuZEhpZ2hsaWdodC5pZC5zZWFyY2goXCJSMl9BTk5PVEFUSU9OX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQoZm91bmRIaWdobGlnaHQuaWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgICAgICAgICAgd2Via2l0Lm1lc3NhZ2VIYW5kbGVycy5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0hJR0hMSUdIVF9cIikgPj0gMCkge1xuICAgICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgICAgICAgICBBbmRyb2lkLmhpZ2hsaWdodEFjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QxLmxlZnQgPCByZWN0Mi5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIubGVmdCA8IHJlY3QxLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIubGVmdCwgcmVjdDEucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0MS50b3AgPCByZWN0Mi5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLnRvcCA8IHJlY3QxLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLnRvcCwgcmVjdDEuYm90dG9tLCB0b2xlcmFuY2UpKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhyZWN0cykge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIC0xKSkge1xuICAgICAgICBsZXQgdG9BZGQgPSBbXTtcbiAgICAgICAgbGV0IHRvUmVtb3ZlO1xuICAgICAgICBsZXQgdG9QcmVzZXJ2ZTtcbiAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czEgPSByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICB0b1ByZXNlcnZlID0gcmVjdDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czIgPSByZWN0U3VidHJhY3QocmVjdDIsIHJlY3QxKTtcbiAgICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoIDwgc3VidHJhY3RSZWN0czIubGVuZ3RoKSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICAgIHRvUHJlc2VydmUgPSByZWN0MjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMjtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDI7XG4gICAgICAgICAgICB0b1ByZXNlcnZlID0gcmVjdDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zdCB0b0NoZWNrID0gW107XG4gICAgICAgICAgdG9DaGVjay5wdXNoKHRvUHJlc2VydmUpO1xuICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRvQ2hlY2ssIHRvQWRkKTtcbiAgICAgICAgICBjaGVja092ZXJsYXBzKHRvQ2hlY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGBDTElFTlQgUkVDVDogb3ZlcmxhcCwgY3V0IG9uZSByZWN0IGludG8gJHt0b0FkZC5sZW5ndGh9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gdG9SZW1vdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShuZXdSZWN0cywgdG9BZGQpO1xuICAgICAgICByZXR1cm4gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhuZXdSZWN0cyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gY2hlY2tPdmVybGFwcyhyZWN0cykge1xuICBjb25zdCBzdGlsbE92ZXJsYXBpbmdSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJlY3QxIG9mIHJlY3RzKSB7XG4gICAgZm9yIChjb25zdCByZWN0MiBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhhczEgPSBzdGlsbE92ZXJsYXBpbmdSZWN0cy5pbmRleE9mKHJlY3QxKSA+PSAwO1xuICAgICAgY29uc3QgaGFzMiA9IHN0aWxsT3ZlcmxhcGluZ1JlY3RzLmluZGV4T2YocmVjdDIpID49IDA7XG4gICAgICBpZiAoIWhhczEgfHwgIWhhczIpIHtcbiAgICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgICBpZiAoIWhhczEpIHtcbiAgICAgICAgICAgIHN0aWxsT3ZlcmxhcGluZ1JlY3RzLnB1c2gocmVjdDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWhhczIpIHtcbiAgICAgICAgICAgIHN0aWxsT3ZlcmxhcGluZ1JlY3RzLnB1c2gocmVjdDIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiBvdmVybGFwIC0tLVwiKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAjMSBUT1A6JHtyZWN0MS50b3B9IEJPVFRPTToke3JlY3QxLmJvdHRvbX0gTEVGVDoke3JlY3QxLmxlZnR9IFJJR0hUOiR7cmVjdDEucmlnaHR9IFdJRFRIOiR7cmVjdDEud2lkdGh9IEhFSUdIVDoke3JlY3QxLmhlaWdodH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAjMiBUT1A6JHtyZWN0Mi50b3B9IEJPVFRPTToke3JlY3QyLmJvdHRvbX0gTEVGVDoke3JlY3QyLmxlZnR9IFJJR0hUOiR7cmVjdDIucmlnaHR9IFdJRFRIOiR7cmVjdDIud2lkdGh9IEhFSUdIVDoke3JlY3QyLmhlaWdodH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCB4T3ZlcmxhcCA9IGdldFJlY3RPdmVybGFwWChyZWN0MSwgcmVjdDIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGB4T3ZlcmxhcDogJHt4T3ZlcmxhcH1gKTtcbiAgICAgICAgICBjb25zdCB5T3ZlcmxhcCA9IGdldFJlY3RPdmVybGFwWShyZWN0MSwgcmVjdDIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGB5T3ZlcmxhcDogJHt5T3ZlcmxhcH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoc3RpbGxPdmVybGFwaW5nUmVjdHMubGVuZ3RoKSB7XG4gICAgY29uc29sZS5sb2coYENMSUVOVCBSRUNUOiBvdmVybGFwcyAke3N0aWxsT3ZlcmxhcGluZ1JlY3RzLmxlbmd0aH1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVDb250YWluZWRSZWN0cyhyZWN0cywgdG9sZXJhbmNlKSB7XG4gIGNvbnN0IHJlY3RzVG9LZWVwID0gbmV3IFNldChyZWN0cyk7XG4gIGZvciAoY29uc3QgcmVjdCBvZiByZWN0cykge1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggPiAxICYmIHJlY3QuaGVpZ2h0ID4gMTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgdGlueVwiKTtcbiAgICAgIH1cbiAgICAgIHJlY3RzVG9LZWVwLmRlbGV0ZShyZWN0KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHBvc3NpYmx5Q29udGFpbmluZ1JlY3Qgb2YgcmVjdHMpIHtcbiAgICAgIGlmIChyZWN0ID09PSBwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFyZWN0c1RvS2VlcC5oYXMocG9zc2libHlDb250YWluaW5nUmVjdCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdENvbnRhaW5zKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QsIHJlY3QsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBjb250YWluZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20ocmVjdHNUb0tlZXApO1xufVxuXG5mdW5jdGlvbiBhbG1vc3RFcXVhbChhLCBiLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8PSB0b2xlcmFuY2U7XG59XG5cbmZ1bmN0aW9uIHJlY3RJbnRlcnNlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IG1heExlZnQgPSBNYXRoLm1heChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgbWluUmlnaHQgPSBNYXRoLm1pbihyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCBtYXhUb3AgPSBNYXRoLm1heChyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IG1pbkJvdHRvbSA9IE1hdGgubWluKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgY29uc3QgcmVjdCA9IHtcbiAgICBib3R0b206IG1pbkJvdHRvbSxcbiAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIG1pbkJvdHRvbSAtIG1heFRvcCksXG4gICAgbGVmdDogbWF4TGVmdCxcbiAgICByaWdodDogbWluUmlnaHQsXG4gICAgdG9wOiBtYXhUb3AsXG4gICAgd2lkdGg6IE1hdGgubWF4KDAsIG1pblJpZ2h0IC0gbWF4TGVmdCksXG4gIH07XG4gIHJldHVybiByZWN0O1xufVxuXG5mdW5jdGlvbiByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IHJlY3RJbnRlcnNlY3RlZCA9IHJlY3RJbnRlcnNlY3QocmVjdDIsIHJlY3QxKTtcbiAgaWYgKHJlY3RJbnRlcnNlY3RlZC5oZWlnaHQgPT09IDAgfHwgcmVjdEludGVyc2VjdGVkLndpZHRoID09PSAwKSB7XG4gICAgcmV0dXJuIFtyZWN0MV07XG4gIH1cbiAgY29uc3QgcmVjdHMgPSBbXTtcbiAge1xuICAgIGNvbnN0IHJlY3RBID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0MS5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RBLndpZHRoID0gcmVjdEEucmlnaHQgLSByZWN0QS5sZWZ0O1xuICAgIHJlY3RBLmhlaWdodCA9IHJlY3RBLmJvdHRvbSAtIHJlY3RBLnRvcDtcbiAgICBpZiAocmVjdEEuaGVpZ2h0ICE9PSAwICYmIHJlY3RBLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RBKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RCID0ge1xuICAgICAgYm90dG9tOiByZWN0SW50ZXJzZWN0ZWQudG9wLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RCLndpZHRoID0gcmVjdEIucmlnaHQgLSByZWN0Qi5sZWZ0O1xuICAgIHJlY3RCLmhlaWdodCA9IHJlY3RCLmJvdHRvbSAtIHJlY3RCLnRvcDtcbiAgICBpZiAocmVjdEIuaGVpZ2h0ICE9PSAwICYmIHJlY3RCLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RCKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RDID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3RJbnRlcnNlY3RlZC5ib3R0b20sXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RDLndpZHRoID0gcmVjdEMucmlnaHQgLSByZWN0Qy5sZWZ0O1xuICAgIHJlY3RDLmhlaWdodCA9IHJlY3RDLmJvdHRvbSAtIHJlY3RDLnRvcDtcbiAgICBpZiAocmVjdEMuaGVpZ2h0ICE9PSAwICYmIHJlY3RDLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RDKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3REID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICByaWdodDogcmVjdDEucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEQud2lkdGggPSByZWN0RC5yaWdodCAtIHJlY3RELmxlZnQ7XG4gICAgcmVjdEQuaGVpZ2h0ID0gcmVjdEQuYm90dG9tIC0gcmVjdEQudG9wO1xuICAgIGlmIChyZWN0RC5oZWlnaHQgIT09IDAgJiYgcmVjdEQud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWluc1BvaW50KHJlY3QsIHgsIHksIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0LmxlZnQgPCB4IHx8IGFsbW9zdEVxdWFsKHJlY3QubGVmdCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5yaWdodCA+IHggfHwgYWxtb3N0RXF1YWwocmVjdC5yaWdodCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC50b3AgPCB5IHx8IGFsbW9zdEVxdWFsKHJlY3QudG9wLCB5LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LmJvdHRvbSA+IHkgfHwgYWxtb3N0RXF1YWwocmVjdC5ib3R0b20sIHksIHRvbGVyYW5jZSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWlucyhyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKVxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IGxlZnQgPSBNYXRoLm1pbihyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgcmlnaHQgPSBNYXRoLm1heChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCB0b3AgPSBNYXRoLm1pbihyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IGJvdHRvbSA9IE1hdGgubWF4KHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgcmV0dXJuIHtcbiAgICBib3R0b20sXG4gICAgaGVpZ2h0OiBib3R0b20gLSB0b3AsXG4gICAgbGVmdCxcbiAgICByaWdodCxcbiAgICB0b3AsXG4gICAgd2lkdGg6IHJpZ2h0IC0gbGVmdCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICByZWN0cyxcbiAgdG9sZXJhbmNlLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwibWVyZ2VUb3VjaGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0c0xpbmVVcFZlcnRpY2FsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIubGVmdCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCBob3Jpem9udGFsQWxsb3dlZCA9ICFkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzO1xuICAgICAgY29uc3QgYWxpZ25lZCA9XG4gICAgICAgIChyZWN0c0xpbmVVcEhvcml6b250YWxseSAmJiBob3Jpem9udGFsQWxsb3dlZCkgfHxcbiAgICAgICAgKHJlY3RzTGluZVVwVmVydGljYWxseSAmJiAhcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkpO1xuICAgICAgY29uc3QgY2FuTWVyZ2UgPSBhbGlnbmVkICYmIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpO1xuICAgICAgaWYgKGNhbk1lcmdlKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGBDTElFTlQgUkVDVDogbWVyZ2luZyB0d28gaW50byBvbmUsIFZFUlRJQ0FMOiAke3JlY3RzTGluZVVwVmVydGljYWxseX0gSE9SSVpPTlRBTDogJHtyZWN0c0xpbmVVcEhvcml6b250YWxseX0gKCR7ZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c30pYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gcmVjdDEgJiYgcmVjdCAhPT0gcmVjdDI7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXBsYWNlbWVudENsaWVudFJlY3QgPSBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgbmV3UmVjdHMucHVzaChyZXBsYWNlbWVudENsaWVudFJlY3QpO1xuICAgICAgICByZXR1cm4gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgICAgICAgIG5ld1JlY3RzLFxuICAgICAgICAgIHRvbGVyYW5jZSxcbiAgICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAocmFuZ2UsIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMpIHtcbiAgY29uc3QgcmFuZ2VDbGllbnRSZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG4gIHJldHVybiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcF8oXG4gICAgcmFuZ2VDbGllbnRSZWN0cyxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwXyhcbiAgY2xpZW50UmVjdHMsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBjb25zdCB0b2xlcmFuY2UgPSAxO1xuICBjb25zdCBvcmlnaW5hbFJlY3RzID0gW107XG4gIGZvciAoY29uc3QgcmFuZ2VDbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgb3JpZ2luYWxSZWN0cy5wdXNoKHtcbiAgICAgIGJvdHRvbTogcmFuZ2VDbGllbnRSZWN0LmJvdHRvbSxcbiAgICAgIGhlaWdodDogcmFuZ2VDbGllbnRSZWN0LmhlaWdodCxcbiAgICAgIGxlZnQ6IHJhbmdlQ2xpZW50UmVjdC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5yaWdodCxcbiAgICAgIHRvcDogcmFuZ2VDbGllbnRSZWN0LnRvcCxcbiAgICAgIHdpZHRoOiByYW5nZUNsaWVudFJlY3Qud2lkdGgsXG4gICAgfSk7XG4gIH1cbiAgY29uc3QgbWVyZ2VkUmVjdHMgPSBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gICAgb3JpZ2luYWxSZWN0cyxcbiAgICB0b2xlcmFuY2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICBjb25zdCBub0NvbnRhaW5lZFJlY3RzID0gcmVtb3ZlQ29udGFpbmVkUmVjdHMobWVyZ2VkUmVjdHMsIHRvbGVyYW5jZSk7XG4gIGNvbnN0IG5ld1JlY3RzID0gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhub0NvbnRhaW5lZFJlY3RzKTtcbiAgY29uc3QgbWluQXJlYSA9IDIgKiAyO1xuICBmb3IgKGxldCBqID0gbmV3UmVjdHMubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICBjb25zdCByZWN0ID0gbmV3UmVjdHNbal07XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCAqIHJlY3QuaGVpZ2h0ID4gbWluQXJlYTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgaWYgKG5ld1JlY3RzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBzbWFsbFwiKTtcbiAgICAgICAgfVxuICAgICAgICBuZXdSZWN0cy5zcGxpY2UoaiwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsLCBidXQga2VlcCBvdGhlcndpc2UgZW1wdHkhXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoSVNfREVWKSB7XG4gICAgY2hlY2tPdmVybGFwcyhuZXdSZWN0cyk7XG4gIH1cbiAgaWYgKElTX0RFVikge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYENMSUVOVCBSRUNUOiByZWR1Y2VkICR7b3JpZ2luYWxSZWN0cy5sZW5ndGh9IC0tPiAke25ld1JlY3RzLmxlbmd0aH1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4gbmV3UmVjdHM7XG59XG5cbmZ1bmN0aW9uIGlzUGFnaW5hdGVkKGRvY3VtZW50KSB7XG4gIHJldHVybiAoXG4gICAgZG9jdW1lbnQgJiZcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiZcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX1BBR0lOQVRFRClcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCkge1xuICBpZiAoZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCkge1xuICAgIHJldHVybiBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50O1xuICB9XG4gIHJldHVybiBkb2N1bWVudC5ib2R5O1xufVxuXG5mdW5jdGlvbiBlbnN1cmVDb250YWluZXIod2luLCBhbm5vdGF0aW9uRmxhZykge1xuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBpZiAoIV9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgaWYgKCFib2R5RXZlbnRMaXN0ZW5lcnNTZXQpIHtcbiAgICAgIGJvZHlFdmVudExpc3RlbmVyc1NldCA9IHRydWU7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwibW91c2Vkb3duXCIsXG4gICAgICAgIChldikgPT4ge1xuICAgICAgICAgIGxhc3RNb3VzZURvd25YID0gZXYuY2xpZW50WDtcbiAgICAgICAgICBsYXN0TW91c2VEb3duWSA9IGV2LmNsaWVudFk7XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcIm1vdXNldXBcIixcbiAgICAgICAgKGV2KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgTWF0aC5hYnMobGFzdE1vdXNlRG93blggLSBldi5jbGllbnRYKSA8IDMgJiZcbiAgICAgICAgICAgIE1hdGguYWJzKGxhc3RNb3VzZURvd25ZIC0gZXYuY2xpZW50WSkgPCAzXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcIm1vdXNlbW92ZVwiLFxuICAgICAgICAoZXYpID0+IHtcbiAgICAgICAgICBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJ0b3VjaGVuZFwiLFxuICAgICAgICBmdW5jdGlvbiB0b3VjaEVuZChlKSB7XG4gICAgICAgICAgcHJvY2Vzc1RvdWNoRXZlbnQod2luLCBlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgfVxuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBJRF9ISUdITElHSFRTX0NPTlRBSU5FUik7XG5cbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChfaGlnaGxpZ2h0c0NvbnRhaW5lcik7XG4gIH1cblxuICByZXR1cm4gX2hpZ2hsaWdodHNDb250YWluZXI7XG59XG5cbmZ1bmN0aW9uIGhpZGVBbGxoaWdobGlnaHRzKCkge1xuICBpZiAoX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5yZW1vdmUoKTtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lciA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVzdHJveUFsbGhpZ2hsaWdodHMoKSB7XG4gIGhpZGVBbGxoaWdobGlnaHRzKCk7XG4gIF9oaWdobGlnaHRzLnNwbGljZSgwLCBfaGlnaGxpZ2h0cy5sZW5ndGgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveUhpZ2hsaWdodChpZCkge1xuICBsZXQgaSA9IC0xO1xuICBsZXQgX2RvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoLCBqKSA9PiB7XG4gICAgaSA9IGo7XG4gICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICB9KTtcbiAgaWYgKGhpZ2hsaWdodCAmJiBpID49IDAgJiYgaSA8IF9oaWdobGlnaHRzLmxlbmd0aCkge1xuICAgIF9oaWdobGlnaHRzLnNwbGljZShpLCAxKTtcbiAgfVxuICBjb25zdCBoaWdobGlnaHRDb250YWluZXIgPSBfZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoaGlnaGxpZ2h0Q29udGFpbmVyKSB7XG4gICAgaGlnaGxpZ2h0Q29udGFpbmVyLnJlbW92ZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2ZpVGV4dE5vZGUobm9kZSkge1xuICByZXR1cm4gbm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREU7XG59XG5cbmZ1bmN0aW9uIGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChlbGVtZW50LCBjaGlsZCkge1xuICBsZXQgZm91bmQgPSAtMTtcbiAgbGV0IHRleHROb2RlSW5kZXggPSAtMTtcbiAgbGV0IHByZXZpb3VzV2FzRWxlbWVudCA9IGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkTm9kZSA9IGVsZW1lbnQuY2hpbGROb2Rlc1tpXTtcbiAgICBjb25zdCBpc1RleHQgPSBpc0NmaVRleHROb2RlKGNoaWxkTm9kZSk7XG4gICAgaWYgKGlzVGV4dCB8fCBwcmV2aW91c1dhc0VsZW1lbnQpIHtcbiAgICAgIHRleHROb2RlSW5kZXggKz0gMjtcbiAgICB9XG4gICAgaWYgKGlzVGV4dCkge1xuICAgICAgaWYgKGNoaWxkTm9kZSA9PT0gY2hpbGQpIHtcbiAgICAgICAgZm91bmQgPSB0ZXh0Tm9kZUluZGV4O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcHJldmlvdXNXYXNFbGVtZW50ID0gY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERTtcbiAgfVxuICByZXR1cm4gZm91bmQ7XG59XG5cbmZ1bmN0aW9uIGdldENvbW1vbkFuY2VzdG9yRWxlbWVudChub2RlMSwgbm9kZTIpIHtcbiAgaWYgKG5vZGUxLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMSA9PT0gbm9kZTIpIHtcbiAgICByZXR1cm4gbm9kZTE7XG4gIH1cbiAgaWYgKG5vZGUxLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMS5jb250YWlucyhub2RlMikpIHtcbiAgICByZXR1cm4gbm9kZTE7XG4gIH1cbiAgaWYgKG5vZGUyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMi5jb250YWlucyhub2RlMSkpIHtcbiAgICByZXR1cm4gbm9kZTI7XG4gIH1cbiAgY29uc3Qgbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbiA9IFtdO1xuICBsZXQgcGFyZW50ID0gbm9kZTEucGFyZW50Tm9kZTtcbiAgd2hpbGUgKHBhcmVudCAmJiBwYXJlbnQubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbi5wdXNoKHBhcmVudCk7XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XG4gIH1cbiAgY29uc3Qgbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbiA9IFtdO1xuICBwYXJlbnQgPSBub2RlMi5wYXJlbnROb2RlO1xuICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluLnB1c2gocGFyZW50KTtcbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgfVxuICBsZXQgY29tbW9uQW5jZXN0b3IgPSBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluLmZpbmQoXG4gICAgKG5vZGUxRWxlbWVudEFuY2VzdG9yKSA9PiB7XG4gICAgICByZXR1cm4gbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbi5pbmRleE9mKG5vZGUxRWxlbWVudEFuY2VzdG9yKSA+PSAwO1xuICAgIH1cbiAgKTtcbiAgaWYgKCFjb21tb25BbmNlc3Rvcikge1xuICAgIGNvbW1vbkFuY2VzdG9yID0gbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbi5maW5kKChub2RlMkVsZW1lbnRBbmNlc3RvcikgPT4ge1xuICAgICAgcmV0dXJuIG5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4uaW5kZXhPZihub2RlMkVsZW1lbnRBbmNlc3RvcikgPj0gMDtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gY29tbW9uQW5jZXN0b3I7XG59XG5cbmZ1bmN0aW9uIGZ1bGxRdWFsaWZpZWRTZWxlY3Rvcihub2RlKSB7XG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIGNvbnN0IGxvd2VyQ2FzZU5hbWUgPVxuICAgICAgKG5vZGUubG9jYWxOYW1lICYmIG5vZGUubG9jYWxOYW1lLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgICBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgcmV0dXJuIGxvd2VyQ2FzZU5hbWU7XG4gIH1cbiAgLy9yZXR1cm4gY3NzUGF0aChub2RlLCBqdXN0U2VsZWN0b3IpO1xuICByZXR1cm4gY3NzUGF0aChub2RlLCB0cnVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvKCkge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmICghc2VsZWN0aW9uKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIENPTExBUFNFRC5cIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYXdUZXh0ID0gc2VsZWN0aW9uLnRvU3RyaW5nKCk7XG4gIGNvbnN0IGNsZWFuVGV4dCA9IHJhd1RleHQudHJpbSgpLnJlcGxhY2UoL1xcbi9nLCBcIiBcIikucmVwbGFjZSgvXFxzXFxzKy9nLCBcIiBcIik7XG4gIGlmIChjbGVhblRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIFRFWFQgRU1QVFkuXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFzZWxlY3Rpb24uYW5jaG9yTm9kZSB8fCAhc2VsZWN0aW9uLmZvY3VzTm9kZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2UgPVxuICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxXG4gICAgICA/IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApXG4gICAgICA6IGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0XG4gICAgICAgICk7XG4gIGlmICghcmFuZ2UgfHwgcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCIkJCQkJCQkJCQkJCQkJCQkJCBDQU5OT1QgR0VUIE5PTi1DT0xMQVBTRUQgU0VMRUNUSU9OIFJBTkdFPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYW5nZUluZm8gPSBjb252ZXJ0UmFuZ2UocmFuZ2UsIGZ1bGxRdWFsaWZpZWRTZWxlY3RvciwgY29tcHV0ZUNGSSk7XG4gIGlmICghcmFuZ2VJbmZvKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIFJBTkdFIElORk8gRkFJTD8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoSVNfREVWICYmIERFQlVHX1ZJU1VBTFMpIHtcbiAgICBjb25zdCByZXN0b3JlZFJhbmdlID0gY29udmVydFJhbmdlSW5mbyh3aW4uZG9jdW1lbnQsIHJhbmdlSW5mbyk7XG4gICAgaWYgKHJlc3RvcmVkUmFuZ2UpIHtcbiAgICAgIGlmIChcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydE9mZnNldCA9PT0gcmFuZ2Uuc3RhcnRPZmZzZXQgJiZcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRPZmZzZXQgPT09IHJhbmdlLmVuZE9mZnNldCAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5zdGFydENvbnRhaW5lciAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLmVuZENvbnRhaW5lciA9PT0gcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgICApIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJTRUxFQ1RJT04gUkFOR0UgUkVTVE9SRUQgT0tBWSAoZGV2IGNoZWNrKS5cIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhcIlNFTEVDVElPTiBSQU5HRSBSRVNUT1JFIEZBSUwgKGRldiBjaGVjaykuXCIpO1xuICAgICAgICBkdW1wRGVidWcoXG4gICAgICAgICAgXCJTRUxFQ1RJT05cIixcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIk9SREVSRUQgUkFOR0UgRlJPTSBTRUxFQ1RJT05cIixcbiAgICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgICAgICByYW5nZS5zdGFydE9mZnNldCxcbiAgICAgICAgICByYW5nZS5lbmRDb250YWluZXIsXG4gICAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIlJFU1RPUkVEIFJBTkdFXCIsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kQ29udGFpbmVyLFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiQ0FOTk9UIFJFU1RPUkUgU0VMRUNUSU9OIFJBTkdFID8/IVwiKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGxvY2F0aW9uczogcmFuZ2VJbmZvMkxvY2F0aW9uKHJhbmdlSW5mbyksXG4gICAgdGV4dDoge1xuICAgICAgaGlnaGxpZ2h0OiByYXdUZXh0LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNoZWNrQmxhY2tsaXN0ZWQoZWwpIHtcbiAgbGV0IGJsYWNrbGlzdGVkSWQ7XG4gIGNvbnN0IGlkID0gZWwuZ2V0QXR0cmlidXRlKFwiaWRcIik7XG4gIGlmIChpZCAmJiBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSS5pbmRleE9mKGlkKSA+PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJjaGVja0JsYWNrbGlzdGVkIElEOiBcIiArIGlkKTtcbiAgICBibGFja2xpc3RlZElkID0gaWQ7XG4gIH1cbiAgbGV0IGJsYWNrbGlzdGVkQ2xhc3M7XG4gIGZvciAoY29uc3QgaXRlbSBvZiBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoaXRlbSkpIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiY2hlY2tCbGFja2xpc3RlZCBDTEFTUzogXCIgKyBpdGVtKTtcbiAgICAgIGJsYWNrbGlzdGVkQ2xhc3MgPSBpdGVtO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChibGFja2xpc3RlZElkIHx8IGJsYWNrbGlzdGVkQ2xhc3MpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY3NzUGF0aChub2RlLCBvcHRpbWl6ZWQpIHtcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cblxuICBjb25zdCBzdGVwcyA9IFtdO1xuICBsZXQgY29udGV4dE5vZGUgPSBub2RlO1xuICB3aGlsZSAoY29udGV4dE5vZGUpIHtcbiAgICBjb25zdCBzdGVwID0gX2Nzc1BhdGhTdGVwKGNvbnRleHROb2RlLCAhIW9wdGltaXplZCwgY29udGV4dE5vZGUgPT09IG5vZGUpO1xuICAgIGlmICghc3RlcCkge1xuICAgICAgYnJlYWs7IC8vIEVycm9yIC0gYmFpbCBvdXQgZWFybHkuXG4gICAgfVxuICAgIHN0ZXBzLnB1c2goc3RlcC52YWx1ZSk7XG4gICAgaWYgKHN0ZXAub3B0aW1pemVkKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY29udGV4dE5vZGUgPSBjb250ZXh0Tm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHN0ZXBzLnJldmVyc2UoKTtcbiAgcmV0dXJuIHN0ZXBzLmpvaW4oXCIgPiBcIik7XG59XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4vLyBodHRwczovL2Nocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vYmxpbmsvKy9tYXN0ZXIvU291cmNlL2RldnRvb2xzL2Zyb250X2VuZC9jb21wb25lbnRzL0RPTVByZXNlbnRhdGlvblV0aWxzLmpzIzMxNlxuZnVuY3Rpb24gX2Nzc1BhdGhTdGVwKG5vZGUsIG9wdGltaXplZCwgaXNUYXJnZXROb2RlKSB7XG4gIGZ1bmN0aW9uIHByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMobmQpIHtcbiAgICBjb25zdCBjbGFzc0F0dHJpYnV0ZSA9IG5kLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpO1xuICAgIGlmICghY2xhc3NBdHRyaWJ1dGUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NBdHRyaWJ1dGVcbiAgICAgIC5zcGxpdCgvXFxzKy9nKVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLm1hcCgobm0pID0+IHtcbiAgICAgICAgLy8gVGhlIHByZWZpeCBpcyByZXF1aXJlZCB0byBzdG9yZSBcIl9fcHJvdG9fX1wiIGluIGEgb2JqZWN0LWJhc2VkIG1hcC5cbiAgICAgICAgcmV0dXJuIFwiJFwiICsgbm07XG4gICAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlkU2VsZWN0b3IoaWRkKSB7XG4gICAgcmV0dXJuIFwiI1wiICsgZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkKGlkZCk7XG4gIH1cblxuICBmdW5jdGlvbiBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQoaWRlbnQpIHtcbiAgICBpZiAoaXNDU1NJZGVudGlmaWVyKGlkZW50KSkge1xuICAgICAgcmV0dXJuIGlkZW50O1xuICAgIH1cblxuICAgIGNvbnN0IHNob3VsZEVzY2FwZUZpcnN0ID0gL14oPzpbMC05XXwtWzAtOS1dPykvLnRlc3QoaWRlbnQpO1xuICAgIGNvbnN0IGxhc3RJbmRleCA9IGlkZW50Lmxlbmd0aCAtIDE7XG4gICAgcmV0dXJuIGlkZW50LnJlcGxhY2UoLy4vZywgZnVuY3Rpb24gKGMsIGlpKSB7XG4gICAgICByZXR1cm4gKHNob3VsZEVzY2FwZUZpcnN0ICYmIGlpID09PSAwKSB8fCAhaXNDU1NJZGVudENoYXIoYylcbiAgICAgICAgPyBlc2NhcGVBc2NpaUNoYXIoYywgaWkgPT09IGxhc3RJbmRleClcbiAgICAgICAgOiBjO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZXNjYXBlQXNjaWlDaGFyKGMsIGlzTGFzdCkge1xuICAgIHJldHVybiBcIlxcXFxcIiArIHRvSGV4Qnl0ZShjKSArIChpc0xhc3QgPyBcIlwiIDogXCIgXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9IZXhCeXRlKGMpIHtcbiAgICBsZXQgaGV4Qnl0ZSA9IGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNik7XG4gICAgaWYgKGhleEJ5dGUubGVuZ3RoID09PSAxKSB7XG4gICAgICBoZXhCeXRlID0gXCIwXCIgKyBoZXhCeXRlO1xuICAgIH1cbiAgICByZXR1cm4gaGV4Qnl0ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQ1NTSWRlbnRDaGFyKGMpIHtcbiAgICBpZiAoL1thLXpBLVowLTlfLV0vLnRlc3QoYykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gYy5jaGFyQ29kZUF0KDApID49IDB4YTA7XG4gIH1cblxuICBmdW5jdGlvbiBpc0NTU0lkZW50aWZpZXIodmFsdWUpIHtcbiAgICByZXR1cm4gL14tP1thLXpBLVpfXVthLXpBLVowLTlfLV0qJC8udGVzdCh2YWx1ZSk7XG4gIH1cblxuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGxvd2VyQ2FzZU5hbWUgPVxuICAgIChub2RlLmxvY2FsTmFtZSAmJiBub2RlLmxvY2FsTmFtZS50b0xvd2VyQ2FzZSgpKSB8fFxuICAgIG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuICBjb25zdCBlbGVtZW50ID0gbm9kZTtcblxuICBjb25zdCBpZCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaWRcIik7XG5cbiAgaWYgKG9wdGltaXplZCkge1xuICAgIGlmIChpZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3B0aW1pemVkOiB0cnVlLFxuICAgICAgICB2YWx1ZTogaWRTZWxlY3RvcihpZCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBsb3dlckNhc2VOYW1lID09PSBcImJvZHlcIiB8fFxuICAgICAgbG93ZXJDYXNlTmFtZSA9PT0gXCJoZWFkXCIgfHxcbiAgICAgIGxvd2VyQ2FzZU5hbWUgPT09IFwiaHRtbFwiXG4gICAgKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICAgIHZhbHVlOiBsb3dlckNhc2VOYW1lLCAvLyBub2RlLm5vZGVOYW1lSW5Db3JyZWN0Q2FzZSgpLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBub2RlTmFtZSA9IGxvd2VyQ2FzZU5hbWU7IC8vIG5vZGUubm9kZU5hbWVJbkNvcnJlY3RDYXNlKCk7XG4gIGlmIChpZCkge1xuICAgIHJldHVybiB7XG4gICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICB2YWx1ZTogbm9kZU5hbWUgKyBpZFNlbGVjdG9yKGlkKSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuXG4gIGlmICghcGFyZW50IHx8IHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5ET0NVTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgIHZhbHVlOiBub2RlTmFtZSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfID0gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhlbGVtZW50KTtcblxuICBjb25zdCBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheSA9IFtdOyAvLyAua2V5U2V0KClcbiAgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfLmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICBpZiAocHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkuaW5kZXhPZihhcnJJdGVtKSA8IDApIHtcbiAgICAgIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5LnB1c2goYXJySXRlbSk7XG4gICAgfVxuICB9KTtcblxuICBsZXQgbmVlZHNDbGFzc05hbWVzID0gZmFsc2U7XG4gIGxldCBuZWVkc050aENoaWxkID0gZmFsc2U7XG4gIGxldCBvd25JbmRleCA9IC0xO1xuICBsZXQgZWxlbWVudEluZGV4ID0gLTE7XG4gIGNvbnN0IHNpYmxpbmdzID0gcGFyZW50LmNoaWxkcmVuO1xuXG4gIGZvciAoXG4gICAgbGV0IGkgPSAwO1xuICAgIChvd25JbmRleCA9PT0gLTEgfHwgIW5lZWRzTnRoQ2hpbGQpICYmIGkgPCBzaWJsaW5ncy5sZW5ndGg7XG4gICAgKytpXG4gICkge1xuICAgIGNvbnN0IHNpYmxpbmcgPSBzaWJsaW5nc1tpXTtcbiAgICBpZiAoc2libGluZy5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBlbGVtZW50SW5kZXggKz0gMTtcbiAgICBpZiAoc2libGluZyA9PT0gbm9kZSkge1xuICAgICAgb3duSW5kZXggPSBlbGVtZW50SW5kZXg7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKG5lZWRzTnRoQ2hpbGQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHNpYmxpbmcubm9kZU5hbWVJbkNvcnJlY3RDYXNlKClcbiAgICBjb25zdCBzaWJsaW5nTmFtZSA9XG4gICAgICAoc2libGluZy5sb2NhbE5hbWUgJiYgc2libGluZy5sb2NhbE5hbWUudG9Mb3dlckNhc2UoKSkgfHxcbiAgICAgIHNpYmxpbmcubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoc2libGluZ05hbWUgIT09IG5vZGVOYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbmVlZHNDbGFzc05hbWVzID0gdHJ1ZTtcblxuICAgIGNvbnN0IG93bkNsYXNzTmFtZXMgPSBbXTtcbiAgICBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheS5mb3JFYWNoKChhcnJJdGVtKSA9PiB7XG4gICAgICBvd25DbGFzc05hbWVzLnB1c2goYXJySXRlbSk7XG4gICAgfSk7XG4gICAgbGV0IG93bkNsYXNzTmFtZUNvdW50ID0gb3duQ2xhc3NOYW1lcy5sZW5ndGg7XG5cbiAgICBpZiAob3duQ2xhc3NOYW1lQ291bnQgPT09IDApIHtcbiAgICAgIG5lZWRzTnRoQ2hpbGQgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHNpYmxpbmdDbGFzc05hbWVzQXJyYXlfID0gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhzaWJsaW5nKTtcbiAgICBjb25zdCBzaWJsaW5nQ2xhc3NOYW1lc0FycmF5ID0gW107IC8vIC5rZXlTZXQoKVxuICAgIHNpYmxpbmdDbGFzc05hbWVzQXJyYXlfLmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICAgIGlmIChzaWJsaW5nQ2xhc3NOYW1lc0FycmF5LmluZGV4T2YoYXJySXRlbSkgPCAwKSB7XG4gICAgICAgIHNpYmxpbmdDbGFzc05hbWVzQXJyYXkucHVzaChhcnJJdGVtKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgc2libGluZ0NsYXNzIG9mIHNpYmxpbmdDbGFzc05hbWVzQXJyYXkpIHtcbiAgICAgIGNvbnN0IGluZCA9IG93bkNsYXNzTmFtZXMuaW5kZXhPZihzaWJsaW5nQ2xhc3MpO1xuICAgICAgaWYgKGluZCA8IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIG93bkNsYXNzTmFtZXMuc3BsaWNlKGluZCwgMSk7IC8vIGRlbGV0ZSBvd25DbGFzc05hbWVzW3NpYmxpbmdDbGFzc107XG5cbiAgICAgIGlmICghLS1vd25DbGFzc05hbWVDb3VudCkge1xuICAgICAgICBuZWVkc050aENoaWxkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHJlc3VsdCA9IG5vZGVOYW1lO1xuICBpZiAoXG4gICAgaXNUYXJnZXROb2RlICYmXG4gICAgbm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJlxuICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwidHlwZVwiKSAmJlxuICAgICFlbGVtZW50LmdldEF0dHJpYnV0ZShcImlkXCIpICYmXG4gICAgIWVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIilcbiAgKSB7XG4gICAgcmVzdWx0ICs9ICdbdHlwZT1cIicgKyBlbGVtZW50LmdldEF0dHJpYnV0ZShcInR5cGVcIikgKyAnXCJdJztcbiAgfVxuICBpZiAobmVlZHNOdGhDaGlsZCkge1xuICAgIHJlc3VsdCArPSBcIjpudGgtY2hpbGQoXCIgKyAob3duSW5kZXggKyAxKSArIFwiKVwiO1xuICB9IGVsc2UgaWYgKG5lZWRzQ2xhc3NOYW1lcykge1xuICAgIGZvciAoY29uc3QgcHJlZml4ZWROYW1lIG9mIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5KSB7XG4gICAgICByZXN1bHQgKz0gXCIuXCIgKyBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQocHJlZml4ZWROYW1lLnN1YnN0cigxKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBvcHRpbWl6ZWQ6IGZhbHNlLFxuICAgIHZhbHVlOiByZXN1bHQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVDRkkobm9kZSkge1xuICAvLyBUT0RPOiBoYW5kbGUgY2hhcmFjdGVyIHBvc2l0aW9uIGluc2lkZSB0ZXh0IG5vZGVcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxldCBjZmkgPSBcIlwiO1xuXG4gIGxldCBjdXJyZW50RWxlbWVudCA9IG5vZGU7XG4gIHdoaWxlIChcbiAgICBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlICYmXG4gICAgY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgKSB7XG4gICAgY29uc3QgYmxhY2tsaXN0ZWQgPSBjaGVja0JsYWNrbGlzdGVkKGN1cnJlbnRFbGVtZW50KTtcbiAgICBpZiAoIWJsYWNrbGlzdGVkKSB7XG4gICAgICBjb25zdCBjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuID0gY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZS5jaGlsZHJlbjtcbiAgICAgIGxldCBjdXJyZW50RWxlbWVudEluZGV4ID0gLTE7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGN1cnJlbnRFbGVtZW50ID09PSBjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuW2ldKSB7XG4gICAgICAgICAgY3VycmVudEVsZW1lbnRJbmRleCA9IGk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50RWxlbWVudEluZGV4ID49IDApIHtcbiAgICAgICAgY29uc3QgY2ZpSW5kZXggPSAoY3VycmVudEVsZW1lbnRJbmRleCArIDEpICogMjtcbiAgICAgICAgY2ZpID1cbiAgICAgICAgICBjZmlJbmRleCArXG4gICAgICAgICAgKGN1cnJlbnRFbGVtZW50LmlkID8gXCJbXCIgKyBjdXJyZW50RWxlbWVudC5pZCArIFwiXVwiIDogXCJcIikgK1xuICAgICAgICAgIChjZmkubGVuZ3RoID8gXCIvXCIgKyBjZmkgOiBcIlwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY3VycmVudEVsZW1lbnQgPSBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlO1xuICB9XG5cbiAgcmV0dXJuIFwiL1wiICsgY2ZpO1xufVxuXG5mdW5jdGlvbiBfY3JlYXRlSGlnaGxpZ2h0KGxvY2F0aW9ucywgY29sb3IsIHBvaW50ZXJJbnRlcmFjdGlvbiwgdHlwZSkge1xuICBjb25zdCByYW5nZUluZm8gPSBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb25zKTtcbiAgY29uc3QgdW5pcXVlU3RyID0gYCR7cmFuZ2VJbmZvLmNmaX0ke3JhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcn0ke3JhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleH0ke3JhbmdlSW5mby5zdGFydE9mZnNldH0ke3JhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3J9JHtyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4fSR7cmFuZ2VJbmZvLmVuZE9mZnNldH1gO1xuXG4gIGNvbnN0IGhhc2ggPSByZXF1aXJlKFwiaGFzaC5qc1wiKTtcbiAgY29uc3Qgc2hhMjU2SGV4ID0gaGFzaC5zaGEyNTYoKS51cGRhdGUodW5pcXVlU3RyKS5kaWdlc3QoXCJoZXhcIik7XG5cbiAgdmFyIGlkO1xuICBpZiAodHlwZSA9PSBJRF9ISUdITElHSFRTX0NPTlRBSU5FUikge1xuICAgIGlkID0gXCJSMl9ISUdITElHSFRfXCIgKyBzaGEyNTZIZXg7XG4gIH0gZWxzZSB7XG4gICAgaWQgPSBcIlIyX0FOTk9UQVRJT05fXCIgKyBzaGEyNTZIZXg7XG4gIH1cblxuICBkZXN0cm95SGlnaGxpZ2h0KGlkKTtcblxuICBjb25zdCBoaWdobGlnaHQgPSB7XG4gICAgY29sb3I6IGNvbG9yID8gY29sb3IgOiBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IsXG4gICAgaWQsXG4gICAgcG9pbnRlckludGVyYWN0aW9uLFxuICAgIHJhbmdlSW5mbyxcbiAgfTtcbiAgX2hpZ2hsaWdodHMucHVzaChoaWdobGlnaHQpO1xuICBjcmVhdGVIaWdobGlnaHREb20oXG4gICAgd2luZG93LFxuICAgIGhpZ2hsaWdodCxcbiAgICB0eXBlID09IElEX0FOTk9UQVRJT05fQ09OVEFJTkVSID8gdHJ1ZSA6IGZhbHNlXG4gICk7XG5cbiAgcmV0dXJuIGhpZ2hsaWdodDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhpZ2hsaWdodChzZWxlY3Rpb25JbmZvLCBjb2xvciwgcG9pbnRlckludGVyYWN0aW9uKSB7XG4gIHJldHVybiBfY3JlYXRlSGlnaGxpZ2h0KFxuICAgIHNlbGVjdGlvbkluZm8sXG4gICAgY29sb3IsXG4gICAgcG9pbnRlckludGVyYWN0aW9uLFxuICAgIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBbm5vdGF0aW9uKGlkKSB7XG4gIGxldCBpID0gLTE7XG5cbiAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCwgaikgPT4ge1xuICAgIGkgPSBqO1xuICAgIHJldHVybiBoLmlkID09PSBpZDtcbiAgfSk7XG4gIGlmIChpID09IF9oaWdobGlnaHRzLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHZhciBsb2NhdGlvbnMgPSB7XG4gICAgbG9jYXRpb25zOiByYW5nZUluZm8yTG9jYXRpb24oaGlnaGxpZ2h0LnJhbmdlSW5mbyksXG4gIH07XG5cbiAgcmV0dXJuIF9jcmVhdGVIaWdobGlnaHQoXG4gICAgbG9jYXRpb25zLFxuICAgIGhpZ2hsaWdodC5jb2xvcixcbiAgICB0cnVlLFxuICAgIElEX0FOTk9UQVRJT05fQ09OVEFJTkVSXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUhpZ2hsaWdodERvbSh3aW4sIGhpZ2hsaWdodCwgYW5ub3RhdGlvbkZsYWcpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG5cbiAgY29uc3Qgc2NhbGUgPVxuICAgIDEgL1xuICAgICh3aW4uUkVBRElVTTIgJiYgd2luLlJFQURJVU0yLmlzRml4ZWRMYXlvdXRcbiAgICAgID8gd2luLlJFQURJVU0yLmZ4bFZpZXdwb3J0U2NhbGVcbiAgICAgIDogMSk7XG5cbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuXG4gIGNvbnN0IHJhbmdlID0gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgaGlnaGxpZ2h0LnJhbmdlSW5mbyk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBoaWdobGlnaHRzQ29udGFpbmVyID0gZW5zdXJlQ29udGFpbmVyKHdpbiwgYW5ub3RhdGlvbkZsYWcpO1xuICBjb25zdCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG4gIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBoaWdobGlnaHQuaWQpO1xuICBoaWdobGlnaHRQYXJlbnQuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUik7XG5cbiAgZG9jdW1lbnQuYm9keS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcbiAgaGlnaGxpZ2h0UGFyZW50LnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICBpZiAoaGlnaGxpZ2h0LnBvaW50ZXJJbnRlcmFjdGlvbikge1xuICAgIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJkYXRhLWNsaWNrXCIsIFwiMVwiKTtcbiAgfVxuXG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgY29uc3QgdXNlU1ZHID0gIURFQlVHX1ZJU1VBTFMgJiYgVVNFX1NWRztcbiAgLy9jb25zdCB1c2VTVkcgPSBVU0VfU1ZHO1xuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgbGV0IGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnO1xuICBjb25zdCByb3VuZGVkQ29ybmVyID0gMztcbiAgY29uc3QgdW5kZXJsaW5lVGhpY2tuZXNzID0gMjtcbiAgY29uc3Qgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgPSAzO1xuICBjb25zdCBvcGFjaXR5ID0gREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFk7XG4gIGxldCBleHRyYSA9IFwiXCI7XG4gIGNvbnN0IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdCA9XG4gICAgZnJhbWVGb3JIaWdobGlnaHRBbm5vdGF0aW9uTWFya1dpdGhJRCh3aW4sIGhpZ2hsaWdodC5pZCk7XG5cbiAgbGV0IHhPZmZzZXQ7XG4gIGxldCB5T2Zmc2V0O1xuICBsZXQgYW5ub3RhdGlvbk9mZnNldDtcblxuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0IDogYm9keVJlY3QubGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICAgIGFubm90YXRpb25PZmZzZXQgPVxuICAgICAgcGFyc2VJbnQoXG4gICAgICAgIChyYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QucmlnaHQgLSB4T2Zmc2V0KSAvIHdpbmRvdy5pbm5lcldpZHRoXG4gICAgICApICsgMTtcbiAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICAgIGFubm90YXRpb25PZmZzZXQgPSBwYXJzZUludChcbiAgICAgIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5yaWdodCAvIHdpbmRvdy5pbm5lcldpZHRoICsgMVxuICAgICk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBpZiAodXNlU1ZHKSB7XG4gICAgICBjb25zdCBib3JkZXJUaGlja25lc3MgPSAwO1xuICAgICAgaWYgKCFoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZykge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdSZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICBTVkdfWE1MX05BTUVTUEFDRSxcbiAgICAgICAgXCJyZWN0XCJcbiAgICAgICk7XG5cbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICBgZmlsbDogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pICFpbXBvcnRhbnQ7IGZpbGwtb3BhY2l0eTogJHtvcGFjaXR5fSAhaW1wb3J0YW50OyBzdHJva2Utd2lkdGg6IDA7YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNjYWxlID0gc2NhbGU7XG5cbiAgICAgIC8qXG4gICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdCA9IHtcbiAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAqL1xuXG4gICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwicnhcIiwgYCR7cm91bmRlZENvcm5lciAqIHNjYWxlfWApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwicnlcIiwgYCR7cm91bmRlZENvcm5lciAqIHNjYWxlfWApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInhcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QubGVmdCAtIGJvcmRlclRoaWNrbmVzcykgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInlcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QudG9wIC0gYm9yZGVyVGhpY2tuZXNzKSAqIHNjYWxlfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0LmhlaWdodCArIGJvcmRlclRoaWNrbmVzcyAqIDIpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJ3aWR0aFwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC53aWR0aCArIGJvcmRlclRoaWNrbmVzcyAqIDIpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnLmFwcGVuZENoaWxkKGhpZ2hsaWdodEFyZWFTVkdSZWN0KTtcbiAgICAgIGlmIChkcmF3VW5kZXJsaW5lKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICAgIFwibGluZVwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgICBgc3Ryb2tlLWxpbmVjYXA6IHJvdW5kOyBzdHJva2Utd2lkdGg6ICR7XG4gICAgICAgICAgICB1bmRlcmxpbmVUaGlja25lc3MgKiBzY2FsZVxuICAgICAgICAgIH07IHN0cm9rZTogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSkgIWltcG9ydGFudDsgc3Ryb2tlLW9wYWNpdHk6ICR7b3BhY2l0eX0gIWltcG9ydGFudGBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGluZU9mZnNldCA9XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCA+IHJvdW5kZWRDb3JuZXIgPyByb3VuZGVkQ29ybmVyIDogMDtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDFcIixcbiAgICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICsgbGluZU9mZnNldCkgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngyXCIsXG4gICAgICAgICAgYCR7XG4gICAgICAgICAgICAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICtcbiAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAtXG4gICAgICAgICAgICAgIGxpbmVPZmZzZXQpICpcbiAgICAgICAgICAgIHNjYWxlXG4gICAgICAgICAgfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgeSA9XG4gICAgICAgICAgKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QudG9wICtcbiAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0IC1cbiAgICAgICAgICAgIHVuZGVybGluZVRoaWNrbmVzcyAvIDIpICpcbiAgICAgICAgICBzY2FsZTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTFcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTJcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIndpZHRoXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0QXJlYVNWR0xpbmUpO1xuICAgICAgfVxuICAgICAgaWYgKGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICAgIFwibGluZVwiXG4gICAgICAgICk7XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICAgIGBzdHJva2UtbGluZWNhcDogYnV0dDsgc3Ryb2tlLXdpZHRoOiAke1xuICAgICAgICAgICAgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgKiBzY2FsZVxuICAgICAgICAgIH07IHN0cm9rZTogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSkgIWltcG9ydGFudDsgc3Ryb2tlLW9wYWNpdHk6ICR7b3BhY2l0eX0gIWltcG9ydGFudGBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2NhbGUgPSBzY2FsZTtcblxuICAgICAgICAvKlxuICAgICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngxXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ4MlwiLFxuICAgICAgICAgIGAke1xuICAgICAgICAgICAgKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QubGVmdCArIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGgpICpcbiAgICAgICAgICAgIHNjYWxlXG4gICAgICAgICAgfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbGluZU9mZnNldCA9IGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgY29uc3QgeSA9IChoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LnRvcCArIGxpbmVPZmZzZXQpICogc2NhbGU7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkxXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkyXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcImhlaWdodFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0ICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ3aWR0aFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGggKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnLmFwcGVuZENoaWxkKGhpZ2hsaWdodEFyZWFTVkdMaW5lKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgICAgIGhpZ2hsaWdodEFyZWEuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuXG4gICAgICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgICAgICBjb25zdCByZ2IgPSBNYXRoLnJvdW5kKDB4ZmZmZmZmICogTWF0aC5yYW5kb20oKSk7XG4gICAgICAgIGNvbnN0IHIgPSByZ2IgPj4gMTY7XG4gICAgICAgIGNvbnN0IGcgPSAocmdiID4+IDgpICYgMjU1O1xuICAgICAgICBjb25zdCBiID0gcmdiICYgMjU1O1xuICAgICAgICBleHRyYSA9IGBvdXRsaW5lLWNvbG9yOiByZ2IoJHtyfSwgJHtnfSwgJHtifSk7IG91dGxpbmUtc3R5bGU6IHNvbGlkOyBvdXRsaW5lLXdpZHRoOiAxcHg7IG91dGxpbmUtb2Zmc2V0OiAtMXB4O2A7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZHJhd1VuZGVybGluZSkge1xuICAgICAgICAgIGV4dHJhICs9IGBib3JkZXItYm90dG9tOiAke3VuZGVybGluZVRoaWNrbmVzcyAqIHNjYWxlfXB4IHNvbGlkIHJnYmEoJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5yZWRcbiAgICAgICAgICB9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7XG4gICAgICAgICAgICBoaWdobGlnaHQuY29sb3IuYmx1ZVxuICAgICAgICAgIH0sICR7b3BhY2l0eX0pICFpbXBvcnRhbnRgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoaWdobGlnaHRBcmVhLnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICBgYm9yZGVyLXJhZGl1czogJHtyb3VuZGVkQ29ybmVyfXB4ICFpbXBvcnRhbnQ7IGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDsgJHtleHRyYX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gICAgICBoaWdobGlnaHRBcmVhLnNjYWxlID0gc2NhbGU7XG4gICAgICAvKlxuICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAqL1xuICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnJlY3QgPSB7XG4gICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLndpZHRoID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LndpZHRoICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5oZWlnaHQgPSBgJHtoaWdobGlnaHRBcmVhLnJlY3QuaGVpZ2h0ICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5sZWZ0ID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LmxlZnQgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnRvcCA9IGAke2hpZ2hsaWdodEFyZWEucmVjdC50b3AgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRQYXJlbnQuYXBwZW5kKGhpZ2hsaWdodEFyZWEpO1xuICAgICAgaWYgKCFERUJVR19WSVNVQUxTICYmIGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIC8vaWYgKGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgICAgYGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDtgXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdCA9IHtcbiAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqL1xuXG4gICAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS53aWR0aCA9IGAke1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3Qud2lkdGggKiBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5oZWlnaHQgPSBgJHtcbiAgICAgICAgICBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyAqIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLmxlZnQgPSBgJHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0LmxlZnQgKiBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS50b3AgPSBgJHtcbiAgICAgICAgICAoaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC50b3AgK1xuICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC5oZWlnaHQgLyAyIC1cbiAgICAgICAgICAgIHN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzIC8gMikgKlxuICAgICAgICAgIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYUxpbmUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZykge1xuICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX1hNTF9OQU1FU1BBQ0UsIFwic3ZnXCIpO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc2V0QXR0cmlidXRlKFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS5vdmVyZmxvdyA9IFwidmlzaWJsZVwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUubGVmdCA9IFwiMFwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUudG9wID0gXCIwXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5hcHBlbmQoaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcpO1xuICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYVNWRyk7XG4gIH1cblxuICBjb25zdCBoaWdobGlnaHRCb3VuZGluZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBKTtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXG4gICAgICBcInN0eWxlXCIsXG4gICAgICBgYm9yZGVyLXJhZGl1czogJHtyb3VuZGVkQ29ybmVyfXB4ICFpbXBvcnRhbnQ7IGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDsgJHtleHRyYX1gXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSk7XG4gIH1cblxuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnNjYWxlID0gc2NhbGU7XG5cbiAgaWYgKERFQlVHX1ZJU1VBTFMpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXG4gICAgICBcInN0eWxlXCIsXG4gICAgICBgb3V0bGluZS1jb2xvcjogbWFnZW50YTsgb3V0bGluZS1zdHlsZTogc29saWQ7IG91dGxpbmUtd2lkdGg6IDFweDsgb3V0bGluZS1vZmZzZXQ6IC0xcHg7YFxuICAgICk7XG4gIH1cblxuICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5yZWN0ID0ge1xuICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QgPSByYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5yZWN0ID0ge1xuICAgICAgaGVpZ2h0OiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgIHRvcDogcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgIHdpZHRoOiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9O1xuICB9XG5cbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUud2lkdGggPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LndpZHRoICogc2NhbGV9cHhgO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5oZWlnaHQgPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LmhlaWdodCAqIHNjYWxlfXB4YDtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUubGVmdCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3QubGVmdCAqIHNjYWxlfXB4YDtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUudG9wID0gYCR7aGlnaGxpZ2h0Qm91bmRpbmcucmVjdC50b3AgKiBzY2FsZX1weGA7XG5cbiAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRCb3VuZGluZyk7XG4gIGhpZ2hsaWdodHNDb250YWluZXIuYXBwZW5kKGhpZ2hsaWdodFBhcmVudCk7XG5cbiAgcmV0dXJuIGhpZ2hsaWdodFBhcmVudDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT3JkZXJlZFJhbmdlKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQsIGVuZE5vZGUsIGVuZE9mZnNldCkge1xuICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZS5zZXRTdGFydChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIGlmICghcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGNvbnNvbGUubG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBDT0xMQVBTRUQgLi4uIFJBTkdFIFJFVkVSU0U/XCIpO1xuICBjb25zdCByYW5nZVJldmVyc2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2VSZXZlcnNlLnNldFN0YXJ0KGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRFbmQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIGlmICghcmFuZ2VSZXZlcnNlLmNvbGxhcHNlZCkge1xuICAgIGNvbnNvbGUubG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIE9LLlwiKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgY29uc29sZS5sb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgQUxTTyBDT0xMQVBTRUQ/IVwiKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gY29udmVydFJhbmdlKHJhbmdlLCBnZXRDc3NTZWxlY3RvciwgY29tcHV0ZUVsZW1lbnRDRkkpIHtcbiAgY29uc3Qgc3RhcnRJc0VsZW1lbnQgPSByYW5nZS5zdGFydENvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyRWxlbWVudCA9IHN0YXJ0SXNFbGVtZW50XG4gICAgPyByYW5nZS5zdGFydENvbnRhaW5lclxuICAgIDogcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZSAmJlxuICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICA/IHJhbmdlLnN0YXJ0Q29udGFpbmVyLnBhcmVudE5vZGVcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKCFzdGFydENvbnRhaW5lckVsZW1lbnQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID0gc3RhcnRJc0VsZW1lbnRcbiAgICA/IC0xXG4gICAgOiBBcnJheS5mcm9tKHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzKS5pbmRleE9mKFxuICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lclxuICAgICAgKTtcbiAgaWYgKHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IDwgLTEpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yID0gZ2V0Q3NzU2VsZWN0b3IoXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50XG4gICk7XG4gIGNvbnN0IGVuZElzRWxlbWVudCA9IHJhbmdlLmVuZENvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7XG4gIGNvbnN0IGVuZENvbnRhaW5lckVsZW1lbnQgPSBlbmRJc0VsZW1lbnRcbiAgICA/IHJhbmdlLmVuZENvbnRhaW5lclxuICAgIDogcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGUgJiZcbiAgICAgIHJhbmdlLmVuZENvbnRhaW5lci5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgID8gcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGVcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKCFlbmRDb250YWluZXJFbGVtZW50KSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPSBlbmRJc0VsZW1lbnRcbiAgICA/IC0xXG4gICAgOiBBcnJheS5mcm9tKGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2RlcykuaW5kZXhPZihyYW5nZS5lbmRDb250YWluZXIpO1xuICBpZiAoZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IDwgLTEpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciA9IGdldENzc1NlbGVjdG9yKGVuZENvbnRhaW5lckVsZW1lbnQpO1xuICBjb25zdCBjb21tb25FbGVtZW50QW5jZXN0b3IgPSBnZXRDb21tb25BbmNlc3RvckVsZW1lbnQoXG4gICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2UuZW5kQ29udGFpbmVyXG4gICk7XG4gIGlmICghY29tbW9uRWxlbWVudEFuY2VzdG9yKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gTk8gUkFOR0UgQ09NTU9OIEFOQ0VTVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAocmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIpIHtcbiAgICBjb25zdCByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCA9XG4gICAgICByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICAgICAgPyByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lclxuICAgICAgICA6IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQgJiZcbiAgICAgIHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50Lm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgICkge1xuICAgICAgaWYgKGNvbW1vbkVsZW1lbnRBbmNlc3RvciAhPT0gcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCI+Pj4+Pj4gQ09NTU9OIEFOQ0VTVE9SIENPTlRBSU5FUiBESUZGPz8hXCIpO1xuICAgICAgICBjb25zb2xlLmxvZyhnZXRDc3NTZWxlY3Rvcihjb21tb25FbGVtZW50QW5jZXN0b3IpKTtcbiAgICAgICAgY29uc29sZS5sb2coZ2V0Q3NzU2VsZWN0b3IocmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3Qgcm9vdEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShjb21tb25FbGVtZW50QW5jZXN0b3IpO1xuICBjb25zdCBzdGFydEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShzdGFydENvbnRhaW5lckVsZW1lbnQpO1xuICBjb25zdCBlbmRFbGVtZW50Q2ZpID0gY29tcHV0ZUVsZW1lbnRDRkkoZW5kQ29udGFpbmVyRWxlbWVudCk7XG4gIGxldCBjZmk7XG4gIGlmIChyb290RWxlbWVudENmaSAmJiBzdGFydEVsZW1lbnRDZmkgJiYgZW5kRWxlbWVudENmaSkge1xuICAgIGxldCBzdGFydEVsZW1lbnRPclRleHRDZmkgPSBzdGFydEVsZW1lbnRDZmk7XG4gICAgaWYgKCFzdGFydElzRWxlbWVudCkge1xuICAgICAgY29uc3Qgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkgPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXJcbiAgICAgICk7XG4gICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICBzdGFydEVsZW1lbnRDZmkgK1xuICAgICAgICBcIi9cIiArXG4gICAgICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpICtcbiAgICAgICAgXCI6XCIgK1xuICAgICAgICByYW5nZS5zdGFydE9mZnNldDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICByYW5nZS5zdGFydE9mZnNldCA+PSAwICYmXG4gICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0IDwgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgY2hpbGROb2RlID0gc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2Uuc3RhcnRPZmZzZXRdO1xuICAgICAgICBpZiAoY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIChyYW5nZS5zdGFydE9mZnNldCArIDEpICogMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBjZmlUZXh0Tm9kZUluZGV4ID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LFxuICAgICAgICAgICAgY2hpbGROb2RlXG4gICAgICAgICAgKTtcbiAgICAgICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPSBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIGNmaVRleHROb2RlSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNmaUluZGV4T2ZMYXN0RWxlbWVudCA9XG4gICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkRWxlbWVudENvdW50ICogMjtcbiAgICAgICAgY29uc3QgbGFzdENoaWxkTm9kZSA9XG4gICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbXG4gICAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggLSAxXG4gICAgICAgICAgXTtcbiAgICAgICAgaWYgKGxhc3RDaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIChjZmlJbmRleE9mTGFzdEVsZW1lbnQgKyAyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBsZXQgZW5kRWxlbWVudE9yVGV4dENmaSA9IGVuZEVsZW1lbnRDZmk7XG4gICAgaWYgKCFlbmRJc0VsZW1lbnQpIHtcbiAgICAgIGNvbnN0IGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSA9IGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChcbiAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgICApO1xuICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgIGVuZEVsZW1lbnRDZmkgK1xuICAgICAgICBcIi9cIiArXG4gICAgICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSArXG4gICAgICAgIFwiOlwiICtcbiAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIHJhbmdlLmVuZE9mZnNldCA+PSAwICYmXG4gICAgICAgIHJhbmdlLmVuZE9mZnNldCA8IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2UuZW5kT2Zmc2V0XTtcbiAgICAgICAgaWYgKGNoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID0gZW5kRWxlbWVudENmaSArIFwiL1wiICsgKHJhbmdlLmVuZE9mZnNldCArIDEpICogMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBjZmlUZXh0Tm9kZUluZGV4ID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgICAgIGNoaWxkTm9kZVxuICAgICAgICAgICk7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9IGVuZEVsZW1lbnRDZmkgKyBcIi9cIiArIGNmaVRleHROb2RlSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNmaUluZGV4T2ZMYXN0RWxlbWVudCA9IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQgKiAyO1xuICAgICAgICBjb25zdCBsYXN0Q2hpbGROb2RlID1cbiAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbXG4gICAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoIC0gMVxuICAgICAgICAgIF07XG4gICAgICAgIGlmIChsYXN0Q2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgZW5kRWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgZW5kRWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNmaSA9XG4gICAgICByb290RWxlbWVudENmaSArXG4gICAgICBcIixcIiArXG4gICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkucmVwbGFjZShyb290RWxlbWVudENmaSwgXCJcIikgK1xuICAgICAgXCIsXCIgK1xuICAgICAgZW5kRWxlbWVudE9yVGV4dENmaS5yZXBsYWNlKHJvb3RFbGVtZW50Q2ZpLCBcIlwiKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGNmaSxcbiAgICBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIGVuZE9mZnNldDogcmFuZ2UuZW5kT2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiByYW5nZS5zdGFydE9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgcmFuZ2VJbmZvKSB7XG4gIGNvbnN0IHN0YXJ0RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghc3RhcnRFbGVtZW50KSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBTVEFSVCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IHN0YXJ0Q29udGFpbmVyID0gc3RhcnRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBzdGFydENvbnRhaW5lciA9XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICBjb25zdCBlbmRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghZW5kRWxlbWVudCkge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gRU5EIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgZW5kQ29udGFpbmVyID0gZW5kRWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVuZENvbnRhaW5lciA9XG4gICAgICBlbmRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICBzdGFydENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uc3RhcnRPZmZzZXQsXG4gICAgZW5kQ29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5lbmRPZmZzZXRcbiAgKTtcbn1cblxuZnVuY3Rpb24gZnJhbWVGb3JIaWdobGlnaHRBbm5vdGF0aW9uTWFya1dpdGhJRCh3aW4sIGlkKSB7XG4gIGxldCBjbGllbnRSZWN0cyA9IGZyYW1lRm9ySGlnaGxpZ2h0V2l0aElEKGlkKTtcbiAgaWYgKCFjbGllbnRSZWN0cykgcmV0dXJuO1xuXG4gIHZhciB0b3BDbGllbnRSZWN0ID0gY2xpZW50UmVjdHNbMF07XG4gIHZhciBtYXhIZWlnaHQgPSB0b3BDbGllbnRSZWN0LmhlaWdodDtcbiAgZm9yIChjb25zdCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgaWYgKGNsaWVudFJlY3QudG9wIDwgdG9wQ2xpZW50UmVjdC50b3ApIHRvcENsaWVudFJlY3QgPSBjbGllbnRSZWN0O1xuICAgIGlmIChjbGllbnRSZWN0LmhlaWdodCA+IG1heEhlaWdodCkgbWF4SGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQ7XG4gIH1cblxuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeU9mZnNldDtcbiAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICB2YXIgbmV3VG9wID0gdG9wQ2xpZW50UmVjdC50b3A7XG5cbiAgaWYgKF9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgZG8ge1xuICAgICAgdmFyIGJvdW5kaW5nQXJlYXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFxuICAgICAgICBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcbiAgICAgICk7XG4gICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgIC8vZm9yIChsZXQgaSA9IDAsIGxlbmd0aCA9IGJvdW5kaW5nQXJlYXMuc25hcHNob3RMZW5ndGg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgZm9yIChcbiAgICAgICAgdmFyIGkgPSAwLCBsZW4gPSBib3VuZGluZ0FyZWFzLmxlbmd0aCB8IDA7XG4gICAgICAgIGkgPCBsZW47XG4gICAgICAgIGkgPSAoaSArIDEpIHwgMFxuICAgICAgKSB7XG4gICAgICAgIHZhciBib3VuZGluZ0FyZWEgPSBib3VuZGluZ0FyZWFzW2ldO1xuICAgICAgICBpZiAoTWF0aC5hYnMoYm91bmRpbmdBcmVhLnJlY3QudG9wIC0gKG5ld1RvcCAtIHlPZmZzZXQpKSA8IDMpIHtcbiAgICAgICAgICBuZXdUb3AgKz0gYm91bmRpbmdBcmVhLnJlY3QuaGVpZ2h0O1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gd2hpbGUgKGZvdW5kKTtcbiAgfVxuXG4gIHRvcENsaWVudFJlY3QudG9wID0gbmV3VG9wO1xuICB0b3BDbGllbnRSZWN0LmhlaWdodCA9IG1heEhlaWdodDtcblxuICByZXR1cm4gdG9wQ2xpZW50UmVjdDtcbn1cblxuZnVuY3Rpb24gaGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGxldCBpID0gLTE7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzLmZpbmQoKGgsIGopID0+IHtcbiAgICBpID0gajtcbiAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gIH0pO1xuICByZXR1cm4gaGlnaGxpZ2h0O1xufVxuXG5mdW5jdGlvbiBmcmFtZUZvckhpZ2hsaWdodFdpdGhJRChpZCkge1xuICBjb25zdCBoaWdobGlnaHQgPSBoaWdobGlnaHRXaXRoSUQoaWQpO1xuICBpZiAoIWhpZ2hsaWdodCkgcmV0dXJuO1xuXG4gIGNvbnN0IGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHJhbmdlID0gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgaGlnaGxpZ2h0LnJhbmdlSW5mbyk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgZHJhd1VuZGVybGluZSA9IGZhbHNlO1xuICBjb25zdCBkcmF3U3RyaWtlVGhyb3VnaCA9IGZhbHNlO1xuICBjb25zdCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gZHJhd1VuZGVybGluZSB8fCBkcmF3U3RyaWtlVGhyb3VnaDtcbiAgLy9jb25zdCBjbGllbnRSZWN0cyA9IERFQlVHX1ZJU1VBTFMgPyByYW5nZS5nZXRDbGllbnRSZWN0cygpIDpcbiAgY29uc3QgY2xpZW50UmVjdHMgPSBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgICByYW5nZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG5cbiAgcmV0dXJuIGNsaWVudFJlY3RzO1xufVxuXG5mdW5jdGlvbiByYW5nZUluZm8yTG9jYXRpb24ocmFuZ2VJbmZvKSB7XG4gIHJldHVybiB7XG4gICAgY3NzU2VsZWN0b3I6IHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICBwYXJ0aWFsQ2ZpOiByYW5nZUluZm8uY2ZpLFxuICAgIGRvbVJhbmdlOiB7XG4gICAgICBzdGFydDoge1xuICAgICAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgICAgICB0ZXh0Tm9kZUluZGV4OiByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgICAgIG9mZnNldDogcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgICAgfSxcbiAgICAgIGVuZDoge1xuICAgICAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICAgICAgdGV4dE5vZGVJbmRleDogcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICAgICAgb2Zmc2V0OiByYW5nZUluZm8uZW5kT2Zmc2V0LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb24pIHtcbiAgY29uc3QgbG9jYXRpb25zID0gbG9jYXRpb24ubG9jYXRpb25zO1xuICBjb25zdCBkb21SYW5nZSA9IGxvY2F0aW9ucy5kb21SYW5nZTtcbiAgY29uc3Qgc3RhcnQgPSBkb21SYW5nZS5zdGFydDtcbiAgY29uc3QgZW5kID0gZG9tUmFuZ2UuZW5kO1xuXG4gIHJldHVybiB7XG4gICAgY2ZpOiBsb2NhdGlvbi5wYXJ0aWFsQ2ZpLFxuICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogZW5kLnRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBlbmQuY3NzU2VsZWN0b3IsXG4gICAgZW5kT2Zmc2V0OiBlbmQub2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBzdGFydC50ZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBzdGFydC5jc3NTZWxlY3RvcixcbiAgICBzdGFydE9mZnNldDogc3RhcnQub2Zmc2V0LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IGhpZ2hsaWdodFdpdGhJRChpZCk7XG4gIGlmICghaGlnaGxpZ2h0KSByZXR1cm47XG5cbiAgY29uc3QgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgcmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCBoaWdobGlnaHQucmFuZ2VJbmZvKTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgdmFyIHNpemUgPSB7XG4gICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgIHNjcmVlbkhlaWdodDogd2luZG93Lm91dGVySGVpZ2h0LFxuICAgIGxlZnQ6IGNsaWVudFJlY3RzWzBdLmxlZnQsXG4gICAgd2lkdGg6IGNsaWVudFJlY3RzWzBdLndpZHRoLFxuICAgIHRvcDogY2xpZW50UmVjdHNbMF0udG9wLFxuICAgIGhlaWdodDogY2xpZW50UmVjdHNbMF0uaGVpZ2h0LFxuICB9O1xuXG4gIHJldHVybiBzaXplO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0aW9uUmVjdCgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciByYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuXG4gICAgY29uc3QgY2xpZW50UmVjdCA9IHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdmFyIGhhbmRsZUJvdW5kcyA9IHtcbiAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgIHNjcmVlbkhlaWdodDogd2luZG93Lm91dGVySGVpZ2h0LFxuICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0LFxuICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICB0b3A6IGNsaWVudFJlY3QudG9wLFxuICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICB9O1xuICAgIHJldHVybiBoYW5kbGVCb3VuZHM7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0U2Nyb2xsTW9kZShmbGFnKSB7XG4gIGlmICghZmxhZykge1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX1BBR0lOQVRFRCk7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfUEFHSU5BVEVEKTtcbiAgfVxufVxuXG4vKlxuIGlmIChkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKSB7IC8vIElFID49IDk7IG90aGVyIGJyb3dzZXJzXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgLy9hbGVydChcIllvdSd2ZSB0cmllZCB0byBvcGVuIGNvbnRleHQgbWVudVwiKTsgLy9oZXJlIHlvdSBkcmF3IHlvdXIgb3duIG1lbnVcbiAgICAgICAgICAgIC8vZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgLy9sZXQgZ2V0Q3NzU2VsZWN0b3IgPSBmdWxsUXVhbGlmaWVkU2VsZWN0b3I7XG4gICAgICAgICAgICBcblx0XHRcdGxldCBzdHIgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG5cdFx0XHRsZXQgc2VsZWN0aW9uSW5mbyA9IGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvKCk7XG5cdFx0XHRsZXQgcG9zID0gY3JlYXRlSGlnaGxpZ2h0KHNlbGVjdGlvbkluZm8se3JlZDoxMCxncmVlbjo1MCxibHVlOjIzMH0sdHJ1ZSk7XG5cdFx0XHRsZXQgcmV0MiA9IGNyZWF0ZUFubm90YXRpb24ocG9zLmlkKTtcblx0XHRcdFxuICB9LCBmYWxzZSk7XG4gICAgfSBlbHNlIHsgLy8gSUUgPCA5XG4gICAgICAgIGRvY3VtZW50LmF0dGFjaEV2ZW50KCdvbmNvbnRleHRtZW51JywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBhbGVydChcIllvdSd2ZSB0cmllZCB0byBvcGVuIGNvbnRleHQgbWVudVwiKTtcbiAgICAgICAgICAgIHdpbmRvdy5ldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG4qL1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMiBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgaXNTY3JvbGxNb2RlRW5hYmxlZCB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBnZXRDc3NTZWxlY3RvciB9IGZyb20gXCJjc3Mtc2VsZWN0b3ItZ2VuZXJhdG9yXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kRmlyc3RWaXNpYmxlTG9jYXRvcigpIHtcbiAgY29uc3QgZWxlbWVudCA9IGZpbmRFbGVtZW50KGRvY3VtZW50LmJvZHkpO1xuICByZXR1cm4ge1xuICAgIGhyZWY6IFwiI1wiLFxuICAgIHR5cGU6IFwiYXBwbGljYXRpb24veGh0bWwreG1sXCIsXG4gICAgbG9jYXRpb25zOiB7XG4gICAgICBjc3NTZWxlY3RvcjogZ2V0Q3NzU2VsZWN0b3IoZWxlbWVudCksXG4gICAgfSxcbiAgICB0ZXh0OiB7XG4gICAgICBoaWdobGlnaHQ6IGVsZW1lbnQudGV4dENvbnRlbnQsXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmluZEVsZW1lbnQocm9vdEVsZW1lbnQpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByb290RWxlbWVudC5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkID0gcm9vdEVsZW1lbnQuY2hpbGRyZW5baV07XG4gICAgaWYgKCFzaG91bGRJZ25vcmVFbGVtZW50KGNoaWxkKSAmJiBpc0VsZW1lbnRWaXNpYmxlKGNoaWxkKSkge1xuICAgICAgcmV0dXJuIGZpbmRFbGVtZW50KGNoaWxkKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJvb3RFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBpc0VsZW1lbnRWaXNpYmxlKGVsZW1lbnQpIHtcbiAgaWYgKHJlYWRpdW0uaXNGaXhlZExheW91dCkgcmV0dXJuIHRydWU7XG5cbiAgaWYgKGVsZW1lbnQgPT09IGRvY3VtZW50LmJvZHkgfHwgZWxlbWVudCA9PT0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKCFkb2N1bWVudCB8fCAhZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8ICFkb2N1bWVudC5ib2R5KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGlmIChpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICByZXR1cm4gcmVjdC5ib3R0b20gPiAwICYmIHJlY3QudG9wIDwgd2luZG93LmlubmVySGVpZ2h0O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiByZWN0LnJpZ2h0ID4gMCAmJiByZWN0LmxlZnQgPCB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRJZ25vcmVFbGVtZW50KGVsZW1lbnQpIHtcbiAgY29uc3QgZWxTdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gIGlmIChlbFN0eWxlKSB7XG4gICAgY29uc3QgZGlzcGxheSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcImRpc3BsYXlcIik7XG4gICAgaWYgKGRpc3BsYXkgIT0gXCJibG9ja1wiKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gQ2Fubm90IGJlIHJlbGllZCB1cG9uLCBiZWNhdXNlIHdlYiBicm93c2VyIGVuZ2luZSByZXBvcnRzIGludmlzaWJsZSB3aGVuIG91dCBvZiB2aWV3IGluXG4gICAgLy8gc2Nyb2xsZWQgY29sdW1ucyFcbiAgICAvLyBjb25zdCB2aXNpYmlsaXR5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwidmlzaWJpbGl0eVwiKTtcbiAgICAvLyBpZiAodmlzaWJpbGl0eSA9PT0gXCJoaWRkZW5cIikge1xuICAgIC8vICAgICByZXR1cm4gZmFsc2U7XG4gICAgLy8gfVxuICAgIGNvbnN0IG9wYWNpdHkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJvcGFjaXR5XCIpO1xuICAgIGlmIChvcGFjaXR5ID09PSBcIjBcIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgbG9nIGFzIGxvZ05hdGl2ZSwgbG9nRXJyb3IsIHNuYXBDdXJyZW50T2Zmc2V0IH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IHRvTmF0aXZlUmVjdCB9IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IFRleHRSYW5nZSB9IGZyb20gXCIuL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90ZXh0LXJhbmdlXCI7XG5cbi8vIFBvbHlmaWxsIGZvciBBbmRyb2lkIEFQSSAyNlxuaW1wb3J0IG1hdGNoQWxsIGZyb20gXCJzdHJpbmcucHJvdG90eXBlLm1hdGNoYWxsXCI7XG5tYXRjaEFsbC5zaGltKCk7XG5cbmNvbnN0IGRlYnVnID0gdHJ1ZTtcblxuLy8gTm90aWZ5IG5hdGl2ZSBjb2RlIHRoYXQgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwibG9hZFwiLFxuICBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGlzU2VsZWN0aW5nID0gZmFsc2U7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2xsYXBzZWQgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuaXNDb2xsYXBzZWQ7XG5cbiAgICAgIGlmIChjb2xsYXBzZWQgJiYgaXNTZWxlY3RpbmcpIHtcbiAgICAgICAgaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgQW5kcm9pZC5vblNlbGVjdGlvbkVuZCgpO1xuICAgICAgICAvLyBTbmFwcyB0aGUgY3VycmVudCBjb2x1bW4gaW4gY2FzZSB0aGUgdXNlciBzaGlmdGVkIHRoZSBzY3JvbGwgYnkgZHJhZ2dpbmcgdGhlIHRleHQgc2VsZWN0aW9uLlxuICAgICAgICBzbmFwQ3VycmVudE9mZnNldCgpO1xuICAgICAgfSBlbHNlIGlmICghY29sbGFwc2VkICYmICFpc1NlbGVjdGluZykge1xuICAgICAgICBpc1NlbGVjdGluZyA9IHRydWU7XG4gICAgICAgIEFuZHJvaWQub25TZWxlY3Rpb25TdGFydCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICBmYWxzZVxuKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb24oKSB7XG4gIGNvbnN0IHRleHQgPSBnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCgpO1xuICBpZiAoIXRleHQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCByZWN0ID0gZ2V0U2VsZWN0aW9uUmVjdCgpO1xuICByZXR1cm4geyB0ZXh0LCByZWN0IH07XG59XG5cbmZ1bmN0aW9uIGdldFNlbGVjdGlvblJlY3QoKSB7XG4gIHRyeSB7XG4gICAgbGV0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmFuZ2UgPSBzZWwuZ2V0UmFuZ2VBdCgwKTtcblxuICAgIHJldHVybiB0b05hdGl2ZVJlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nRXJyb3IoZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvblRleHQoKSB7XG4gIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGhpZ2hsaWdodCA9IHNlbGVjdGlvbi50b1N0cmluZygpO1xuICBjb25zdCBjbGVhbkhpZ2hsaWdodCA9IGhpZ2hsaWdodFxuICAgIC50cmltKClcbiAgICAucmVwbGFjZSgvXFxuL2csIFwiIFwiKVxuICAgIC5yZXBsYWNlKC9cXHNcXHMrL2csIFwiIFwiKTtcbiAgaWYgKGNsZWFuSGlnaGxpZ2h0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFzZWxlY3Rpb24uYW5jaG9yTm9kZSB8fCAhc2VsZWN0aW9uLmZvY3VzTm9kZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2UgPVxuICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxXG4gICAgICA/IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApXG4gICAgICA6IGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0XG4gICAgICAgICk7XG4gIGlmICghcmFuZ2UgfHwgcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgbG9nKFwiJCQkJCQkJCQkJCQkJCQkJCQgQ0FOTk9UIEdFVCBOT04tQ09MTEFQU0VEIFNFTEVDVElPTiBSQU5HRT8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCB0ZXh0ID0gZG9jdW1lbnQuYm9keS50ZXh0Q29udGVudDtcbiAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhkb2N1bWVudC5ib2R5KTtcbiAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICBjb25zdCBlbmQgPSB0ZXh0UmFuZ2UuZW5kLm9mZnNldDtcblxuICBjb25zdCBzbmlwcGV0TGVuZ3RoID0gMjAwO1xuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYmVmb3JlIHRoZSBoaWdobGlnaHQsIGlnbm9yaW5nIHRoZSBmaXJzdCBcIndvcmRcIiwgd2hpY2ggbWlnaHQgYmUgY3V0LlxuICBsZXQgYmVmb3JlID0gdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIHNuaXBwZXRMZW5ndGgpLCBzdGFydCk7XG4gIGxldCBmaXJzdFdvcmRTdGFydCA9IGJlZm9yZS5zZWFyY2goL1xcUHtMfVxccHtMfS9ndSk7XG4gIGlmIChmaXJzdFdvcmRTdGFydCAhPT0gLTEpIHtcbiAgICBiZWZvcmUgPSBiZWZvcmUuc2xpY2UoZmlyc3RXb3JkU3RhcnQgKyAxKTtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYWZ0ZXIgdGhlIGhpZ2hsaWdodCwgaWdub3JpbmcgdGhlIGxhc3QgXCJ3b3JkXCIsIHdoaWNoIG1pZ2h0IGJlIGN1dC5cbiAgbGV0IGFmdGVyID0gdGV4dC5zbGljZShlbmQsIE1hdGgubWluKHRleHQubGVuZ3RoLCBlbmQgKyBzbmlwcGV0TGVuZ3RoKSk7XG4gIGxldCBsYXN0V29yZEVuZCA9IEFycmF5LmZyb20oYWZ0ZXIubWF0Y2hBbGwoL1xccHtMfVxcUHtMfS9ndSkpLnBvcCgpO1xuICBpZiAobGFzdFdvcmRFbmQgIT09IHVuZGVmaW5lZCAmJiBsYXN0V29yZEVuZC5pbmRleCA+IDEpIHtcbiAgICBhZnRlciA9IGFmdGVyLnNsaWNlKDAsIGxhc3RXb3JkRW5kLmluZGV4ICsgMSk7XG4gIH1cblxuICByZXR1cm4geyBoaWdobGlnaHQsIGJlZm9yZSwgYWZ0ZXIgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT3JkZXJlZFJhbmdlKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQsIGVuZE5vZGUsIGVuZE9mZnNldCkge1xuICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZS5zZXRTdGFydChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIGlmICghcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgQ09MTEFQU0VEIC4uLiBSQU5HRSBSRVZFUlNFP1wiKTtcbiAgY29uc3QgcmFuZ2VSZXZlcnNlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRTdGFydChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICByYW5nZVJldmVyc2Uuc2V0RW5kKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICBpZiAoIXJhbmdlUmV2ZXJzZS5jb2xsYXBzZWQpIHtcbiAgICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgT0suXCIpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgQUxTTyBDT0xMQVBTRUQ/IVwiKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIHJhbmdlSW5mbykge1xuICBjb25zdCBzdGFydEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIXN0YXJ0RWxlbWVudCkge1xuICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIFNUQVJUIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgc3RhcnRDb250YWluZXIgPSBzdGFydEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBzdGFydENvbnRhaW5lciA9XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCIpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgY29uc3QgZW5kRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIWVuZEVsZW1lbnQpIHtcbiAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBFTkQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBlbmRDb250YWluZXIgPSBlbmRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVuZENvbnRhaW5lciA9XG4gICAgICBlbmRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgIGVuZENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uZW5kT2Zmc2V0XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb24pIHtcbiAgY29uc3QgbG9jYXRpb25zID0gbG9jYXRpb24ubG9jYXRpb25zO1xuICBjb25zdCBkb21SYW5nZSA9IGxvY2F0aW9ucy5kb21SYW5nZTtcbiAgY29uc3Qgc3RhcnQgPSBkb21SYW5nZS5zdGFydDtcbiAgY29uc3QgZW5kID0gZG9tUmFuZ2UuZW5kO1xuXG4gIHJldHVybiB7XG4gICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBlbmQudGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IGVuZC5jc3NTZWxlY3RvcixcbiAgICBlbmRPZmZzZXQ6IGVuZC5vZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IHN0YXJ0LnRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IHN0YXJ0LmNzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiBzdGFydC5vZmZzZXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgbG9nTmF0aXZlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIEJhc2Ugc2NyaXB0IHVzZWQgYnkgYm90aCByZWZsb3dhYmxlIGFuZCBmaXhlZCBsYXlvdXQgcmVzb3VyY2VzLlxuXG5pbXBvcnQgXCIuL2dlc3R1cmVzXCI7XG5pbXBvcnQge1xuICByZW1vdmVQcm9wZXJ0eSxcbiAgc2Nyb2xsTGVmdCxcbiAgc2Nyb2xsUmlnaHQsXG4gIHNjcm9sbFRvRW5kLFxuICBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1Bvc2l0aW9uLFxuICBzY3JvbGxUb1N0YXJ0LFxuICBzY3JvbGxUb1RleHQsXG4gIHNldFByb3BlcnR5LFxuICBzZXRDU1NQcm9wZXJ0aWVzLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgY3JlYXRlQW5ub3RhdGlvbixcbiAgY3JlYXRlSGlnaGxpZ2h0LFxuICBkZXN0cm95SGlnaGxpZ2h0LFxuICBnZXRDdXJyZW50U2VsZWN0aW9uSW5mbyxcbiAgZ2V0U2VsZWN0aW9uUmVjdCxcbiAgcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElELFxuICBzZXRTY3JvbGxNb2RlLFxufSBmcm9tIFwiLi9oaWdobGlnaHRcIjtcbmltcG9ydCB7IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yIH0gZnJvbSBcIi4vZG9tXCI7XG5pbXBvcnQgeyBnZXRDdXJyZW50U2VsZWN0aW9uIH0gZnJvbSBcIi4vc2VsZWN0aW9uXCI7XG5pbXBvcnQgeyBnZXREZWNvcmF0aW9ucywgcmVnaXN0ZXJUZW1wbGF0ZXMgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcblxuLy8gUHVibGljIEFQSSB1c2VkIGJ5IHRoZSBuYXZpZ2F0b3IuXG53aW5kb3cucmVhZGl1bSA9IHtcbiAgLy8gdXRpbHNcbiAgc2Nyb2xsVG9JZDogc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9Qb3NpdGlvbjogc2Nyb2xsVG9Qb3NpdGlvbixcbiAgc2Nyb2xsVG9UZXh0OiBzY3JvbGxUb1RleHQsXG4gIHNjcm9sbExlZnQ6IHNjcm9sbExlZnQsXG4gIHNjcm9sbFJpZ2h0OiBzY3JvbGxSaWdodCxcbiAgc2Nyb2xsVG9TdGFydDogc2Nyb2xsVG9TdGFydCxcbiAgc2Nyb2xsVG9FbmQ6IHNjcm9sbFRvRW5kLFxuICBzZXRDU1NQcm9wZXJ0aWVzOiBzZXRDU1NQcm9wZXJ0aWVzLFxuICBzZXRQcm9wZXJ0eTogc2V0UHJvcGVydHksXG4gIHJlbW92ZVByb3BlcnR5OiByZW1vdmVQcm9wZXJ0eSxcblxuICAvLyBzZWxlY3Rpb25cbiAgZ2V0Q3VycmVudFNlbGVjdGlvbjogZ2V0Q3VycmVudFNlbGVjdGlvbixcblxuICAvLyBkZWNvcmF0aW9uXG4gIHJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlczogcmVnaXN0ZXJUZW1wbGF0ZXMsXG4gIGdldERlY29yYXRpb25zOiBnZXREZWNvcmF0aW9ucyxcblxuICAvLyBET01cbiAgZmluZEZpcnN0VmlzaWJsZUxvY2F0b3I6IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yLFxufTtcblxuLy8gTGVnYWN5IGhpZ2hsaWdodHMgQVBJLlxud2luZG93LmNyZWF0ZUFubm90YXRpb24gPSBjcmVhdGVBbm5vdGF0aW9uO1xud2luZG93LmNyZWF0ZUhpZ2hsaWdodCA9IGNyZWF0ZUhpZ2hsaWdodDtcbndpbmRvdy5kZXN0cm95SGlnaGxpZ2h0ID0gZGVzdHJveUhpZ2hsaWdodDtcbndpbmRvdy5nZXRDdXJyZW50U2VsZWN0aW9uSW5mbyA9IGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvO1xud2luZG93LmdldFNlbGVjdGlvblJlY3QgPSBnZXRTZWxlY3Rpb25SZWN0O1xud2luZG93LnJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRCA9IHJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRDtcbndpbmRvdy5zZXRTY3JvbGxNb2RlID0gc2V0U2Nyb2xsTW9kZTtcbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIFNjcmlwdCB1c2VkIGZvciByZWZsb3dhYmxlIHJlc291cmNlcy5cblxuaW1wb3J0IFwiLi9pbmRleFwiO1xuXG53aW5kb3cucmVhZGl1bS5pc1JlZmxvd2FibGUgPSB0cnVlO1xuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmdW5jdGlvbiAoKSB7XG4gIC8vIFNldHVwcyB0aGUgYHZpZXdwb3J0YCBtZXRhIHRhZyB0byBkaXNhYmxlIHpvb21pbmcuXG4gIGxldCBtZXRhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIm1ldGFcIik7XG4gIG1ldGEuc2V0QXR0cmlidXRlKFwibmFtZVwiLCBcInZpZXdwb3J0XCIpO1xuICBtZXRhLnNldEF0dHJpYnV0ZShcbiAgICBcImNvbnRlbnRcIixcbiAgICBcIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MS4wLCB1c2VyLXNjYWxhYmxlPW5vLCBzaHJpbmstdG8tZml0PW5vXCJcbiAgKTtcbiAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChtZXRhKTtcbn0pO1xuIl0sIm5hbWVzIjpbImFwcHJveFNlYXJjaCIsInNlYXJjaCIsInRleHQiLCJzdHIiLCJtYXhFcnJvcnMiLCJtYXRjaFBvcyIsImV4YWN0TWF0Y2hlcyIsImluZGV4T2YiLCJwdXNoIiwic3RhcnQiLCJlbmQiLCJsZW5ndGgiLCJlcnJvcnMiLCJ0ZXh0TWF0Y2hTY29yZSIsIm1hdGNoZXMiLCJtYXRjaFF1b3RlIiwicXVvdGUiLCJjb250ZXh0IiwiTWF0aCIsIm1pbiIsInNjb3JlTWF0Y2giLCJtYXRjaCIsInF1b3RlV2VpZ2h0IiwicHJlZml4V2VpZ2h0Iiwic3VmZml4V2VpZ2h0IiwicG9zV2VpZ2h0IiwicXVvdGVTY29yZSIsInByZWZpeFNjb3JlIiwicHJlZml4Iiwic2xpY2UiLCJtYXgiLCJzdWZmaXhTY29yZSIsInN1ZmZpeCIsInBvc1Njb3JlIiwiaGludCIsIm9mZnNldCIsImFicyIsInJhd1Njb3JlIiwibWF4U2NvcmUiLCJub3JtYWxpemVkU2NvcmUiLCJzY29yZWRNYXRjaGVzIiwibWFwIiwibSIsInNjb3JlIiwic29ydCIsImEiLCJiIiwibm9kZVRleHRMZW5ndGgiLCJub2RlIiwibm9kZVR5cGUiLCJOb2RlIiwiRUxFTUVOVF9OT0RFIiwiVEVYVF9OT0RFIiwidGV4dENvbnRlbnQiLCJwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aCIsInNpYmxpbmciLCJwcmV2aW91c1NpYmxpbmciLCJyZXNvbHZlT2Zmc2V0cyIsImVsZW1lbnQiLCJvZmZzZXRzIiwibmV4dE9mZnNldCIsInNoaWZ0Iiwibm9kZUl0ZXIiLCJvd25lckRvY3VtZW50IiwiY3JlYXRlTm9kZUl0ZXJhdG9yIiwiTm9kZUZpbHRlciIsIlNIT1dfVEVYVCIsInJlc3VsdHMiLCJjdXJyZW50Tm9kZSIsIm5leHROb2RlIiwidGV4dE5vZGUiLCJ1bmRlZmluZWQiLCJkYXRhIiwiUmFuZ2VFcnJvciIsIlJFU09MVkVfRk9SV0FSRFMiLCJSRVNPTFZFX0JBQ0tXQVJEUyIsIlRleHRQb3NpdGlvbiIsIkVycm9yIiwicGFyZW50IiwiY29udGFpbnMiLCJlbCIsInBhcmVudEVsZW1lbnQiLCJvcHRpb25zIiwiZXJyIiwiZGlyZWN0aW9uIiwidHciLCJkb2N1bWVudCIsImNyZWF0ZVRyZWVXYWxrZXIiLCJnZXRSb290Tm9kZSIsImZvcndhcmRzIiwicHJldmlvdXNOb2RlIiwiZnJvbVBvaW50IiwidGV4dE9mZnNldCIsImNoaWxkTm9kZXMiLCJpIiwiVGV4dFJhbmdlIiwicmVsYXRpdmVUbyIsInJlc29sdmUiLCJyYW5nZSIsIlJhbmdlIiwic2V0U3RhcnQiLCJzZXRFbmQiLCJzdGFydENvbnRhaW5lciIsInN0YXJ0T2Zmc2V0IiwiZW5kQ29udGFpbmVyIiwiZW5kT2Zmc2V0Iiwicm9vdCIsIm5vZGVGcm9tWFBhdGgiLCJ4cGF0aEZyb21Ob2RlIiwiUmFuZ2VBbmNob3IiLCJub3JtYWxpemVkUmFuZ2UiLCJmcm9tUmFuZ2UiLCJ0b1JhbmdlIiwidGV4dFJhbmdlIiwidHlwZSIsInNlbGVjdG9yIiwic3RhcnRQb3MiLCJmcm9tQ2hhck9mZnNldCIsImVuZFBvcyIsIlRleHRQb3NpdGlvbkFuY2hvciIsImZyb21PZmZzZXRzIiwiVGV4dFF1b3RlQW5jaG9yIiwiZXhhY3QiLCJ0b1Bvc2l0aW9uQW5jaG9yIiwiY29udGV4dExlbiIsIndpbmRvdyIsImFkZEV2ZW50TGlzdGVuZXIiLCJldmVudCIsIkFuZHJvaWQiLCJsb2dFcnJvciIsIm1lc3NhZ2UiLCJmaWxlbmFtZSIsImxpbmVubyIsIm9ic2VydmVyIiwiUmVzaXplT2JzZXJ2ZXIiLCJvblZpZXdwb3J0V2lkdGhDaGFuZ2VkIiwic25hcEN1cnJlbnRPZmZzZXQiLCJvYnNlcnZlIiwiYm9keSIsImFwcGVuZFZpcnR1YWxDb2x1bW5JZk5lZWRlZCIsImlkIiwidmlydHVhbENvbCIsImdldEVsZW1lbnRCeUlkIiwiaXNTY3JvbGxNb2RlRW5hYmxlZCIsImdldENvbHVtbkNvdW50UGVyU2NyZWVuIiwicmVtb3ZlIiwiZG9jdW1lbnRXaWR0aCIsInNjcm9sbGluZ0VsZW1lbnQiLCJzY3JvbGxXaWR0aCIsImNvbENvdW50IiwicGFnZVdpZHRoIiwiaGFzT2RkQ29sQ291bnQiLCJyb3VuZCIsImNyZWF0ZUVsZW1lbnQiLCJzZXRBdHRyaWJ1dGUiLCJzdHlsZSIsImJyZWFrQmVmb3JlIiwiaW5uZXJIVE1MIiwiYXBwZW5kQ2hpbGQiLCJ3aWR0aCIsImdldFZpZXdwb3J0V2lkdGgiLCJkZXZpY2VQaXhlbFJhdGlvIiwic2V0UHJvcGVydHkiLCJwYXJzZUludCIsImdldENvbXB1dGVkU3R5bGUiLCJkb2N1bWVudEVsZW1lbnQiLCJnZXRQcm9wZXJ0eVZhbHVlIiwidHJpbSIsImlzUlRMIiwiZGlyIiwidG9Mb3dlckNhc2UiLCJzY3JvbGxUb0lkIiwic2Nyb2xsVG9SZWN0IiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0Iiwic2Nyb2xsVG9Qb3NpdGlvbiIsInBvc2l0aW9uIiwic2Nyb2xsSGVpZ2h0Iiwic2Nyb2xsVG9wIiwiZmFjdG9yIiwic2Nyb2xsTGVmdCIsInNuYXBPZmZzZXQiLCJzY3JvbGxUb1RleHQiLCJyYW5nZUZyb21Mb2NhdG9yIiwic2Nyb2xsVG9SYW5nZSIsInJlY3QiLCJ0b3AiLCJzY3JvbGxZIiwiaW5uZXJIZWlnaHQiLCJsZWZ0Iiwic2Nyb2xsWCIsInNjcm9sbFRvU3RhcnQiLCJzY3JvbGxUbyIsInNjcm9sbFRvRW5kIiwibWluT2Zmc2V0Iiwic2Nyb2xsVG9PZmZzZXQiLCJzY3JvbGxSaWdodCIsIm1heE9mZnNldCIsImN1cnJlbnRPZmZzZXQiLCJkaWZmIiwidmFsdWUiLCJkZWx0YSIsImxvY2F0b3IiLCJsb2NhdGlvbnMiLCJoaWdobGlnaHQiLCJjc3NTZWxlY3RvciIsInF1ZXJ5U2VsZWN0b3IiLCJhbmNob3IiLCJiZWZvcmUiLCJhZnRlciIsImZyYWdtZW50cyIsImh0bWxJZCIsImNyZWF0ZVJhbmdlIiwic2V0U3RhcnRCZWZvcmUiLCJzZXRFbmRBZnRlciIsImUiLCJzZXRDU1NQcm9wZXJ0aWVzIiwicHJvcGVydGllcyIsIm5hbWUiLCJrZXkiLCJyZW1vdmVQcm9wZXJ0eSIsImxvZyIsIkFycmF5IiwicHJvdG90eXBlIiwiY2FsbCIsImFyZ3VtZW50cyIsImpvaW4iLCJsb2dOYXRpdmUiLCJkZWJ1ZyIsInRvTmF0aXZlUmVjdCIsInBpeGVsUmF0aW8iLCJoZWlnaHQiLCJyaWdodCIsImJvdHRvbSIsImdldENsaWVudFJlY3RzTm9PdmVybGFwIiwiZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cyIsImNsaWVudFJlY3RzIiwiZ2V0Q2xpZW50UmVjdHMiLCJ0b2xlcmFuY2UiLCJvcmlnaW5hbFJlY3RzIiwicmFuZ2VDbGllbnRSZWN0IiwibWVyZ2VkUmVjdHMiLCJtZXJnZVRvdWNoaW5nUmVjdHMiLCJub0NvbnRhaW5lZFJlY3RzIiwicmVtb3ZlQ29udGFpbmVkUmVjdHMiLCJuZXdSZWN0cyIsInJlcGxhY2VPdmVybGFwaW5nUmVjdHMiLCJtaW5BcmVhIiwiaiIsImJpZ0Vub3VnaCIsInNwbGljZSIsInJlY3RzIiwicmVjdDEiLCJyZWN0MiIsInJlY3RzTGluZVVwVmVydGljYWxseSIsImFsbW9zdEVxdWFsIiwicmVjdHNMaW5lVXBIb3Jpem9udGFsbHkiLCJob3Jpem9udGFsQWxsb3dlZCIsImFsaWduZWQiLCJjYW5NZXJnZSIsInJlY3RzVG91Y2hPck92ZXJsYXAiLCJmaWx0ZXIiLCJyZXBsYWNlbWVudENsaWVudFJlY3QiLCJnZXRCb3VuZGluZ1JlY3QiLCJyZWN0c1RvS2VlcCIsIlNldCIsImRlbGV0ZSIsInBvc3NpYmx5Q29udGFpbmluZ1JlY3QiLCJoYXMiLCJyZWN0Q29udGFpbnMiLCJmcm9tIiwicmVjdENvbnRhaW5zUG9pbnQiLCJ4IiwieSIsInRvQWRkIiwidG9SZW1vdmUiLCJzdWJ0cmFjdFJlY3RzMSIsInJlY3RTdWJ0cmFjdCIsInN1YnRyYWN0UmVjdHMyIiwiYXBwbHkiLCJyZWN0SW50ZXJzZWN0ZWQiLCJyZWN0SW50ZXJzZWN0IiwicmVjdEEiLCJyZWN0QiIsInJlY3RDIiwicmVjdEQiLCJtYXhMZWZ0IiwibWluUmlnaHQiLCJtYXhUb3AiLCJtaW5Cb3R0b20iLCJzdHlsZXMiLCJNYXAiLCJncm91cHMiLCJsYXN0R3JvdXBJZCIsInJlZ2lzdGVyVGVtcGxhdGVzIiwibmV3U3R5bGVzIiwic3R5bGVzaGVldCIsIk9iamVjdCIsImVudHJpZXMiLCJzZXQiLCJzdHlsZUVsZW1lbnQiLCJnZXRFbGVtZW50c0J5VGFnTmFtZSIsImdldERlY29yYXRpb25zIiwiZ3JvdXBOYW1lIiwiZ3JvdXAiLCJnZXQiLCJEZWNvcmF0aW9uR3JvdXAiLCJoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudCIsImNsaWNrRXZlbnQiLCJzaXplIiwiZmluZFRhcmdldCIsImdyb3VwQ29udGVudCIsIml0ZW1zIiwicmV2ZXJzZSIsIml0ZW0iLCJjbGlja2FibGVFbGVtZW50cyIsInRvSlNPTiIsImNsaWVudFgiLCJjbGllbnRZIiwidGFyZ2V0Iiwib25EZWNvcmF0aW9uQWN0aXZhdGVkIiwiSlNPTiIsInN0cmluZ2lmeSIsImRlY29yYXRpb24iLCJjbGljayIsImdyb3VwSWQiLCJsYXN0SXRlbUlkIiwiY29udGFpbmVyIiwiYWRkIiwibGF5b3V0IiwiZGVjb3JhdGlvbklkIiwiaW5kZXgiLCJmaW5kSW5kZXgiLCJ1cGRhdGUiLCJjbGVhciIsImNsZWFyQ29udGFpbmVyIiwicmVxdWVzdExheW91dCIsImZvckVhY2giLCJncm91cENvbnRhaW5lciIsInJlcXVpcmVDb250YWluZXIiLCJpdGVtQ29udGFpbmVyIiwidmlld3BvcnRXaWR0aCIsImlubmVyV2lkdGgiLCJjb2x1bW5Db3VudCIsInhPZmZzZXQiLCJ5T2Zmc2V0IiwicG9zaXRpb25FbGVtZW50IiwiYm91bmRpbmdSZWN0IiwiZmxvb3IiLCJlbGVtZW50VGVtcGxhdGUiLCJ0ZW1wbGF0ZSIsImNvbnRlbnQiLCJmaXJzdEVsZW1lbnRDaGlsZCIsImVycm9yIiwicjEiLCJyMiIsImNsaWVudFJlY3QiLCJsaW5lIiwiY2xvbmVOb2RlIiwiYXBwZW5kIiwiYm91bmRzIiwicXVlcnlTZWxlY3RvckFsbCIsImNoaWxkcmVuIiwibGFzdFNpemUiLCJjbGllbnRXaWR0aCIsImNsaWVudEhlaWdodCIsIm9uQ2xpY2siLCJiaW5kRHJhZ0dlc3R1cmUiLCJnZXRTZWxlY3Rpb24iLCJpc0NvbGxhcHNlZCIsImRlZmF1bHRQcmV2ZW50ZWQiLCJ0YXJnZXRFbGVtZW50Iiwib3V0ZXJIVE1MIiwiaW50ZXJhY3RpdmVFbGVtZW50IiwibmVhcmVzdEludGVyYWN0aXZlRWxlbWVudCIsInNob3VsZFByZXZlbnREZWZhdWx0Iiwib25UYXAiLCJzdG9wUHJvcGFnYXRpb24iLCJwcmV2ZW50RGVmYXVsdCIsIm9uU3RhcnQiLCJwYXNzaXZlIiwib25FbmQiLCJvbk1vdmUiLCJzdGF0ZSIsImlzU3RhcnRpbmdEcmFnIiwic3RhcnRYIiwidG91Y2hlcyIsInN0YXJ0WSIsImN1cnJlbnRYIiwiY3VycmVudFkiLCJvZmZzZXRYIiwib2Zmc2V0WSIsIm9uRHJhZ1N0YXJ0Iiwib25EcmFnTW92ZSIsIm9uRHJhZ0VuZCIsImludGVyYWN0aXZlVGFncyIsIm5vZGVOYW1lIiwiaGFzQXR0cmlidXRlIiwiZ2V0QXR0cmlidXRlIiwiUk9PVF9DTEFTU19SRURVQ0VfTU9USU9OIiwiUk9PVF9DTEFTU19OT19GT09UTk9URVMiLCJQT1BVUF9ESUFMT0dfQ0xBU1MiLCJGT09UTk9URVNfQ09OVEFJTkVSX0NMQVNTIiwiRk9PVE5PVEVTX0NMT1NFX0JVVFRPTl9DTEFTUyIsIkZPT1ROT1RFX0ZPUkNFX1NIT1ciLCJUVFNfSURfUFJFVklPVVMiLCJUVFNfSURfTkVYVCIsIlRUU19JRF9TTElERVIiLCJUVFNfSURfQUNUSVZFX1dPUkQiLCJUVFNfSURfQ09OVEFJTkVSIiwiVFRTX0lEX0lORk8iLCJUVFNfTkFWX0JVVFRPTl9DTEFTUyIsIlRUU19JRF9TUEVBS0lOR19ET0NfRUxFTUVOVCIsIlRUU19DTEFTU19JTkpFQ1RFRF9TUEFOIiwiVFRTX0NMQVNTX0lOSkVDVEVEX1NVQlNQQU4iLCJUVFNfSURfSU5KRUNURURfUEFSRU5UIiwiSURfSElHSExJR0hUU19DT05UQUlORVIiLCJJRF9BTk5PVEFUSU9OX0NPTlRBSU5FUiIsIkNMQVNTX0hJR0hMSUdIVF9DT05UQUlORVIiLCJDTEFTU19BTk5PVEFUSU9OX0NPTlRBSU5FUiIsIkNMQVNTX0hJR0hMSUdIVF9BUkVBIiwiQ0xBU1NfQU5OT1RBVElPTl9BUkVBIiwiQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEiLCJDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUEiLCJfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSIsIkNMQVNTX1BBR0lOQVRFRCIsIklTX0RFViIsIl9oaWdobGlnaHRzIiwiX2hpZ2hsaWdodHNDb250YWluZXIiLCJfYW5ub3RhdGlvbkNvbnRhaW5lciIsImxhc3RNb3VzZURvd25YIiwibGFzdE1vdXNlRG93blkiLCJib2R5RXZlbnRMaXN0ZW5lcnNTZXQiLCJVU0VfU1ZHIiwiREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkiLCJBTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZIiwiREVCVUdfVklTVUFMUyIsIkRFRkFVTFRfQkFDS0dST1VORF9DT0xPUiIsImJsdWUiLCJncmVlbiIsInJlZCIsIkFOTk9UQVRJT05fV0lEVEgiLCJyZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUiLCJfd2luIiwiaGlnaGxpZ2h0Qm91bmRpbmciLCJvdXRsaW5lIiwic2V0SGlnaGxpZ2h0QXJlYVN0eWxlIiwid2luIiwiaGlnaGxpZ2h0QXJlYXMiLCJ1c2VTVkciLCJoaWdobGlnaHRBcmVhIiwiaXNTVkciLCJuYW1lc3BhY2VVUkkiLCJTVkdfWE1MX05BTUVTUEFDRSIsIm9wYWNpdHkiLCJjb2xvciIsInJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlIiwicGFyZW50Tm9kZSIsImZpbmQiLCJoIiwicHJvY2Vzc1RvdWNoRXZlbnQiLCJldiIsInNjcm9sbEVsZW1lbnQiLCJnZXRTY3JvbGxpbmdFbGVtZW50IiwiY2hhbmdlZFRvdWNoZXMiLCJwYWdpbmF0ZWQiLCJpc1BhZ2luYXRlZCIsImJvZHlSZWN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiZm91bmRIaWdobGlnaHQiLCJmb3VuZEVsZW1lbnQiLCJmb3VuZFJlY3QiLCJoaWdobGlnaHRQYXJlbnQiLCJoaXQiLCJoaWdobGlnaHRGcmFnbWVudHMiLCJoaWdobGlnaHRGcmFnbWVudCIsIndpdGhSZWN0IiwiaGlnaGxpZ2h0Qm91bmRpbmdzIiwiYWxsSGlnaGxpZ2h0QXJlYXMiLCJmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyIsImZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIiwiYWxsSGlnaGxpZ2h0Qm91bmRpbmdzIiwic2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSIsInNjcmVlbldpZHRoIiwib3V0ZXJXaWR0aCIsInNjcmVlbkhlaWdodCIsIm91dGVySGVpZ2h0IiwicGF5bG9hZCIsInByb2Nlc3MiLCJlbGVjdHJvbl8xIiwiaXBjUmVuZGVyZXIiLCJzZW5kVG9Ib3N0IiwiUjJfRVZFTlRfSElHSExJR0hUX0NMSUNLIiwid2Via2l0VVJMIiwiY29uc29sZSIsImluY2x1ZGVzIiwiaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQiLCJ3ZWJraXQiLCJtZXNzYWdlSGFuZGxlcnMiLCJwb3N0TWVzc2FnZSIsImhpZ2hsaWdodEFjdGl2YXRlZCIsInByb2Nlc3NNb3VzZUV2ZW50IiwidG91Y2hlZFBvc2l0aW9uIiwidG9QcmVzZXJ2ZSIsInRvQ2hlY2siLCJjaGVja092ZXJsYXBzIiwic3RpbGxPdmVybGFwaW5nUmVjdHMiLCJoYXMxIiwiaGFzMiIsInhPdmVybGFwIiwiZ2V0UmVjdE92ZXJsYXBYIiwieU92ZXJsYXAiLCJnZXRSZWN0T3ZlcmxhcFkiLCJyYW5nZUNsaWVudFJlY3RzIiwiZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXBfIiwiY2xhc3NMaXN0IiwiZW5zdXJlQ29udGFpbmVyIiwiYW5ub3RhdGlvbkZsYWciLCJ0b3VjaEVuZCIsImhpZGVBbGxoaWdobGlnaHRzIiwiZGVzdHJveUFsbGhpZ2hsaWdodHMiLCJkZXN0cm95SGlnaGxpZ2h0IiwiX2RvY3VtZW50IiwiaGlnaGxpZ2h0Q29udGFpbmVyIiwiaXNDZmlUZXh0Tm9kZSIsImdldENoaWxkVGV4dE5vZGVDZmlJbmRleCIsImNoaWxkIiwiZm91bmQiLCJ0ZXh0Tm9kZUluZGV4IiwicHJldmlvdXNXYXNFbGVtZW50IiwiY2hpbGROb2RlIiwiaXNUZXh0IiwiZ2V0Q29tbW9uQW5jZXN0b3JFbGVtZW50Iiwibm9kZTEiLCJub2RlMiIsIm5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4iLCJub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluIiwiY29tbW9uQW5jZXN0b3IiLCJub2RlMUVsZW1lbnRBbmNlc3RvciIsIm5vZGUyRWxlbWVudEFuY2VzdG9yIiwiZnVsbFF1YWxpZmllZFNlbGVjdG9yIiwibG93ZXJDYXNlTmFtZSIsImxvY2FsTmFtZSIsImNzc1BhdGgiLCJnZXRDdXJyZW50U2VsZWN0aW9uSW5mbyIsInNlbGVjdGlvbiIsInJhd1RleHQiLCJ0b1N0cmluZyIsImNsZWFuVGV4dCIsInJlcGxhY2UiLCJhbmNob3JOb2RlIiwiZm9jdXNOb2RlIiwicmFuZ2VDb3VudCIsImdldFJhbmdlQXQiLCJjcmVhdGVPcmRlcmVkUmFuZ2UiLCJhbmNob3JPZmZzZXQiLCJmb2N1c09mZnNldCIsImNvbGxhcHNlZCIsInJhbmdlSW5mbyIsImNvbnZlcnRSYW5nZSIsImNvbXB1dGVDRkkiLCJyZXN0b3JlZFJhbmdlIiwiY29udmVydFJhbmdlSW5mbyIsImR1bXBEZWJ1ZyIsImdldENzc1NlbGVjdG9yIiwicmFuZ2VJbmZvMkxvY2F0aW9uIiwiY2hlY2tCbGFja2xpc3RlZCIsImJsYWNrbGlzdGVkSWQiLCJibGFja2xpc3RlZENsYXNzIiwib3B0aW1pemVkIiwic3RlcHMiLCJjb250ZXh0Tm9kZSIsInN0ZXAiLCJfY3NzUGF0aFN0ZXAiLCJpc1RhcmdldE5vZGUiLCJwcmVmaXhlZEVsZW1lbnRDbGFzc05hbWVzIiwibmQiLCJjbGFzc0F0dHJpYnV0ZSIsInNwbGl0IiwiQm9vbGVhbiIsIm5tIiwiaWRTZWxlY3RvciIsImlkZCIsImVzY2FwZUlkZW50aWZpZXJJZk5lZWRlZCIsImlkZW50IiwiaXNDU1NJZGVudGlmaWVyIiwic2hvdWxkRXNjYXBlRmlyc3QiLCJ0ZXN0IiwibGFzdEluZGV4IiwiYyIsImlpIiwiaXNDU1NJZGVudENoYXIiLCJlc2NhcGVBc2NpaUNoYXIiLCJpc0xhc3QiLCJ0b0hleEJ5dGUiLCJoZXhCeXRlIiwiY2hhckNvZGVBdCIsIkRPQ1VNRU5UX05PREUiLCJwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheV8iLCJwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheSIsImFyckl0ZW0iLCJuZWVkc0NsYXNzTmFtZXMiLCJuZWVkc050aENoaWxkIiwib3duSW5kZXgiLCJlbGVtZW50SW5kZXgiLCJzaWJsaW5ncyIsInNpYmxpbmdOYW1lIiwib3duQ2xhc3NOYW1lcyIsIm93bkNsYXNzTmFtZUNvdW50Iiwic2libGluZ0NsYXNzTmFtZXNBcnJheV8iLCJzaWJsaW5nQ2xhc3NOYW1lc0FycmF5Iiwic2libGluZ0NsYXNzIiwiaW5kIiwicmVzdWx0IiwicHJlZml4ZWROYW1lIiwic3Vic3RyIiwiY2ZpIiwiY3VycmVudEVsZW1lbnQiLCJibGFja2xpc3RlZCIsImN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW4iLCJjdXJyZW50RWxlbWVudEluZGV4IiwiY2ZpSW5kZXgiLCJfY3JlYXRlSGlnaGxpZ2h0IiwicG9pbnRlckludGVyYWN0aW9uIiwibG9jYXRpb24yUmFuZ2VJbmZvIiwidW5pcXVlU3RyIiwic3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IiLCJzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCIsImVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciIsImVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCIsImhhc2giLCJyZXF1aXJlIiwic2hhMjU2SGV4Iiwic2hhMjU2IiwiZGlnZXN0IiwiY3JlYXRlSGlnaGxpZ2h0RG9tIiwiY3JlYXRlSGlnaGxpZ2h0Iiwic2VsZWN0aW9uSW5mbyIsImNyZWF0ZUFubm90YXRpb24iLCJzY2FsZSIsIlJFQURJVU0yIiwiaXNGaXhlZExheW91dCIsImZ4bFZpZXdwb3J0U2NhbGUiLCJoaWdobGlnaHRzQ29udGFpbmVyIiwiZHJhd1VuZGVybGluZSIsImRyYXdTdHJpa2VUaHJvdWdoIiwiaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWciLCJyb3VuZGVkQ29ybmVyIiwidW5kZXJsaW5lVGhpY2tuZXNzIiwic3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MiLCJleHRyYSIsInJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdCIsImZyYW1lRm9ySGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtXaXRoSUQiLCJhbm5vdGF0aW9uT2Zmc2V0IiwiYm9yZGVyVGhpY2tuZXNzIiwiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCIsImhpZ2hsaWdodEFyZWFTVkdSZWN0IiwiY3JlYXRlRWxlbWVudE5TIiwiaGlnaGxpZ2h0QXJlYVNWR0xpbmUiLCJsaW5lT2Zmc2V0IiwicmdiIiwicmFuZG9tIiwiciIsImciLCJoaWdobGlnaHRBcmVhTGluZSIsImhpZ2hsaWdodEFyZWFTVkciLCJvdmVyZmxvdyIsInJhbmdlQm91bmRpbmdDbGllbnRSZWN0Iiwic3RhcnROb2RlIiwiZW5kTm9kZSIsInJhbmdlUmV2ZXJzZSIsImNvbXB1dGVFbGVtZW50Q0ZJIiwic3RhcnRJc0VsZW1lbnQiLCJzdGFydENvbnRhaW5lckVsZW1lbnQiLCJlbmRJc0VsZW1lbnQiLCJlbmRDb250YWluZXJFbGVtZW50IiwiY29tbW9uRWxlbWVudEFuY2VzdG9yIiwiY29tbW9uQW5jZXN0b3JDb250YWluZXIiLCJyYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCIsInJvb3RFbGVtZW50Q2ZpIiwic3RhcnRFbGVtZW50Q2ZpIiwiZW5kRWxlbWVudENmaSIsInN0YXJ0RWxlbWVudE9yVGV4dENmaSIsInN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpIiwiY2ZpVGV4dE5vZGVJbmRleCIsImNmaUluZGV4T2ZMYXN0RWxlbWVudCIsImNoaWxkRWxlbWVudENvdW50IiwibGFzdENoaWxkTm9kZSIsImVuZEVsZW1lbnRPclRleHRDZmkiLCJlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkiLCJzdGFydEVsZW1lbnQiLCJlbmRFbGVtZW50IiwiZnJhbWVGb3JIaWdobGlnaHRXaXRoSUQiLCJ0b3BDbGllbnRSZWN0IiwibWF4SGVpZ2h0IiwibmV3VG9wIiwiYm91bmRpbmdBcmVhcyIsImdldEVsZW1lbnRzQnlDbGFzc05hbWUiLCJsZW4iLCJib3VuZGluZ0FyZWEiLCJoaWdobGlnaHRXaXRoSUQiLCJwYXJ0aWFsQ2ZpIiwiZG9tUmFuZ2UiLCJsb2NhdGlvbiIsInJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRCIsImdldFNlbGVjdGlvblJlY3QiLCJzZWwiLCJoYW5kbGVCb3VuZHMiLCJzZXRTY3JvbGxNb2RlIiwiZmxhZyIsImZpbmRGaXJzdFZpc2libGVMb2NhdG9yIiwiZmluZEVsZW1lbnQiLCJocmVmIiwicm9vdEVsZW1lbnQiLCJzaG91bGRJZ25vcmVFbGVtZW50IiwiaXNFbGVtZW50VmlzaWJsZSIsInJlYWRpdW0iLCJlbFN0eWxlIiwiZGlzcGxheSIsIm1hdGNoQWxsIiwic2hpbSIsImlzU2VsZWN0aW5nIiwib25TZWxlY3Rpb25FbmQiLCJvblNlbGVjdGlvblN0YXJ0IiwiZ2V0Q3VycmVudFNlbGVjdGlvbiIsImdldEN1cnJlbnRTZWxlY3Rpb25UZXh0IiwiY2xlYW5IaWdobGlnaHQiLCJzbmlwcGV0TGVuZ3RoIiwiZmlyc3RXb3JkU3RhcnQiLCJsYXN0V29yZEVuZCIsInBvcCIsInJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlcyIsImlzUmVmbG93YWJsZSIsIm1ldGEiLCJoZWFkIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5232\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},3715:function(__unused_webpack_module,exports,__webpack_require__){eval("var hash = exports;\n\nhash.utils = __webpack_require__(6436);\nhash.common = __webpack_require__(5772);\nhash.sha = __webpack_require__(9041);\nhash.ripemd = __webpack_require__(2949);\nhash.hmac = __webpack_require__(2344);\n\n// Proxy hash functions to the main object\nhash.sha1 = hash.sha.sha1;\nhash.sha256 = hash.sha.sha256;\nhash.sha224 = hash.sha.sha224;\nhash.sha384 = hash.sha.sha384;\nhash.sha512 = hash.sha.sha512;\nhash.ripemd160 = hash.ripemd.ripemd160;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcxNS5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQSxhQUFhLG1CQUFPLENBQUMsSUFBYztBQUNuQyxjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBWTtBQUMvQixjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsSUFBYTs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanM/N2Q5MiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3715\n")},5772:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction BlockHash() {\n this.pending = null;\n this.pendingTotal = 0;\n this.blockSize = this.constructor.blockSize;\n this.outSize = this.constructor.outSize;\n this.hmacStrength = this.constructor.hmacStrength;\n this.padLength = this.constructor.padLength / 8;\n this.endian = 'big';\n\n this._delta8 = this.blockSize / 8;\n this._delta32 = this.blockSize / 32;\n}\nexports.BlockHash = BlockHash;\n\nBlockHash.prototype.update = function update(msg, enc) {\n // Convert message to array, pad it, and join into 32bit blocks\n msg = utils.toArray(msg, enc);\n if (!this.pending)\n this.pending = msg;\n else\n this.pending = this.pending.concat(msg);\n this.pendingTotal += msg.length;\n\n // Enough data, try updating\n if (this.pending.length >= this._delta8) {\n msg = this.pending;\n\n // Process pending data in blocks\n var r = msg.length % this._delta8;\n this.pending = msg.slice(msg.length - r, msg.length);\n if (this.pending.length === 0)\n this.pending = null;\n\n msg = utils.join32(msg, 0, msg.length - r, this.endian);\n for (var i = 0; i < msg.length; i += this._delta32)\n this._update(msg, i, i + this._delta32);\n }\n\n return this;\n};\n\nBlockHash.prototype.digest = function digest(enc) {\n this.update(this._pad());\n assert(this.pending === null);\n\n return this._digest(enc);\n};\n\nBlockHash.prototype._pad = function pad() {\n var len = this.pendingTotal;\n var bytes = this._delta8;\n var k = bytes - ((len + this.padLength) % bytes);\n var res = new Array(k + this.padLength);\n res[0] = 0x80;\n for (var i = 1; i < k; i++)\n res[i] = 0;\n\n // Append length\n len <<= 3;\n if (this.endian === 'big') {\n for (var t = 8; t < this.padLength; t++)\n res[i++] = 0;\n\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = len & 0xff;\n } else {\n res[i++] = len & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n\n for (t = 8; t < this.padLength; t++)\n res[i++] = 0;\n }\n\n return res;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTc3Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLE9BQU87QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzP2VkYzkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5772\n")},2344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction Hmac(hash, key, enc) {\n if (!(this instanceof Hmac))\n return new Hmac(hash, key, enc);\n this.Hash = hash;\n this.blockSize = hash.blockSize / 8;\n this.outSize = hash.outSize / 8;\n this.inner = null;\n this.outer = null;\n\n this._init(utils.toArray(key, enc));\n}\nmodule.exports = Hmac;\n\nHmac.prototype._init = function init(key) {\n // Shorten key, if needed\n if (key.length > this.blockSize)\n key = new this.Hash().update(key).digest();\n assert(key.length <= this.blockSize);\n\n // Add padding to key\n for (var i = key.length; i < this.blockSize; i++)\n key.push(0);\n\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x36;\n this.inner = new this.Hash().update(key);\n\n // 0x36 ^ 0x5c = 0x6a\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x6a;\n this.outer = new this.Hash().update(key);\n};\n\nHmac.prototype.update = function update(msg, enc) {\n this.inner.update(msg, enc);\n return this;\n};\n\nHmac.prototype.digest = function digest(enc) {\n this.outer.update(this.inner.digest());\n return this.outer.digest(enc);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsb0JBQW9CO0FBQy9DOztBQUVBLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvaG1hYy5qcz8yMTM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gSG1hYyhoYXNoLCBrZXksIGVuYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hYykpXG4gICAgcmV0dXJuIG5ldyBIbWFjKGhhc2gsIGtleSwgZW5jKTtcbiAgdGhpcy5IYXNoID0gaGFzaDtcbiAgdGhpcy5ibG9ja1NpemUgPSBoYXNoLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMub3V0U2l6ZSA9IGhhc2gub3V0U2l6ZSAvIDg7XG4gIHRoaXMuaW5uZXIgPSBudWxsO1xuICB0aGlzLm91dGVyID0gbnVsbDtcblxuICB0aGlzLl9pbml0KHV0aWxzLnRvQXJyYXkoa2V5LCBlbmMpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hYztcblxuSG1hYy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGtleSkge1xuICAvLyBTaG9ydGVuIGtleSwgaWYgbmVlZGVkXG4gIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpXG4gICAga2V5ID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xuICBhc3NlcnQoa2V5Lmxlbmd0aCA8PSB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gQWRkIHBhZGRpbmcgdG8ga2V5XG4gIGZvciAodmFyIGkgPSBrZXkubGVuZ3RoOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKylcbiAgICBrZXkucHVzaCgwKTtcblxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDM2O1xuICB0aGlzLmlubmVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xuXG4gIC8vIDB4MzYgXiAweDVjID0gMHg2YVxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2344\n")},2949:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_3 = utils.sum32_3;\nvar sum32_4 = utils.sum32_4;\nvar BlockHash = common.BlockHash;\n\nfunction RIPEMD160() {\n if (!(this instanceof RIPEMD160))\n return new RIPEMD160();\n\n BlockHash.call(this);\n\n this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];\n this.endian = 'little';\n}\nutils.inherits(RIPEMD160, BlockHash);\nexports.ripemd160 = RIPEMD160;\n\nRIPEMD160.blockSize = 512;\nRIPEMD160.outSize = 160;\nRIPEMD160.hmacStrength = 192;\nRIPEMD160.padLength = 64;\n\nRIPEMD160.prototype._update = function update(msg, start) {\n var A = this.h[0];\n var B = this.h[1];\n var C = this.h[2];\n var D = this.h[3];\n var E = this.h[4];\n var Ah = A;\n var Bh = B;\n var Ch = C;\n var Dh = D;\n var Eh = E;\n for (var j = 0; j < 80; j++) {\n var T = sum32(\n rotl32(\n sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),\n s[j]),\n E);\n A = E;\n E = D;\n D = rotl32(C, 10);\n C = B;\n B = T;\n T = sum32(\n rotl32(\n sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),\n sh[j]),\n Eh);\n Ah = Eh;\n Eh = Dh;\n Dh = rotl32(Ch, 10);\n Ch = Bh;\n Bh = T;\n }\n T = sum32_3(this.h[1], C, Dh);\n this.h[1] = sum32_3(this.h[2], D, Eh);\n this.h[2] = sum32_3(this.h[3], E, Ah);\n this.h[3] = sum32_3(this.h[4], A, Bh);\n this.h[4] = sum32_3(this.h[0], B, Ch);\n this.h[0] = T;\n};\n\nRIPEMD160.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'little');\n else\n return utils.split32(this.h, 'little');\n};\n\nfunction f(j, x, y, z) {\n if (j <= 15)\n return x ^ y ^ z;\n else if (j <= 31)\n return (x & y) | ((~x) & z);\n else if (j <= 47)\n return (x | (~y)) ^ z;\n else if (j <= 63)\n return (x & z) | (y & (~z));\n else\n return x ^ (y | (~z));\n}\n\nfunction K(j) {\n if (j <= 15)\n return 0x00000000;\n else if (j <= 31)\n return 0x5a827999;\n else if (j <= 47)\n return 0x6ed9eba1;\n else if (j <= 63)\n return 0x8f1bbcdc;\n else\n return 0xa953fd4e;\n}\n\nfunction Kh(j) {\n if (j <= 15)\n return 0x50a28be6;\n else if (j <= 31)\n return 0x5c4dd124;\n else if (j <= 47)\n return 0x6d703ef3;\n else if (j <= 63)\n return 0x7a6d76e9;\n else\n return 0x00000000;\n}\n\nvar r = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,\n 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,\n 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13\n];\n\nvar rh = [\n 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,\n 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,\n 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,\n 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,\n 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11\n];\n\nvar s = [\n 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,\n 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,\n 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,\n 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,\n 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6\n];\n\nvar sh = [\n 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,\n 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,\n 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,\n 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,\n 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11\n];\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBVTs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzP2JiNDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2949\n")},9041:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nexports.sha1 = __webpack_require__(4761);\nexports.sha224 = __webpack_require__(799);\nexports.sha256 = __webpack_require__(9344);\nexports.sha384 = __webpack_require__(772);\nexports.sha512 = __webpack_require__(5900);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA0MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix3Q0FBaUM7QUFDakMseUNBQXFDO0FBQ3JDLDBDQUFxQztBQUNyQyx5Q0FBcUM7QUFDckMsMENBQXFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcz81OTE5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGEvMScpO1xuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYS8yMjQnKTtcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEvMjU2Jyk7XG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhLzM4NCcpO1xuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYS81MTInKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9041\n")},4761:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_5 = utils.sum32_5;\nvar ft_1 = shaCommon.ft_1;\nvar BlockHash = common.BlockHash;\n\nvar sha1_K = [\n 0x5A827999, 0x6ED9EBA1,\n 0x8F1BBCDC, 0xCA62C1D6\n];\n\nfunction SHA1() {\n if (!(this instanceof SHA1))\n return new SHA1();\n\n BlockHash.call(this);\n this.h = [\n 0x67452301, 0xefcdab89, 0x98badcfe,\n 0x10325476, 0xc3d2e1f0 ];\n this.W = new Array(80);\n}\n\nutils.inherits(SHA1, BlockHash);\nmodule.exports = SHA1;\n\nSHA1.blockSize = 512;\nSHA1.outSize = 160;\nSHA1.hmacStrength = 80;\nSHA1.padLength = 64;\n\nSHA1.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n\n for(; i < W.length; i++)\n W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n\n for (i = 0; i < W.length; i++) {\n var s = ~~(i / 20);\n var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);\n e = d;\n d = c;\n c = rotl32(b, 30);\n b = a;\n a = t;\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n};\n\nSHA1.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc2MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVOztBQUVsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixRQUFRO0FBQzFCOztBQUVBLFFBQVEsY0FBYztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzEuanM/MTNlMiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGZ0XzEgPSBzaGFDb21tb24uZnRfMTtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMTtcblxuU0hBMS5ibG9ja1NpemUgPSA1MTI7XG5TSEExLm91dFNpemUgPSAxNjA7XG5TSEExLmhtYWNTdHJlbmd0aCA9IDgwO1xuU0hBMS5wYWRMZW5ndGggPSA2NDtcblxuU0hBMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuXG4gIGZvcig7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSByb3RsMzIoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSwgMSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4761\n")},799:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar SHA256 = __webpack_require__(9344);\n\nfunction SHA224() {\n if (!(this instanceof SHA224))\n return new SHA224();\n\n SHA256.call(this);\n this.h = [\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];\n}\nutils.inherits(SHA224, SHA256);\nmodule.exports = SHA224;\n\nSHA224.blockSize = 512;\nSHA224.outSize = 224;\nSHA224.hmacStrength = 192;\nSHA224.padLength = 64;\n\nSHA224.prototype._digest = function digest(enc) {\n // Just truncate output\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 7), 'big');\n else\n return utils.split32(this.h.slice(0, 7), 'big');\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVO0FBQzlCLGFBQWEsbUJBQU8sQ0FBQyxJQUFPOztBQUU1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzIyNC5qcz8wN2YyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBTSEEyNTYgPSByZXF1aXJlKCcuLzI1NicpO1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///799\n")},9344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\nvar assert = __webpack_require__(9746);\n\nvar sum32 = utils.sum32;\nvar sum32_4 = utils.sum32_4;\nvar sum32_5 = utils.sum32_5;\nvar ch32 = shaCommon.ch32;\nvar maj32 = shaCommon.maj32;\nvar s0_256 = shaCommon.s0_256;\nvar s1_256 = shaCommon.s1_256;\nvar g0_256 = shaCommon.g0_256;\nvar g1_256 = shaCommon.g1_256;\n\nvar BlockHash = common.BlockHash;\n\nvar sha256_K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\nfunction SHA256() {\n if (!(this instanceof SHA256))\n return new SHA256();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n ];\n this.k = sha256_K;\n this.W = new Array(64);\n}\nutils.inherits(SHA256, BlockHash);\nmodule.exports = SHA256;\n\nSHA256.blockSize = 512;\nSHA256.outSize = 256;\nSHA256.hmacStrength = 192;\nSHA256.padLength = 64;\n\nSHA256.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i++)\n W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n var f = this.h[5];\n var g = this.h[6];\n var h = this.h[7];\n\n assert(this.k.length === W.length);\n for (i = 0; i < W.length; i++) {\n var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);\n var T2 = sum32(s0_256(a), maj32(a, b, c));\n h = g;\n g = f;\n f = e;\n e = sum32(d, T1);\n d = c;\n c = b;\n b = a;\n a = sum32(T1, T2);\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n this.h[5] = sum32(this.h[5], f);\n this.h[6] = sum32(this.h[6], g);\n this.h[7] = sum32(this.h[7], h);\n};\n\nSHA256.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBLFNBQVMsY0FBYztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMjU2LmpzPzZlZWQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIHNoYUNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciBjaDMyID0gc2hhQ29tbW9uLmNoMzI7XG52YXIgbWFqMzIgPSBzaGFDb21tb24ubWFqMzI7XG52YXIgczBfMjU2ID0gc2hhQ29tbW9uLnMwXzI1NjtcbnZhciBzMV8yNTYgPSBzaGFDb21tb24uczFfMjU2O1xudmFyIGcwXzI1NiA9IHNoYUNvbW1vbi5nMF8yNTY7XG52YXIgZzFfMjU2ID0gc2hhQ29tbW9uLmcxXzI1NjtcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG4gIF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBUMSA9IHN1bTMyXzUoaCwgczFfMjU2KGUpLCBjaDMyKGUsIGYsIGcpLCB0aGlzLmtbaV0sIFdbaV0pO1xuICAgIHZhciBUMiA9IHN1bTMyKHMwXzI1NihhKSwgbWFqMzIoYSwgYiwgYykpO1xuICAgIGggPSBnO1xuICAgIGcgPSBmO1xuICAgIGYgPSBlO1xuICAgIGUgPSBzdW0zMihkLCBUMSk7XG4gICAgZCA9IGM7XG4gICAgYyA9IGI7XG4gICAgYiA9IGE7XG4gICAgYSA9IHN1bTMyKFQxLCBUMik7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xuICB0aGlzLmhbNV0gPSBzdW0zMih0aGlzLmhbNV0sIGYpO1xuICB0aGlzLmhbNl0gPSBzdW0zMih0aGlzLmhbNl0sIGcpO1xuICB0aGlzLmhbN10gPSBzdW0zMih0aGlzLmhbN10sIGgpO1xufTtcblxuU0hBMjU2LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9344\n")},772:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\n\nvar SHA512 = __webpack_require__(5900);\n\nfunction SHA384() {\n if (!(this instanceof SHA384))\n return new SHA384();\n\n SHA512.call(this);\n this.h = [\n 0xcbbb9d5d, 0xc1059ed8,\n 0x629a292a, 0x367cd507,\n 0x9159015a, 0x3070dd17,\n 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31,\n 0x8eb44a87, 0x68581511,\n 0xdb0c2e0d, 0x64f98fa7,\n 0x47b5481d, 0xbefa4fa4 ];\n}\nutils.inherits(SHA384, SHA512);\nmodule.exports = SHA384;\n\nSHA384.blockSize = 1024;\nSHA384.outSize = 384;\nSHA384.hmacStrength = 192;\nSHA384.padLength = 128;\n\nSHA384.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 12), 'big');\n else\n return utils.split32(this.h.slice(0, 12), 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcyLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVOztBQUU5QixhQUFhLG1CQUFPLENBQUMsSUFBTzs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMzg0LmpzPzhiOTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi81MTInKTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///772\n")},5900:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar assert = __webpack_require__(9746);\n\nvar rotr64_hi = utils.rotr64_hi;\nvar rotr64_lo = utils.rotr64_lo;\nvar shr64_hi = utils.shr64_hi;\nvar shr64_lo = utils.shr64_lo;\nvar sum64 = utils.sum64;\nvar sum64_hi = utils.sum64_hi;\nvar sum64_lo = utils.sum64_lo;\nvar sum64_4_hi = utils.sum64_4_hi;\nvar sum64_4_lo = utils.sum64_4_lo;\nvar sum64_5_hi = utils.sum64_5_hi;\nvar sum64_5_lo = utils.sum64_5_lo;\n\nvar BlockHash = common.BlockHash;\n\nvar sha512_K = [\n 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,\n 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,\n 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,\n 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,\n 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,\n 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,\n 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,\n 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,\n 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,\n 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,\n 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,\n 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,\n 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,\n 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,\n 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,\n 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,\n 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,\n 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,\n 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,\n 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,\n 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,\n 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,\n 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,\n 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,\n 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,\n 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,\n 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,\n 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,\n 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,\n 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,\n 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,\n 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,\n 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,\n 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,\n 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,\n 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,\n 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,\n 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,\n 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,\n 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817\n];\n\nfunction SHA512() {\n if (!(this instanceof SHA512))\n return new SHA512();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xf3bcc908,\n 0xbb67ae85, 0x84caa73b,\n 0x3c6ef372, 0xfe94f82b,\n 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1,\n 0x9b05688c, 0x2b3e6c1f,\n 0x1f83d9ab, 0xfb41bd6b,\n 0x5be0cd19, 0x137e2179 ];\n this.k = sha512_K;\n this.W = new Array(160);\n}\nutils.inherits(SHA512, BlockHash);\nmodule.exports = SHA512;\n\nSHA512.blockSize = 1024;\nSHA512.outSize = 512;\nSHA512.hmacStrength = 192;\nSHA512.padLength = 128;\n\nSHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {\n var W = this.W;\n\n // 32 x 32bit words\n for (var i = 0; i < 32; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i += 2) {\n var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2\n var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);\n var c1_hi = W[i - 14]; // i - 7\n var c1_lo = W[i - 13];\n var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15\n var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);\n var c3_hi = W[i - 32]; // i - 16\n var c3_lo = W[i - 31];\n\n W[i] = sum64_4_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n W[i + 1] = sum64_4_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n }\n};\n\nSHA512.prototype._update = function _update(msg, start) {\n this._prepareBlock(msg, start);\n\n var W = this.W;\n\n var ah = this.h[0];\n var al = this.h[1];\n var bh = this.h[2];\n var bl = this.h[3];\n var ch = this.h[4];\n var cl = this.h[5];\n var dh = this.h[6];\n var dl = this.h[7];\n var eh = this.h[8];\n var el = this.h[9];\n var fh = this.h[10];\n var fl = this.h[11];\n var gh = this.h[12];\n var gl = this.h[13];\n var hh = this.h[14];\n var hl = this.h[15];\n\n assert(this.k.length === W.length);\n for (var i = 0; i < W.length; i += 2) {\n var c0_hi = hh;\n var c0_lo = hl;\n var c1_hi = s1_512_hi(eh, el);\n var c1_lo = s1_512_lo(eh, el);\n var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);\n var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);\n var c3_hi = this.k[i];\n var c3_lo = this.k[i + 1];\n var c4_hi = W[i];\n var c4_lo = W[i + 1];\n\n var T1_hi = sum64_5_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n var T1_lo = sum64_5_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n\n c0_hi = s0_512_hi(ah, al);\n c0_lo = s0_512_lo(ah, al);\n c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);\n c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);\n\n var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);\n var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);\n\n hh = gh;\n hl = gl;\n\n gh = fh;\n gl = fl;\n\n fh = eh;\n fl = el;\n\n eh = sum64_hi(dh, dl, T1_hi, T1_lo);\n el = sum64_lo(dl, dl, T1_hi, T1_lo);\n\n dh = ch;\n dl = cl;\n\n ch = bh;\n cl = bl;\n\n bh = ah;\n bl = al;\n\n ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);\n al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);\n }\n\n sum64(this.h, 0, ah, al);\n sum64(this.h, 2, bh, bl);\n sum64(this.h, 4, ch, cl);\n sum64(this.h, 6, dh, dl);\n sum64(this.h, 8, eh, el);\n sum64(this.h, 10, fh, fl);\n sum64(this.h, 12, gh, gl);\n sum64(this.h, 14, hh, hl);\n};\n\nSHA512.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n\nfunction ch64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ ((~xh) & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction ch64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ ((~xl) & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 28);\n var c1_hi = rotr64_hi(xl, xh, 2); // 34\n var c2_hi = rotr64_hi(xl, xh, 7); // 39\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 28);\n var c1_lo = rotr64_lo(xl, xh, 2); // 34\n var c2_lo = rotr64_lo(xl, xh, 7); // 39\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 14);\n var c1_hi = rotr64_hi(xh, xl, 18);\n var c2_hi = rotr64_hi(xl, xh, 9); // 41\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 14);\n var c1_lo = rotr64_lo(xh, xl, 18);\n var c2_lo = rotr64_lo(xl, xh, 9); // 41\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 1);\n var c1_hi = rotr64_hi(xh, xl, 8);\n var c2_hi = shr64_hi(xh, xl, 7);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 1);\n var c1_lo = rotr64_lo(xh, xl, 8);\n var c2_lo = shr64_lo(xh, xl, 7);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 19);\n var c1_hi = rotr64_hi(xl, xh, 29); // 61\n var c2_hi = shr64_hi(xh, xl, 6);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 19);\n var c1_lo = rotr64_lo(xl, xh, 29); // 61\n var c2_lo = shr64_lo(xh, xl, 6);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTkwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixRQUFRO0FBQzFCO0FBQ0EsU0FBUyxjQUFjO0FBQ3ZCLGdEQUFnRDtBQUNoRDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzUxMi5qcz9iNTI1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbnZhciByb3RyNjRfaGkgPSB1dGlscy5yb3RyNjRfaGk7XG52YXIgcm90cjY0X2xvID0gdXRpbHMucm90cjY0X2xvO1xudmFyIHNocjY0X2hpID0gdXRpbHMuc2hyNjRfaGk7XG52YXIgc2hyNjRfbG8gPSB1dGlscy5zaHI2NF9sbztcbnZhciBzdW02NCA9IHV0aWxzLnN1bTY0O1xudmFyIHN1bTY0X2hpID0gdXRpbHMuc3VtNjRfaGk7XG52YXIgc3VtNjRfbG8gPSB1dGlscy5zdW02NF9sbztcbnZhciBzdW02NF80X2hpID0gdXRpbHMuc3VtNjRfNF9oaTtcbnZhciBzdW02NF80X2xvID0gdXRpbHMuc3VtNjRfNF9sbztcbnZhciBzdW02NF81X2hpID0gdXRpbHMuc3VtNjRfNV9oaTtcbnZhciBzdW02NF81X2xvID0gdXRpbHMuc3VtNjRfNV9sbztcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCxcbiAgICAweGJiNjdhZTg1LCAweDg0Y2FhNzNiLFxuICAgIDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIsXG4gICAgMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSxcbiAgICAweDUxMGU1MjdmLCAweGFkZTY4MmQxLFxuICAgIDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYsXG4gICAgMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YixcbiAgICAweDViZTBjZDE5LCAweDEzN2UyMTc5IF07XG4gIHRoaXMuayA9IHNoYTUxMl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoMTYwKTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTUxMiwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBNTEyO1xuXG5TSEE1MTIuYmxvY2tTaXplID0gMTAyNDtcblNIQTUxMi5vdXRTaXplID0gNTEyO1xuU0hBNTEyLmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTUxMi5wYWRMZW5ndGggPSAxMjg7XG5cblNIQTUxMi5wcm90b3R5cGUuX3ByZXBhcmVCbG9jayA9IGZ1bmN0aW9uIF9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICAvLyAzMiB4IDMyYml0IHdvcmRzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGcxXzUxMl9oaShXW2kgLSA0XSwgV1tpIC0gM10pOyAgLy8gaSAtIDJcbiAgICB2YXIgYzBfbG8gPSBnMV81MTJfbG8oV1tpIC0gNF0sIFdbaSAtIDNdKTtcbiAgICB2YXIgYzFfaGkgPSBXW2kgLSAxNF07ICAvLyBpIC0gN1xuICAgIHZhciBjMV9sbyA9IFdbaSAtIDEzXTtcbiAgICB2YXIgYzJfaGkgPSBnMF81MTJfaGkoV1tpIC0gMzBdLCBXW2kgLSAyOV0pOyAgLy8gaSAtIDE1XG4gICAgdmFyIGMyX2xvID0gZzBfNTEyX2xvKFdbaSAtIDMwXSwgV1tpIC0gMjldKTtcbiAgICB2YXIgYzNfaGkgPSBXW2kgLSAzMl07ICAvLyBpIC0gMTZcbiAgICB2YXIgYzNfbG8gPSBXW2kgLSAzMV07XG5cbiAgICBXW2ldID0gc3VtNjRfNF9oaShcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyk7XG4gICAgV1tpICsgMV0gPSBzdW02NF80X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcbiAgICB2YXIgVDFfbG8gPSBzdW02NF81X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcblxuICAgIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgYzBfbG8gPSBzMF81MTJfbG8oYWgsIGFsKTtcbiAgICBjMV9oaSA9IG1hajY0X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wpO1xuICAgIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gY2g2NF9oaSh4aCwgeGwsIHloLCB5bCwgemgpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICh4aCAmIHpoKSBeICh5aCAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKHhsICYgemwpIF4gKHlsICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDEpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDEpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5900\n")},7038:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar rotr32 = utils.rotr32;\n\nfunction ft_1(s, x, y, z) {\n if (s === 0)\n return ch32(x, y, z);\n if (s === 1 || s === 3)\n return p32(x, y, z);\n if (s === 2)\n return maj32(x, y, z);\n}\nexports.ft_1 = ft_1;\n\nfunction ch32(x, y, z) {\n return (x & y) ^ ((~x) & z);\n}\nexports.ch32 = ch32;\n\nfunction maj32(x, y, z) {\n return (x & y) ^ (x & z) ^ (y & z);\n}\nexports.maj32 = maj32;\n\nfunction p32(x, y, z) {\n return x ^ y ^ z;\n}\nexports.p32 = p32;\n\nfunction s0_256(x) {\n return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);\n}\nexports.s0_256 = s0_256;\n\nfunction s1_256(x) {\n return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);\n}\nexports.s1_256 = s1_256;\n\nfunction g0_256(x) {\n return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);\n}\nexports.g0_256 = g0_256;\n\nfunction g1_256(x) {\n return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);\n}\nexports.g1_256 = g1_256;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAzOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0EsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxjQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS9jb21tb24uanM/YWE1NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgcm90cjMyID0gdXRpbHMucm90cjMyO1xuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuZXhwb3J0cy5mdF8xID0gZnRfMTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cbmV4cG9ydHMuY2gzMiA9IGNoMzI7XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cbmV4cG9ydHMubWFqMzIgPSBtYWozMjtcblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cbmV4cG9ydHMucDMyID0gcDMyO1xuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5leHBvcnRzLnMwXzI1NiA9IHMwXzI1NjtcblxuZnVuY3Rpb24gczFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA2KSBeIHJvdHIzMih4LCAxMSkgXiByb3RyMzIoeCwgMjUpO1xufVxuZXhwb3J0cy5zMV8yNTYgPSBzMV8yNTY7XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuZXhwb3J0cy5nMF8yNTYgPSBnMF8yNTY7XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5leHBvcnRzLmcxXzI1NiA9IGcxXzI1NjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7038\n")},6436:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar assert = __webpack_require__(9746);\nvar inherits = __webpack_require__(5717);\n\nexports.inherits = inherits;\n\nfunction isSurrogatePair(msg, i) {\n if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {\n return false;\n }\n if (i < 0 || i + 1 >= msg.length) {\n return false;\n }\n return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;\n}\n\nfunction toArray(msg, enc) {\n if (Array.isArray(msg))\n return msg.slice();\n if (!msg)\n return [];\n var res = [];\n if (typeof msg === 'string') {\n if (!enc) {\n // Inspired by stringToUtf8ByteArray() in closure-library by Google\n // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143\n // Apache License 2.0\n // https://github.com/google/closure-library/blob/master/LICENSE\n var p = 0;\n for (var i = 0; i < msg.length; i++) {\n var c = msg.charCodeAt(i);\n if (c < 128) {\n res[p++] = c;\n } else if (c < 2048) {\n res[p++] = (c >> 6) | 192;\n res[p++] = (c & 63) | 128;\n } else if (isSurrogatePair(msg, i)) {\n c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);\n res[p++] = (c >> 18) | 240;\n res[p++] = ((c >> 12) & 63) | 128;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n } else {\n res[p++] = (c >> 12) | 224;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n }\n }\n } else if (enc === 'hex') {\n msg = msg.replace(/[^a-z0-9]+/ig, '');\n if (msg.length % 2 !== 0)\n msg = '0' + msg;\n for (i = 0; i < msg.length; i += 2)\n res.push(parseInt(msg[i] + msg[i + 1], 16));\n }\n } else {\n for (i = 0; i < msg.length; i++)\n res[i] = msg[i] | 0;\n }\n return res;\n}\nexports.toArray = toArray;\n\nfunction toHex(msg) {\n var res = '';\n for (var i = 0; i < msg.length; i++)\n res += zero2(msg[i].toString(16));\n return res;\n}\nexports.toHex = toHex;\n\nfunction htonl(w) {\n var res = (w >>> 24) |\n ((w >>> 8) & 0xff00) |\n ((w << 8) & 0xff0000) |\n ((w & 0xff) << 24);\n return res >>> 0;\n}\nexports.htonl = htonl;\n\nfunction toHex32(msg, endian) {\n var res = '';\n for (var i = 0; i < msg.length; i++) {\n var w = msg[i];\n if (endian === 'little')\n w = htonl(w);\n res += zero8(w.toString(16));\n }\n return res;\n}\nexports.toHex32 = toHex32;\n\nfunction zero2(word) {\n if (word.length === 1)\n return '0' + word;\n else\n return word;\n}\nexports.zero2 = zero2;\n\nfunction zero8(word) {\n if (word.length === 7)\n return '0' + word;\n else if (word.length === 6)\n return '00' + word;\n else if (word.length === 5)\n return '000' + word;\n else if (word.length === 4)\n return '0000' + word;\n else if (word.length === 3)\n return '00000' + word;\n else if (word.length === 2)\n return '000000' + word;\n else if (word.length === 1)\n return '0000000' + word;\n else\n return word;\n}\nexports.zero8 = zero8;\n\nfunction join32(msg, start, end, endian) {\n var len = end - start;\n assert(len % 4 === 0);\n var res = new Array(len / 4);\n for (var i = 0, k = start; i < res.length; i++, k += 4) {\n var w;\n if (endian === 'big')\n w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];\n else\n w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];\n res[i] = w >>> 0;\n }\n return res;\n}\nexports.join32 = join32;\n\nfunction split32(msg, endian) {\n var res = new Array(msg.length * 4);\n for (var i = 0, k = 0; i < msg.length; i++, k += 4) {\n var m = msg[i];\n if (endian === 'big') {\n res[k] = m >>> 24;\n res[k + 1] = (m >>> 16) & 0xff;\n res[k + 2] = (m >>> 8) & 0xff;\n res[k + 3] = m & 0xff;\n } else {\n res[k + 3] = m >>> 24;\n res[k + 2] = (m >>> 16) & 0xff;\n res[k + 1] = (m >>> 8) & 0xff;\n res[k] = m & 0xff;\n }\n }\n return res;\n}\nexports.split32 = split32;\n\nfunction rotr32(w, b) {\n return (w >>> b) | (w << (32 - b));\n}\nexports.rotr32 = rotr32;\n\nfunction rotl32(w, b) {\n return (w << b) | (w >>> (32 - b));\n}\nexports.rotl32 = rotl32;\n\nfunction sum32(a, b) {\n return (a + b) >>> 0;\n}\nexports.sum32 = sum32;\n\nfunction sum32_3(a, b, c) {\n return (a + b + c) >>> 0;\n}\nexports.sum32_3 = sum32_3;\n\nfunction sum32_4(a, b, c, d) {\n return (a + b + c + d) >>> 0;\n}\nexports.sum32_4 = sum32_4;\n\nfunction sum32_5(a, b, c, d, e) {\n return (a + b + c + d + e) >>> 0;\n}\nexports.sum32_5 = sum32_5;\n\nfunction sum64(buf, pos, ah, al) {\n var bh = buf[pos];\n var bl = buf[pos + 1];\n\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n buf[pos] = hi >>> 0;\n buf[pos + 1] = lo;\n}\nexports.sum64 = sum64;\n\nfunction sum64_hi(ah, al, bh, bl) {\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n return hi >>> 0;\n}\nexports.sum64_hi = sum64_hi;\n\nfunction sum64_lo(ah, al, bh, bl) {\n var lo = al + bl;\n return lo >>> 0;\n}\nexports.sum64_lo = sum64_lo;\n\nfunction sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n\n var hi = ah + bh + ch + dh + carry;\n return hi >>> 0;\n}\nexports.sum64_4_hi = sum64_4_hi;\n\nfunction sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {\n var lo = al + bl + cl + dl;\n return lo >>> 0;\n}\nexports.sum64_4_lo = sum64_4_lo;\n\nfunction sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n lo = (lo + el) >>> 0;\n carry += lo < el ? 1 : 0;\n\n var hi = ah + bh + ch + dh + eh + carry;\n return hi >>> 0;\n}\nexports.sum64_5_hi = sum64_5_hi;\n\nfunction sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var lo = al + bl + cl + dl + el;\n\n return lo >>> 0;\n}\nexports.sum64_5_lo = sum64_5_lo;\n\nfunction rotr64_hi(ah, al, num) {\n var r = (al << (32 - num)) | (ah >>> num);\n return r >>> 0;\n}\nexports.rotr64_hi = rotr64_hi;\n\nfunction rotr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.rotr64_lo = rotr64_lo;\n\nfunction shr64_hi(ah, al, num) {\n return ah >>> num;\n}\nexports.shr64_hi = shr64_hi;\n\nfunction shr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.shr64_lo = shr64_lo;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBcUI7QUFDMUMsZUFBZSxtQkFBTyxDQUFDLElBQVU7O0FBRWpDLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGdCQUFnQjtBQUN0QztBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0EsSUFBSTtBQUNKLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsZ0JBQWdCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcz9jM2MwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuaW5oZXJpdHMgPSBpbmhlcml0cztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkge1xuICBpZiAoKG1zZy5jaGFyQ29kZUF0KGkpICYgMHhGQzAwKSAhPT0gMHhEODAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpIDwgMCB8fCBpICsgMSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAobXNnLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwO1xufVxuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIC8vIEluc3BpcmVkIGJ5IHN0cmluZ1RvVXRmOEJ5dGVBcnJheSgpIGluIGNsb3N1cmUtbGlicmFyeSBieSBHb29nbGVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvODU5OGQ4NzI0MmFmNTlhYWMyMzMyNzA3NDJjODk4NGUyYjJiZGJlMC9jbG9zdXJlL2dvb2cvY3J5cHQvY3J5cHQuanMjTDExNy1MMTQzXG4gICAgICAvLyBBcGFjaGUgTGljZW5zZSAyLjBcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAgICAgIHZhciBwID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSBjO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPCAyMDQ4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyA+PiA2KSB8IDE5MjtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3Vycm9nYXRlUGFpcihtc2csIGkpKSB7XG4gICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgJiAweDAzRkYpIDw8IDEwKSArIChtc2cuY2hhckNvZGVBdCgrK2kpICYgMHgwM0ZGKTtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDE4KSB8IDI0MDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiAxMikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoKGMgPj4gNikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyAmIDYzKSB8IDEyODtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDEyKSB8IDIyNDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleCA9IHRvSGV4O1xuXG5mdW5jdGlvbiBodG9ubCh3KSB7XG4gIHZhciByZXMgPSAodyA+Pj4gMjQpIHxcbiAgICAgICAgICAgICgodyA+Pj4gOCkgJiAweGZmMDApIHxcbiAgICAgICAgICAgICgodyA8PCA4KSAmIDB4ZmYwMDAwKSB8XG4gICAgICAgICAgICAoKHcgJiAweGZmKSA8PCAyNCk7XG4gIHJldHVybiByZXMgPj4+IDA7XG59XG5leHBvcnRzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHplcm84KHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSA3KVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNilcbiAgICByZXR1cm4gJzAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA1KVxuICAgIHJldHVybiAnMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA0KVxuICAgIHJldHVybiAnMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMylcbiAgICByZXR1cm4gJzAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAyKVxuICAgIHJldHVybiAnMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMDAwMDAwMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5zcGxpdDMyID0gc3BsaXQzMjtcblxuZnVuY3Rpb24gcm90cjMyKHcsIGIpIHtcbiAgcmV0dXJuICh3ID4+PiBiKSB8ICh3IDw8ICgzMiAtIGIpKTtcbn1cbmV4cG9ydHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyID0gc3VtMzI7XG5cbmZ1bmN0aW9uIHN1bTMyXzMoYSwgYiwgYykge1xuICByZXR1cm4gKGEgKyBiICsgYykgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNSA9IHN1bTMyXzU7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0X2hpID0gc3VtNjRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0X2xvKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IGFsICsgYmw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNF9sbyA9IHN1bTY0XzRfbG87XG5cbmZ1bmN0aW9uIHN1bTY0XzVfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZWwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGVsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBlaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMucm90cjY0X2hpID0gcm90cjY0X2hpO1xuXG5mdW5jdGlvbiByb3RyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufVxuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnNocjY0X2xvID0gc2hyNjRfbG87XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6436\n")},5717:function(module){eval("if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTcxNy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzPzNmYjUiXSwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5717\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},9746:function(module){eval("module.exports = assert;\n\nfunction assert(val, msg) {\n if (!val)\n throw new Error(msg || 'Assertion failed');\n}\n\nassert.equal = function assertEqual(l, r, msg) {\n if (l != r)\n throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvbWluaW1hbGlzdGljLWFzc2VydC9pbmRleC5qcz9kYTNlIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXNzZXJ0O1xuXG5mdW5jdGlvbiBhc3NlcnQodmFsLCBtc2cpIHtcbiAgaWYgKCF2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBhc3NlcnRFcXVhbChsLCByLCBtc2cpIHtcbiAgaWYgKGwgIT0gcilcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICgnQXNzZXJ0aW9uIGZhaWxlZDogJyArIGwgKyAnICE9ICcgKyByKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9746\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz80ZWE4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz83NGM5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/YTYyMCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzPzAxZjQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NjY2MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/NmY5MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz81YTAxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/NDI2NCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz81YWVhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzPzYzOTQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz84ZDcxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/ZWFhNyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzhlMDkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz8xMzA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82NzlhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz84NzVlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZTg1OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzP2IzN2MiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzP2EwODciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz9iODZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz9iMjE4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YzQyNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzPzFkZTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz85OTYyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz8wOGE4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZjM5ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz9iYWU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzP2UzYTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz84OTU0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz80YmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz82OTRmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz9lZDNhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzU5OGMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9hODA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz9kNGYxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/Y2E0MCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz82ZDczIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzYyZjQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/NzhjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/NjBhNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9lNWExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/OGYyNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/NjEwMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/YzRkZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzP2VkYzMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzP2U3ODEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz9hODFhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzP2NmYjYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/Yjk1MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz83NzM0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzP2NlNzIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZmQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/YTNiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/NzQ3OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz84YTM0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzP2Q4MmUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/OGRmNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9lMGI2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(Q){var t=__webpack_module_cache__[Q];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[Q]={exports:{}};return __webpack_modules__[Q](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=function(Q){var t=Q&&Q.__esModule?function(){return Q.default}:function(){return Q};return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=function(Q,t){for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(Q,n)&&Object.defineProperty(Q,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=function(Q,t){return Object.prototype.hasOwnProperty.call(Q,t)};var __webpack_exports__=__webpack_require__(5232)})(); \ No newline at end of file +(function(){var __webpack_modules__={3089:function(__unused_webpack_module,exports){"use strict";eval('var __webpack_unused_export__;\n\n/**\n * Implementation of Myers\' online approximate string matching algorithm [1],\n * with additional optimizations suggested by [2].\n *\n * This has O((k/w) * n) complexity where `n` is the length of the text, `k` is\n * the maximum number of errors allowed (always <= the pattern length) and `w`\n * is the word size. Because JS only supports bitwise operations on 32 bit\n * integers, `w` is 32.\n *\n * As far as I am aware, there aren\'t any online algorithms which are\n * significantly better for a wide range of input parameters. The problem can be\n * solved faster using "filter then verify" approaches which first filter out\n * regions of the text that cannot match using a "cheap" check and then verify\n * the remaining potential matches. The verify step requires an algorithm such\n * as this one however.\n *\n * The algorithm\'s approach is essentially to optimize the classic dynamic\n * programming solution to the problem by computing columns of the matrix in\n * word-sized chunks (ie. dealing with 32 chars of the pattern at a time) and\n * avoiding calculating regions of the matrix where the minimum error count is\n * guaranteed to exceed the input threshold.\n *\n * The paper consists of two parts, the first describes the core algorithm for\n * matching patterns <= the size of a word (implemented by `advanceBlock` here).\n * The second uses the core algorithm as part of a larger block-based algorithm\n * to handle longer patterns.\n *\n * [1] G. Myers, “A Fast Bit-Vector Algorithm for Approximate String Matching\n * Based on Dynamic Programming,” vol. 46, no. 3, pp. 395–415, 1999.\n *\n * [2] Šošić, M. (2014). An simd dynamic programming c/c++ library (Doctoral\n * dissertation, Fakultet Elektrotehnike i računarstva, Sveučilište u Zagrebu).\n */\n__webpack_unused_export__ = ({ value: true });\nfunction reverse(s) {\n return s\n .split("")\n .reverse()\n .join("");\n}\n/**\n * Given the ends of approximate matches for `pattern` in `text`, find\n * the start of the matches.\n *\n * @param findEndFn - Function for finding the end of matches in\n * text.\n * @return Matches with the `start` property set.\n */\nfunction findMatchStarts(text, pattern, matches) {\n var patRev = reverse(pattern);\n return matches.map(function (m) {\n // Find start of each match by reversing the pattern and matching segment\n // of text and searching for an approx match with the same number of\n // errors.\n var minStart = Math.max(0, m.end - pattern.length - m.errors);\n var textRev = reverse(text.slice(minStart, m.end));\n // If there are multiple possible start points, choose the one that\n // maximizes the length of the match.\n var start = findMatchEnds(textRev, patRev, m.errors).reduce(function (min, rm) {\n if (m.end - rm.end < min) {\n return m.end - rm.end;\n }\n return min;\n }, m.end);\n return {\n start: start,\n end: m.end,\n errors: m.errors\n };\n });\n}\n/**\n * Return 1 if a number is non-zero or zero otherwise, without using\n * conditional operators.\n *\n * This should get inlined into `advanceBlock` below by the JIT.\n *\n * Adapted from https://stackoverflow.com/a/3912218/434243\n */\nfunction oneIfNotZero(n) {\n return ((n | -n) >> 31) & 1;\n}\n/**\n * Block calculation step of the algorithm.\n *\n * From Fig 8. on p. 408 of [1], additionally optimized to replace conditional\n * checks with bitwise operations as per Section 4.2.3 of [2].\n *\n * @param ctx - The pattern context object\n * @param peq - The `peq` array for the current character (`ctx.peq.get(ch)`)\n * @param b - The block level\n * @param hIn - Horizontal input delta ∈ {1,0,-1}\n * @return Horizontal output delta ∈ {1,0,-1}\n */\nfunction advanceBlock(ctx, peq, b, hIn) {\n var pV = ctx.P[b];\n var mV = ctx.M[b];\n var hInIsNegative = hIn >>> 31; // 1 if hIn < 0 or 0 otherwise.\n var eq = peq[b] | hInIsNegative;\n // Step 1: Compute horizontal deltas.\n var xV = eq | mV;\n var xH = (((eq & pV) + pV) ^ pV) | eq;\n var pH = mV | ~(xH | pV);\n var mH = pV & xH;\n // Step 2: Update score (value of last row of this block).\n var hOut = oneIfNotZero(pH & ctx.lastRowMask[b]) -\n oneIfNotZero(mH & ctx.lastRowMask[b]);\n // Step 3: Update vertical deltas for use when processing next char.\n pH <<= 1;\n mH <<= 1;\n mH |= hInIsNegative;\n pH |= oneIfNotZero(hIn) - hInIsNegative; // set pH[0] if hIn > 0\n pV = mH | ~(xV | pH);\n mV = pH & xV;\n ctx.P[b] = pV;\n ctx.M[b] = mV;\n return hOut;\n}\n/**\n * Find the ends and error counts for matches of `pattern` in `text`.\n *\n * Only the matches with the lowest error count are reported. Other matches\n * with error counts <= maxErrors are discarded.\n *\n * This is the block-based search algorithm from Fig. 9 on p.410 of [1].\n */\nfunction findMatchEnds(text, pattern, maxErrors) {\n if (pattern.length === 0) {\n return [];\n }\n // Clamp error count so we can rely on the `maxErrors` and `pattern.length`\n // rows being in the same block below.\n maxErrors = Math.min(maxErrors, pattern.length);\n var matches = [];\n // Word size.\n var w = 32;\n // Index of maximum block level.\n var bMax = Math.ceil(pattern.length / w) - 1;\n // Context used across block calculations.\n var ctx = {\n P: new Uint32Array(bMax + 1),\n M: new Uint32Array(bMax + 1),\n lastRowMask: new Uint32Array(bMax + 1)\n };\n ctx.lastRowMask.fill(1 << 31);\n ctx.lastRowMask[bMax] = 1 << (pattern.length - 1) % w;\n // Dummy "peq" array for chars in the text which do not occur in the pattern.\n var emptyPeq = new Uint32Array(bMax + 1);\n // Map of UTF-16 character code to bit vector indicating positions in the\n // pattern that equal that character.\n var peq = new Map();\n // Version of `peq` that only stores mappings for small characters. This\n // allows faster lookups when iterating through the text because a simple\n // array lookup can be done instead of a hash table lookup.\n var asciiPeq = [];\n for (var i = 0; i < 256; i++) {\n asciiPeq.push(emptyPeq);\n }\n // Calculate `ctx.peq` - a map of character values to bitmasks indicating\n // positions of that character within the pattern, where each bit represents\n // a position in the pattern.\n for (var c = 0; c < pattern.length; c += 1) {\n var val = pattern.charCodeAt(c);\n if (peq.has(val)) {\n // Duplicate char in pattern.\n continue;\n }\n var charPeq = new Uint32Array(bMax + 1);\n peq.set(val, charPeq);\n if (val < asciiPeq.length) {\n asciiPeq[val] = charPeq;\n }\n for (var b = 0; b <= bMax; b += 1) {\n charPeq[b] = 0;\n // Set all the bits where the pattern matches the current char (ch).\n // For indexes beyond the end of the pattern, always set the bit as if the\n // pattern contained a wildcard char in that position.\n for (var r = 0; r < w; r += 1) {\n var idx = b * w + r;\n if (idx >= pattern.length) {\n continue;\n }\n var match = pattern.charCodeAt(idx) === val;\n if (match) {\n charPeq[b] |= 1 << r;\n }\n }\n }\n }\n // Index of last-active block level in the column.\n var y = Math.max(0, Math.ceil(maxErrors / w) - 1);\n // Initialize maximum error count at bottom of each block.\n var score = new Uint32Array(bMax + 1);\n for (var b = 0; b <= y; b += 1) {\n score[b] = (b + 1) * w;\n }\n score[bMax] = pattern.length;\n // Initialize vertical deltas for each block.\n for (var b = 0; b <= y; b += 1) {\n ctx.P[b] = ~0;\n ctx.M[b] = 0;\n }\n // Process each char of the text, computing the error count for `w` chars of\n // the pattern at a time.\n for (var j = 0; j < text.length; j += 1) {\n // Lookup the bitmask representing the positions of the current char from\n // the text within the pattern.\n var charCode = text.charCodeAt(j);\n var charPeq = void 0;\n if (charCode < asciiPeq.length) {\n // Fast array lookup.\n charPeq = asciiPeq[charCode];\n }\n else {\n // Slower hash table lookup.\n charPeq = peq.get(charCode);\n if (typeof charPeq === "undefined") {\n charPeq = emptyPeq;\n }\n }\n // Calculate error count for blocks that we definitely have to process for\n // this column.\n var carry = 0;\n for (var b = 0; b <= y; b += 1) {\n carry = advanceBlock(ctx, charPeq, b, carry);\n score[b] += carry;\n }\n // Check if we also need to compute an additional block, or if we can reduce\n // the number of blocks processed for the next column.\n if (score[y] - carry <= maxErrors &&\n y < bMax &&\n (charPeq[y + 1] & 1 || carry < 0)) {\n // Error count for bottom block is under threshold, increase the number of\n // blocks processed for this column & next by 1.\n y += 1;\n ctx.P[y] = ~0;\n ctx.M[y] = 0;\n var maxBlockScore = y === bMax ? pattern.length % w : w;\n score[y] =\n score[y - 1] +\n maxBlockScore -\n carry +\n advanceBlock(ctx, charPeq, y, carry);\n }\n else {\n // Error count for bottom block exceeds threshold, reduce the number of\n // blocks processed for the next column.\n while (y > 0 && score[y] >= maxErrors + w) {\n y -= 1;\n }\n }\n // If error count is under threshold, report a match.\n if (y === bMax && score[y] <= maxErrors) {\n if (score[y] < maxErrors) {\n // Discard any earlier, worse matches.\n matches.splice(0, matches.length);\n }\n matches.push({\n start: -1,\n end: j + 1,\n errors: score[y]\n });\n // Because `search` only reports the matches with the lowest error count,\n // we can "ratchet down" the max error threshold whenever a match is\n // encountered and thereby save a small amount of work for the remainder\n // of the text.\n maxErrors = score[y];\n }\n }\n return matches;\n}\n/**\n * Search for matches for `pattern` in `text` allowing up to `maxErrors` errors.\n *\n * Returns the start, and end positions and error counts for each lowest-cost\n * match. Only the "best" matches are returned.\n */\nfunction search(text, pattern, maxErrors) {\n var matches = findMatchEnds(text, pattern, maxErrors);\n return findMatchStarts(text, pattern, matches);\n}\nexports.Z = search;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA4OS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkMsRUFBRSxhQUFhLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLE9BQU87QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2FwcHJveC1zdHJpbmctbWF0Y2gvZGlzdC9pbmRleC5qcz83MjMwIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBNeWVycycgb25saW5lIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBhbGdvcml0aG0gWzFdLFxuICogd2l0aCBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgc3VnZ2VzdGVkIGJ5IFsyXS5cbiAqXG4gKiBUaGlzIGhhcyBPKChrL3cpICogbikgY29tcGxleGl0eSB3aGVyZSBgbmAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCwgYGtgIGlzXG4gKiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIGFsbG93ZWQgKGFsd2F5cyA8PSB0aGUgcGF0dGVybiBsZW5ndGgpIGFuZCBgd2BcbiAqIGlzIHRoZSB3b3JkIHNpemUuIEJlY2F1c2UgSlMgb25seSBzdXBwb3J0cyBiaXR3aXNlIG9wZXJhdGlvbnMgb24gMzIgYml0XG4gKiBpbnRlZ2VycywgYHdgIGlzIDMyLlxuICpcbiAqIEFzIGZhciBhcyBJIGFtIGF3YXJlLCB0aGVyZSBhcmVuJ3QgYW55IG9ubGluZSBhbGdvcml0aG1zIHdoaWNoIGFyZVxuICogc2lnbmlmaWNhbnRseSBiZXR0ZXIgZm9yIGEgd2lkZSByYW5nZSBvZiBpbnB1dCBwYXJhbWV0ZXJzLiBUaGUgcHJvYmxlbSBjYW4gYmVcbiAqIHNvbHZlZCBmYXN0ZXIgdXNpbmcgXCJmaWx0ZXIgdGhlbiB2ZXJpZnlcIiBhcHByb2FjaGVzIHdoaWNoIGZpcnN0IGZpbHRlciBvdXRcbiAqIHJlZ2lvbnMgb2YgdGhlIHRleHQgdGhhdCBjYW5ub3QgbWF0Y2ggdXNpbmcgYSBcImNoZWFwXCIgY2hlY2sgYW5kIHRoZW4gdmVyaWZ5XG4gKiB0aGUgcmVtYWluaW5nIHBvdGVudGlhbCBtYXRjaGVzLiBUaGUgdmVyaWZ5IHN0ZXAgcmVxdWlyZXMgYW4gYWxnb3JpdGhtIHN1Y2hcbiAqIGFzIHRoaXMgb25lIGhvd2V2ZXIuXG4gKlxuICogVGhlIGFsZ29yaXRobSdzIGFwcHJvYWNoIGlzIGVzc2VudGlhbGx5IHRvIG9wdGltaXplIHRoZSBjbGFzc2ljIGR5bmFtaWNcbiAqIHByb2dyYW1taW5nIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGJ5IGNvbXB1dGluZyBjb2x1bW5zIG9mIHRoZSBtYXRyaXggaW5cbiAqIHdvcmQtc2l6ZWQgY2h1bmtzIChpZS4gZGVhbGluZyB3aXRoIDMyIGNoYXJzIG9mIHRoZSBwYXR0ZXJuIGF0IGEgdGltZSkgYW5kXG4gKiBhdm9pZGluZyBjYWxjdWxhdGluZyByZWdpb25zIG9mIHRoZSBtYXRyaXggd2hlcmUgdGhlIG1pbmltdW0gZXJyb3IgY291bnQgaXNcbiAqIGd1YXJhbnRlZWQgdG8gZXhjZWVkIHRoZSBpbnB1dCB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHBhcGVyIGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgdGhlIGZpcnN0IGRlc2NyaWJlcyB0aGUgY29yZSBhbGdvcml0aG0gZm9yXG4gKiBtYXRjaGluZyBwYXR0ZXJucyA8PSB0aGUgc2l6ZSBvZiBhIHdvcmQgKGltcGxlbWVudGVkIGJ5IGBhZHZhbmNlQmxvY2tgIGhlcmUpLlxuICogVGhlIHNlY29uZCB1c2VzIHRoZSBjb3JlIGFsZ29yaXRobSBhcyBwYXJ0IG9mIGEgbGFyZ2VyIGJsb2NrLWJhc2VkIGFsZ29yaXRobVxuICogdG8gaGFuZGxlIGxvbmdlciBwYXR0ZXJucy5cbiAqXG4gKiBbMV0gRy4gTXllcnMsIOKAnEEgRmFzdCBCaXQtVmVjdG9yIEFsZ29yaXRobSBmb3IgQXBwcm94aW1hdGUgU3RyaW5nIE1hdGNoaW5nXG4gKiBCYXNlZCBvbiBEeW5hbWljIFByb2dyYW1taW5nLOKAnSB2b2wuIDQ2LCBuby4gMywgcHAuIDM5NeKAkzQxNSwgMTk5OS5cbiAqXG4gKiBbMl0gxaBvxaFpxIcsIE0uICgyMDE0KS4gQW4gc2ltZCBkeW5hbWljIHByb2dyYW1taW5nIGMvYysrIGxpYnJhcnkgKERvY3RvcmFsXG4gKiBkaXNzZXJ0YXRpb24sIEZha3VsdGV0IEVsZWt0cm90ZWhuaWtlIGkgcmHEjXVuYXJzdHZhLCBTdmV1xI1pbGnFoXRlIHUgWmFncmVidSkuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJldmVyc2Uocykge1xuICAgIHJldHVybiBzXG4gICAgICAgIC5zcGxpdChcIlwiKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5qb2luKFwiXCIpO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgZW5kcyBvZiBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHRleHRgLCBmaW5kXG4gKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMuXG4gKlxuICogQHBhcmFtIGZpbmRFbmRGbiAtIEZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBlbmQgb2YgbWF0Y2hlcyBpblxuICogdGV4dC5cbiAqIEByZXR1cm4gTWF0Y2hlcyB3aXRoIHRoZSBgc3RhcnRgIHByb3BlcnR5IHNldC5cbiAqL1xuZnVuY3Rpb24gZmluZE1hdGNoU3RhcnRzKHRleHQsIHBhdHRlcm4sIG1hdGNoZXMpIHtcbiAgICB2YXIgcGF0UmV2ID0gcmV2ZXJzZShwYXR0ZXJuKTtcbiAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgLy8gRmluZCBzdGFydCBvZiBlYWNoIG1hdGNoIGJ5IHJldmVyc2luZyB0aGUgcGF0dGVybiBhbmQgbWF0Y2hpbmcgc2VnbWVudFxuICAgICAgICAvLyBvZiB0ZXh0IGFuZCBzZWFyY2hpbmcgZm9yIGFuIGFwcHJveCBtYXRjaCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZlxuICAgICAgICAvLyBlcnJvcnMuXG4gICAgICAgIHZhciBtaW5TdGFydCA9IE1hdGgubWF4KDAsIG0uZW5kIC0gcGF0dGVybi5sZW5ndGggLSBtLmVycm9ycyk7XG4gICAgICAgIHZhciB0ZXh0UmV2ID0gcmV2ZXJzZSh0ZXh0LnNsaWNlKG1pblN0YXJ0LCBtLmVuZCkpO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgc3RhcnQgcG9pbnRzLCBjaG9vc2UgdGhlIG9uZSB0aGF0XG4gICAgICAgIC8vIG1heGltaXplcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaC5cbiAgICAgICAgdmFyIHN0YXJ0ID0gZmluZE1hdGNoRW5kcyh0ZXh0UmV2LCBwYXRSZXYsIG0uZXJyb3JzKS5yZWR1Y2UoZnVuY3Rpb24gKG1pbiwgcm0pIHtcbiAgICAgICAgICAgIGlmIChtLmVuZCAtIHJtLmVuZCA8IG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmVuZCAtIHJtLmVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtaW47XG4gICAgICAgIH0sIG0uZW5kKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogbS5lbmQsXG4gICAgICAgICAgICBlcnJvcnM6IG0uZXJyb3JzXG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybiAxIGlmIGEgbnVtYmVyIGlzIG5vbi16ZXJvIG9yIHplcm8gb3RoZXJ3aXNlLCB3aXRob3V0IHVzaW5nXG4gKiBjb25kaXRpb25hbCBvcGVyYXRvcnMuXG4gKlxuICogVGhpcyBzaG91bGQgZ2V0IGlubGluZWQgaW50byBgYWR2YW5jZUJsb2NrYCBiZWxvdyBieSB0aGUgSklULlxuICpcbiAqIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzkxMjIxOC80MzQyNDNcbiAqL1xuZnVuY3Rpb24gb25lSWZOb3RaZXJvKG4pIHtcbiAgICByZXR1cm4gKChuIHwgLW4pID4+IDMxKSAmIDE7XG59XG4vKipcbiAqIEJsb2NrIGNhbGN1bGF0aW9uIHN0ZXAgb2YgdGhlIGFsZ29yaXRobS5cbiAqXG4gKiBGcm9tIEZpZyA4LiBvbiBwLiA0MDggb2YgWzFdLCBhZGRpdGlvbmFsbHkgb3B0aW1pemVkIHRvIHJlcGxhY2UgY29uZGl0aW9uYWxcbiAqIGNoZWNrcyB3aXRoIGJpdHdpc2Ugb3BlcmF0aW9ucyBhcyBwZXIgU2VjdGlvbiA0LjIuMyBvZiBbMl0uXG4gKlxuICogQHBhcmFtIGN0eCAtIFRoZSBwYXR0ZXJuIGNvbnRleHQgb2JqZWN0XG4gKiBAcGFyYW0gcGVxIC0gVGhlIGBwZXFgIGFycmF5IGZvciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgKGBjdHgucGVxLmdldChjaClgKVxuICogQHBhcmFtIGIgLSBUaGUgYmxvY2sgbGV2ZWxcbiAqIEBwYXJhbSBoSW4gLSBIb3Jpem9udGFsIGlucHV0IGRlbHRhIOKIiCB7MSwwLC0xfVxuICogQHJldHVybiBIb3Jpem9udGFsIG91dHB1dCBkZWx0YSDiiIggezEsMCwtMX1cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUJsb2NrKGN0eCwgcGVxLCBiLCBoSW4pIHtcbiAgICB2YXIgcFYgPSBjdHguUFtiXTtcbiAgICB2YXIgbVYgPSBjdHguTVtiXTtcbiAgICB2YXIgaEluSXNOZWdhdGl2ZSA9IGhJbiA+Pj4gMzE7IC8vIDEgaWYgaEluIDwgMCBvciAwIG90aGVyd2lzZS5cbiAgICB2YXIgZXEgPSBwZXFbYl0gfCBoSW5Jc05lZ2F0aXZlO1xuICAgIC8vIFN0ZXAgMTogQ29tcHV0ZSBob3Jpem9udGFsIGRlbHRhcy5cbiAgICB2YXIgeFYgPSBlcSB8IG1WO1xuICAgIHZhciB4SCA9ICgoKGVxICYgcFYpICsgcFYpIF4gcFYpIHwgZXE7XG4gICAgdmFyIHBIID0gbVYgfCB+KHhIIHwgcFYpO1xuICAgIHZhciBtSCA9IHBWICYgeEg7XG4gICAgLy8gU3RlcCAyOiBVcGRhdGUgc2NvcmUgKHZhbHVlIG9mIGxhc3Qgcm93IG9mIHRoaXMgYmxvY2spLlxuICAgIHZhciBoT3V0ID0gb25lSWZOb3RaZXJvKHBIICYgY3R4Lmxhc3RSb3dNYXNrW2JdKSAtXG4gICAgICAgIG9uZUlmTm90WmVybyhtSCAmIGN0eC5sYXN0Um93TWFza1tiXSk7XG4gICAgLy8gU3RlcCAzOiBVcGRhdGUgdmVydGljYWwgZGVsdGFzIGZvciB1c2Ugd2hlbiBwcm9jZXNzaW5nIG5leHQgY2hhci5cbiAgICBwSCA8PD0gMTtcbiAgICBtSCA8PD0gMTtcbiAgICBtSCB8PSBoSW5Jc05lZ2F0aXZlO1xuICAgIHBIIHw9IG9uZUlmTm90WmVybyhoSW4pIC0gaEluSXNOZWdhdGl2ZTsgLy8gc2V0IHBIWzBdIGlmIGhJbiA+IDBcbiAgICBwViA9IG1IIHwgfih4ViB8IHBIKTtcbiAgICBtViA9IHBIICYgeFY7XG4gICAgY3R4LlBbYl0gPSBwVjtcbiAgICBjdHguTVtiXSA9IG1WO1xuICAgIHJldHVybiBoT3V0O1xufVxuLyoqXG4gKiBGaW5kIHRoZSBlbmRzIGFuZCBlcnJvciBjb3VudHMgZm9yIG1hdGNoZXMgb2YgYHBhdHRlcm5gIGluIGB0ZXh0YC5cbiAqXG4gKiBPbmx5IHRoZSBtYXRjaGVzIHdpdGggdGhlIGxvd2VzdCBlcnJvciBjb3VudCBhcmUgcmVwb3J0ZWQuIE90aGVyIG1hdGNoZXNcbiAqIHdpdGggZXJyb3IgY291bnRzIDw9IG1heEVycm9ycyBhcmUgZGlzY2FyZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGJsb2NrLWJhc2VkIHNlYXJjaCBhbGdvcml0aG0gZnJvbSBGaWcuIDkgb24gcC40MTAgb2YgWzFdLlxuICovXG5mdW5jdGlvbiBmaW5kTWF0Y2hFbmRzKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIENsYW1wIGVycm9yIGNvdW50IHNvIHdlIGNhbiByZWx5IG9uIHRoZSBgbWF4RXJyb3JzYCBhbmQgYHBhdHRlcm4ubGVuZ3RoYFxuICAgIC8vIHJvd3MgYmVpbmcgaW4gdGhlIHNhbWUgYmxvY2sgYmVsb3cuXG4gICAgbWF4RXJyb3JzID0gTWF0aC5taW4obWF4RXJyb3JzLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgICAvLyBXb3JkIHNpemUuXG4gICAgdmFyIHcgPSAzMjtcbiAgICAvLyBJbmRleCBvZiBtYXhpbXVtIGJsb2NrIGxldmVsLlxuICAgIHZhciBiTWF4ID0gTWF0aC5jZWlsKHBhdHRlcm4ubGVuZ3RoIC8gdykgLSAxO1xuICAgIC8vIENvbnRleHQgdXNlZCBhY3Jvc3MgYmxvY2sgY2FsY3VsYXRpb25zLlxuICAgIHZhciBjdHggPSB7XG4gICAgICAgIFA6IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIE06IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIGxhc3RSb3dNYXNrOiBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpXG4gICAgfTtcbiAgICBjdHgubGFzdFJvd01hc2suZmlsbCgxIDw8IDMxKTtcbiAgICBjdHgubGFzdFJvd01hc2tbYk1heF0gPSAxIDw8IChwYXR0ZXJuLmxlbmd0aCAtIDEpICUgdztcbiAgICAvLyBEdW1teSBcInBlcVwiIGFycmF5IGZvciBjaGFycyBpbiB0aGUgdGV4dCB3aGljaCBkbyBub3Qgb2NjdXIgaW4gdGhlIHBhdHRlcm4uXG4gICAgdmFyIGVtcHR5UGVxID0gbmV3IFVpbnQzMkFycmF5KGJNYXggKyAxKTtcbiAgICAvLyBNYXAgb2YgVVRGLTE2IGNoYXJhY3RlciBjb2RlIHRvIGJpdCB2ZWN0b3IgaW5kaWNhdGluZyBwb3NpdGlvbnMgaW4gdGhlXG4gICAgLy8gcGF0dGVybiB0aGF0IGVxdWFsIHRoYXQgY2hhcmFjdGVyLlxuICAgIHZhciBwZXEgPSBuZXcgTWFwKCk7XG4gICAgLy8gVmVyc2lvbiBvZiBgcGVxYCB0aGF0IG9ubHkgc3RvcmVzIG1hcHBpbmdzIGZvciBzbWFsbCBjaGFyYWN0ZXJzLiBUaGlzXG4gICAgLy8gYWxsb3dzIGZhc3RlciBsb29rdXBzIHdoZW4gaXRlcmF0aW5nIHRocm91Z2ggdGhlIHRleHQgYmVjYXVzZSBhIHNpbXBsZVxuICAgIC8vIGFycmF5IGxvb2t1cCBjYW4gYmUgZG9uZSBpbnN0ZWFkIG9mIGEgaGFzaCB0YWJsZSBsb29rdXAuXG4gICAgdmFyIGFzY2lpUGVxID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgICBhc2NpaVBlcS5wdXNoKGVtcHR5UGVxKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlIGBjdHgucGVxYCAtIGEgbWFwIG9mIGNoYXJhY3RlciB2YWx1ZXMgdG8gYml0bWFza3MgaW5kaWNhdGluZ1xuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGF0IGNoYXJhY3RlciB3aXRoaW4gdGhlIHBhdHRlcm4sIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHNcbiAgICAvLyBhIHBvc2l0aW9uIGluIHRoZSBwYXR0ZXJuLlxuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgcGF0dGVybi5sZW5ndGg7IGMgKz0gMSkge1xuICAgICAgICB2YXIgdmFsID0gcGF0dGVybi5jaGFyQ29kZUF0KGMpO1xuICAgICAgICBpZiAocGVxLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgY2hhciBpbiBwYXR0ZXJuLlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoYXJQZXEgPSBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpO1xuICAgICAgICBwZXEuc2V0KHZhbCwgY2hhclBlcSk7XG4gICAgICAgIGlmICh2YWwgPCBhc2NpaVBlcS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFzY2lpUGVxW3ZhbF0gPSBjaGFyUGVxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGIgPSAwOyBiIDw9IGJNYXg7IGIgKz0gMSkge1xuICAgICAgICAgICAgY2hhclBlcVtiXSA9IDA7XG4gICAgICAgICAgICAvLyBTZXQgYWxsIHRoZSBiaXRzIHdoZXJlIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGN1cnJlbnQgY2hhciAoY2gpLlxuICAgICAgICAgICAgLy8gRm9yIGluZGV4ZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIGFsd2F5cyBzZXQgdGhlIGJpdCBhcyBpZiB0aGVcbiAgICAgICAgICAgIC8vIHBhdHRlcm4gY29udGFpbmVkIGEgd2lsZGNhcmQgY2hhciBpbiB0aGF0IHBvc2l0aW9uLlxuICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCB3OyByICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gYiAqIHcgKyByO1xuICAgICAgICAgICAgICAgIGlmIChpZHggPj0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IHBhdHRlcm4uY2hhckNvZGVBdChpZHgpID09PSB2YWw7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJQZXFbYl0gfD0gMSA8PCByO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJbmRleCBvZiBsYXN0LWFjdGl2ZSBibG9jayBsZXZlbCBpbiB0aGUgY29sdW1uLlxuICAgIHZhciB5ID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKG1heEVycm9ycyAvIHcpIC0gMSk7XG4gICAgLy8gSW5pdGlhbGl6ZSBtYXhpbXVtIGVycm9yIGNvdW50IGF0IGJvdHRvbSBvZiBlYWNoIGJsb2NrLlxuICAgIHZhciBzY29yZSA9IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSk7XG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIHNjb3JlW2JdID0gKGIgKyAxKSAqIHc7XG4gICAgfVxuICAgIHNjb3JlW2JNYXhdID0gcGF0dGVybi5sZW5ndGg7XG4gICAgLy8gSW5pdGlhbGl6ZSB2ZXJ0aWNhbCBkZWx0YXMgZm9yIGVhY2ggYmxvY2suXG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIGN0eC5QW2JdID0gfjA7XG4gICAgICAgIGN0eC5NW2JdID0gMDtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBlYWNoIGNoYXIgb2YgdGhlIHRleHQsIGNvbXB1dGluZyB0aGUgZXJyb3IgY291bnQgZm9yIGB3YCBjaGFycyBvZlxuICAgIC8vIHRoZSBwYXR0ZXJuIGF0IGEgdGltZS5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRleHQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBiaXRtYXNrIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb25zIG9mIHRoZSBjdXJyZW50IGNoYXIgZnJvbVxuICAgICAgICAvLyB0aGUgdGV4dCB3aXRoaW4gdGhlIHBhdHRlcm4uXG4gICAgICAgIHZhciBjaGFyQ29kZSA9IHRleHQuY2hhckNvZGVBdChqKTtcbiAgICAgICAgdmFyIGNoYXJQZXEgPSB2b2lkIDA7XG4gICAgICAgIGlmIChjaGFyQ29kZSA8IGFzY2lpUGVxLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gRmFzdCBhcnJheSBsb29rdXAuXG4gICAgICAgICAgICBjaGFyUGVxID0gYXNjaWlQZXFbY2hhckNvZGVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU2xvd2VyIGhhc2ggdGFibGUgbG9va3VwLlxuICAgICAgICAgICAgY2hhclBlcSA9IHBlcS5nZXQoY2hhckNvZGUpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyUGVxID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgY2hhclBlcSA9IGVtcHR5UGVxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3VudCBmb3IgYmxvY2tzIHRoYXQgd2UgZGVmaW5pdGVseSBoYXZlIHRvIHByb2Nlc3MgZm9yXG4gICAgICAgIC8vIHRoaXMgY29sdW1uLlxuICAgICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBiID0gMDsgYiA8PSB5OyBiICs9IDEpIHtcbiAgICAgICAgICAgIGNhcnJ5ID0gYWR2YW5jZUJsb2NrKGN0eCwgY2hhclBlcSwgYiwgY2FycnkpO1xuICAgICAgICAgICAgc2NvcmVbYl0gKz0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgYWxzbyBuZWVkIHRvIGNvbXB1dGUgYW4gYWRkaXRpb25hbCBibG9jaywgb3IgaWYgd2UgY2FuIHJlZHVjZVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGJsb2NrcyBwcm9jZXNzZWQgZm9yIHRoZSBuZXh0IGNvbHVtbi5cbiAgICAgICAgaWYgKHNjb3JlW3ldIC0gY2FycnkgPD0gbWF4RXJyb3JzICYmXG4gICAgICAgICAgICB5IDwgYk1heCAmJlxuICAgICAgICAgICAgKGNoYXJQZXFbeSArIDFdICYgMSB8fCBjYXJyeSA8IDApKSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGlzIHVuZGVyIHRocmVzaG9sZCwgaW5jcmVhc2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhpcyBjb2x1bW4gJiBuZXh0IGJ5IDEuXG4gICAgICAgICAgICB5ICs9IDE7XG4gICAgICAgICAgICBjdHguUFt5XSA9IH4wO1xuICAgICAgICAgICAgY3R4Lk1beV0gPSAwO1xuICAgICAgICAgICAgdmFyIG1heEJsb2NrU2NvcmUgPSB5ID09PSBiTWF4ID8gcGF0dGVybi5sZW5ndGggJSB3IDogdztcbiAgICAgICAgICAgIHNjb3JlW3ldID1cbiAgICAgICAgICAgICAgICBzY29yZVt5IC0gMV0gK1xuICAgICAgICAgICAgICAgICAgICBtYXhCbG9ja1Njb3JlIC1cbiAgICAgICAgICAgICAgICAgICAgY2FycnkgK1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlQmxvY2soY3R4LCBjaGFyUGVxLCB5LCBjYXJyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGV4Y2VlZHMgdGhyZXNob2xkLCByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhlIG5leHQgY29sdW1uLlxuICAgICAgICAgICAgd2hpbGUgKHkgPiAwICYmIHNjb3JlW3ldID49IG1heEVycm9ycyArIHcpIHtcbiAgICAgICAgICAgICAgICB5IC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZXJyb3IgY291bnQgaXMgdW5kZXIgdGhyZXNob2xkLCByZXBvcnQgYSBtYXRjaC5cbiAgICAgICAgaWYgKHkgPT09IGJNYXggJiYgc2NvcmVbeV0gPD0gbWF4RXJyb3JzKSB7XG4gICAgICAgICAgICBpZiAoc2NvcmVbeV0gPCBtYXhFcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIGFueSBlYXJsaWVyLCB3b3JzZSBtYXRjaGVzLlxuICAgICAgICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKDAsIG1hdGNoZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICAgICAgICAgIGVuZDogaiArIDEsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBzY29yZVt5XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBCZWNhdXNlIGBzZWFyY2hgIG9ubHkgcmVwb3J0cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBsb3dlc3QgZXJyb3IgY291bnQsXG4gICAgICAgICAgICAvLyB3ZSBjYW4gXCJyYXRjaGV0IGRvd25cIiB0aGUgbWF4IGVycm9yIHRocmVzaG9sZCB3aGVuZXZlciBhIG1hdGNoIGlzXG4gICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbmQgdGhlcmVieSBzYXZlIGEgc21hbGwgYW1vdW50IG9mIHdvcmsgZm9yIHRoZSByZW1haW5kZXJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB0ZXh0LlxuICAgICAgICAgICAgbWF4RXJyb3JzID0gc2NvcmVbeV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59XG4vKipcbiAqIFNlYXJjaCBmb3IgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogUmV0dXJucyB0aGUgc3RhcnQsIGFuZCBlbmQgcG9zaXRpb25zIGFuZCBlcnJvciBjb3VudHMgZm9yIGVhY2ggbG93ZXN0LWNvc3RcbiAqIG1hdGNoLiBPbmx5IHRoZSBcImJlc3RcIiBtYXRjaGVzIGFyZSByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoRW5kcyh0ZXh0LCBwYXR0ZXJuLCBtYXhFcnJvcnMpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hTdGFydHModGV4dCwgcGF0dGVybiwgbWF0Y2hlcyk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzZWFyY2g7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3089\n')},6960:function(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__){"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/approx-string-match/dist/index.js\nvar dist = __webpack_require__(3089);\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/match-quote.js\n\n/**\n * @typedef {import(\'approx-string-match\').Match} StringMatch\n */\n\n/**\n * @typedef Match\n * @prop {number} start - Start offset of match in text\n * @prop {number} end - End offset of match in text\n * @prop {number} score -\n * Score for the match between 0 and 1.0, where 1.0 indicates a perfect match\n * for the quote and context.\n */\n\n/**\n * Find the best approximate matches for `str` in `text` allowing up to `maxErrors` errors.\n *\n * @param {string} text\n * @param {string} str\n * @param {number} maxErrors\n * @return {StringMatch[]}\n */\n\nfunction search(text, str, maxErrors) {\n // Do a fast search for exact matches. The `approx-string-match` library\n // doesn\'t currently incorporate this optimization itself.\n var matchPos = 0;\n var exactMatches = [];\n\n while (matchPos !== -1) {\n matchPos = text.indexOf(str, matchPos);\n\n if (matchPos !== -1) {\n exactMatches.push({\n start: matchPos,\n end: matchPos + str.length,\n errors: 0\n });\n matchPos += 1;\n }\n }\n\n if (exactMatches.length > 0) {\n return exactMatches;\n } // If there are no exact matches, do a more expensive search for matches\n // with errors.\n\n\n return (0,dist/* default */.Z)(text, str, maxErrors);\n}\n/**\n * Compute a score between 0 and 1.0 for the similarity between `text` and `str`.\n *\n * @param {string} text\n * @param {string} str\n */\n\n\nfunction textMatchScore(text, str) {\n /* istanbul ignore next - `scoreMatch` will never pass an empty string */\n if (str.length === 0 || text.length === 0) {\n return 0.0;\n }\n\n var matches = search(text, str, str.length); // prettier-ignore\n\n return 1 - matches[0].errors / str.length;\n}\n/**\n * Find the best approximate match for `quote` in `text`.\n *\n * Returns `null` if no match exceeding the minimum quality threshold was found.\n *\n * @param {string} text - Document text to search\n * @param {string} quote - String to find within `text`\n * @param {Object} context -\n * Context in which the quote originally appeared. This is used to choose the\n * best match.\n * @param {string} [context.prefix] - Expected text before the quote\n * @param {string} [context.suffix] - Expected text after the quote\n * @param {number} [context.hint] - Expected offset of match within text\n * @return {Match|null}\n */\n\n\nfunction matchQuote(text, quote) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (quote.length === 0) {\n return null;\n } // Choose the maximum number of errors to allow for the initial search.\n // This choice involves a tradeoff between:\n //\n // - Recall (proportion of "good" matches found)\n // - Precision (proportion of matches found which are "good")\n // - Cost of the initial search and of processing the candidate matches [1]\n //\n // [1] Specifically, the expected-time complexity of the initial search is\n // `O((maxErrors / 32) * text.length)`. See `approx-string-match` docs.\n\n\n var maxErrors = Math.min(256, quote.length / 2); // Find closest matches for `quote` in `text` based on edit distance.\n\n var matches = search(text, quote, maxErrors);\n\n if (matches.length === 0) {\n return null;\n }\n /**\n * Compute a score between 0 and 1.0 for a match candidate.\n *\n * @param {StringMatch} match\n */\n\n\n var scoreMatch = function scoreMatch(match) {\n var quoteWeight = 50; // Similarity of matched text to quote.\n\n var prefixWeight = 20; // Similarity of text before matched text to `context.prefix`.\n\n var suffixWeight = 20; // Similarity of text after matched text to `context.suffix`.\n\n var posWeight = 2; // Proximity to expected location. Used as a tie-breaker.\n\n var quoteScore = 1 - match.errors / quote.length;\n var prefixScore = context.prefix ? textMatchScore(text.slice(Math.max(0, match.start - context.prefix.length), match.start), context.prefix) : 1.0;\n var suffixScore = context.suffix ? textMatchScore(text.slice(match.end, match.end + context.suffix.length), context.suffix) : 1.0;\n var posScore = 1.0;\n\n if (typeof context.hint === \'number\') {\n var offset = Math.abs(match.start - context.hint);\n posScore = 1.0 - offset / text.length;\n }\n\n var rawScore = quoteWeight * quoteScore + prefixWeight * prefixScore + suffixWeight * suffixScore + posWeight * posScore;\n var maxScore = quoteWeight + prefixWeight + suffixWeight + posWeight;\n var normalizedScore = rawScore / maxScore;\n return normalizedScore;\n }; // Rank matches based on similarity of actual and expected surrounding text\n // and actual/expected offset in the document text.\n\n\n var scoredMatches = matches.map(function (m) {\n return {\n start: m.start,\n end: m.end,\n score: scoreMatch(m)\n };\n }); // Choose match with highest score.\n\n scoredMatches.sort(function (a, b) {\n return b.score - a.score;\n });\n return scoredMatches[0];\n}\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/text-range.js\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Return the combined length of text nodes contained in `node`.\n *\n * @param {Node} node\n */\nfunction nodeTextLength(node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.TEXT_NODE:\n // nb. `textContent` excludes text in comments and processing instructions\n // when called on a parent element, so we don\'t need to subtract that here.\n return (\n /** @type {string} */\n node.textContent.length\n );\n\n default:\n return 0;\n }\n}\n/**\n * Return the total length of the text of all previous siblings of `node`.\n *\n * @param {Node} node\n */\n\n\nfunction previousSiblingsTextLength(node) {\n var sibling = node.previousSibling;\n var length = 0;\n\n while (sibling) {\n length += nodeTextLength(sibling);\n sibling = sibling.previousSibling;\n }\n\n return length;\n}\n/**\n * Resolve one or more character offsets within an element to (text node, position)\n * pairs.\n *\n * @param {Element} element\n * @param {number[]} offsets - Offsets, which must be sorted in ascending order\n * @return {{ node: Text, offset: number }[]}\n */\n\n\nfunction resolveOffsets(element) {\n for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n offsets[_key - 1] = arguments[_key];\n }\n\n var nextOffset = offsets.shift();\n var nodeIter =\n /** @type {Document} */\n element.ownerDocument.createNodeIterator(element, NodeFilter.SHOW_TEXT);\n var results = [];\n var currentNode = nodeIter.nextNode();\n var textNode;\n var length = 0; // Find the text node containing the `nextOffset`th character from the start\n // of `element`.\n\n while (nextOffset !== undefined && currentNode) {\n textNode =\n /** @type {Text} */\n currentNode;\n\n if (length + textNode.data.length > nextOffset) {\n results.push({\n node: textNode,\n offset: nextOffset - length\n });\n nextOffset = offsets.shift();\n } else {\n currentNode = nodeIter.nextNode();\n length += textNode.data.length;\n }\n } // Boundary case.\n\n\n while (nextOffset !== undefined && textNode && length === nextOffset) {\n results.push({\n node: textNode,\n offset: textNode.data.length\n });\n nextOffset = offsets.shift();\n }\n\n if (nextOffset !== undefined) {\n throw new RangeError(\'Offset exceeds text length\');\n }\n\n return results;\n}\n\nvar RESOLVE_FORWARDS = 1;\nvar RESOLVE_BACKWARDS = 2;\n/**\n * Represents an offset within the text content of an element.\n *\n * This position can be resolved to a specific descendant node in the current\n * DOM subtree of the element using the `resolve` method.\n */\n\nvar text_range_TextPosition = /*#__PURE__*/function () {\n /**\n * Construct a `TextPosition` that refers to the text position `offset` within\n * the text content of `element`.\n *\n * @param {Element} element\n * @param {number} offset\n */\n function TextPosition(element, offset) {\n _classCallCheck(this, TextPosition);\n\n if (offset < 0) {\n throw new Error(\'Offset is invalid\');\n }\n /** Element that `offset` is relative to. */\n\n\n this.element = element;\n /** Character offset from the start of the element\'s `textContent`. */\n\n this.offset = offset;\n }\n /**\n * Return a copy of this position with offset relative to a given ancestor\n * element.\n *\n * @param {Element} parent - Ancestor of `this.element`\n * @return {TextPosition}\n */\n\n\n _createClass(TextPosition, [{\n key: "relativeTo",\n value: function relativeTo(parent) {\n if (!parent.contains(this.element)) {\n throw new Error(\'Parent is not an ancestor of current element\');\n }\n\n var el = this.element;\n var offset = this.offset;\n\n while (el !== parent) {\n offset += previousSiblingsTextLength(el);\n el =\n /** @type {Element} */\n el.parentElement;\n }\n\n return new TextPosition(el, offset);\n }\n /**\n * Resolve the position to a specific text node and offset within that node.\n *\n * Throws if `this.offset` exceeds the length of the element\'s text. In the\n * case where the element has no text and `this.offset` is 0, the `direction`\n * option determines what happens.\n *\n * Offsets at the boundary between two nodes are resolved to the start of the\n * node that begins at the boundary.\n *\n * @param {Object} [options]\n * @param {RESOLVE_FORWARDS|RESOLVE_BACKWARDS} [options.direction] -\n * Specifies in which direction to search for the nearest text node if\n * `this.offset` is `0` and `this.element` has no text. If not specified\n * an error is thrown.\n * @return {{ node: Text, offset: number }}\n * @throws {RangeError}\n */\n\n }, {\n key: "resolve",\n value: function resolve() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n try {\n return resolveOffsets(this.element, this.offset)[0];\n } catch (err) {\n if (this.offset === 0 && options.direction !== undefined) {\n var tw = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);\n tw.currentNode = this.element;\n var forwards = options.direction === RESOLVE_FORWARDS;\n var text =\n /** @type {Text|null} */\n forwards ? tw.nextNode() : tw.previousNode();\n\n if (!text) {\n throw err;\n }\n\n return {\n node: text,\n offset: forwards ? 0 : text.data.length\n };\n } else {\n throw err;\n }\n }\n }\n /**\n * Construct a `TextPosition` that refers to the `offset`th character within\n * `node`.\n *\n * @param {Node} node\n * @param {number} offset\n * @return {TextPosition}\n */\n\n }], [{\n key: "fromCharOffset",\n value: function fromCharOffset(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n return TextPosition.fromPoint(node, offset);\n\n case Node.ELEMENT_NODE:\n return new TextPosition(\n /** @type {Element} */\n node, offset);\n\n default:\n throw new Error(\'Node is not an element or text node\');\n }\n }\n /**\n * Construct a `TextPosition` representing the range start or end point (node, offset).\n *\n * @param {Node} node - Text or Element node\n * @param {number} offset - Offset within the node.\n * @return {TextPosition}\n */\n\n }, {\n key: "fromPoint",\n value: function fromPoint(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n {\n if (offset < 0 || offset >\n /** @type {Text} */\n node.data.length) {\n throw new Error(\'Text node offset is out of range\');\n }\n\n if (!node.parentElement) {\n throw new Error(\'Text node has no parent\');\n } // Get the offset from the start of the parent element.\n\n\n var textOffset = previousSiblingsTextLength(node) + offset;\n return new TextPosition(node.parentElement, textOffset);\n }\n\n case Node.ELEMENT_NODE:\n {\n if (offset < 0 || offset > node.childNodes.length) {\n throw new Error(\'Child node offset is out of range\');\n } // Get the text length before the `offset`th child of element.\n\n\n var _textOffset = 0;\n\n for (var i = 0; i < offset; i++) {\n _textOffset += nodeTextLength(node.childNodes[i]);\n }\n\n return new TextPosition(\n /** @type {Element} */\n node, _textOffset);\n }\n\n default:\n throw new Error(\'Point is not in an element or text node\');\n }\n }\n }]);\n\n return TextPosition;\n}();\n/**\n * Represents a region of a document as a (start, end) pair of `TextPosition` points.\n *\n * Representing a range in this way allows for changes in the DOM content of the\n * range which don\'t affect its text content, without affecting the text content\n * of the range itself.\n */\n\nvar text_range_TextRange = /*#__PURE__*/function () {\n /**\n * Construct an immutable `TextRange` from a `start` and `end` point.\n *\n * @param {TextPosition} start\n * @param {TextPosition} end\n */\n function TextRange(start, end) {\n _classCallCheck(this, TextRange);\n\n this.start = start;\n this.end = end;\n }\n /**\n * Return a copy of this range with start and end positions relative to a\n * given ancestor. See `TextPosition.relativeTo`.\n *\n * @param {Element} element\n */\n\n\n _createClass(TextRange, [{\n key: "relativeTo",\n value: function relativeTo(element) {\n return new TextRange(this.start.relativeTo(element), this.end.relativeTo(element));\n }\n /**\n * Resolve the `TextRange` to a DOM range.\n *\n * The resulting DOM Range will always start and end in a `Text` node.\n * Hence `TextRange.fromRange(range).toRange()` can be used to "shrink" a\n * range to the text it contains.\n *\n * May throw if the `start` or `end` positions cannot be resolved to a range.\n *\n * @return {Range}\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var start;\n var end;\n\n if (this.start.element === this.end.element && this.start.offset <= this.end.offset) {\n // Fast path for start and end points in same element.\n var _resolveOffsets = resolveOffsets(this.start.element, this.start.offset, this.end.offset);\n\n var _resolveOffsets2 = _slicedToArray(_resolveOffsets, 2);\n\n start = _resolveOffsets2[0];\n end = _resolveOffsets2[1];\n } else {\n start = this.start.resolve({\n direction: RESOLVE_FORWARDS\n });\n end = this.end.resolve({\n direction: RESOLVE_BACKWARDS\n });\n }\n\n var range = new Range();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range;\n }\n /**\n * Convert an existing DOM `Range` to a `TextRange`\n *\n * @param {Range} range\n * @return {TextRange}\n */\n\n }], [{\n key: "fromRange",\n value: function fromRange(range) {\n var start = text_range_TextPosition.fromPoint(range.startContainer, range.startOffset);\n var end = text_range_TextPosition.fromPoint(range.endContainer, range.endOffset);\n return new TextRange(start, end);\n }\n /**\n * Return a `TextRange` from the `start`th to `end`th characters in `root`.\n *\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n\n }, {\n key: "fromOffsets",\n value: function fromOffsets(root, start, end) {\n return new TextRange(new text_range_TextPosition(root, start), new text_range_TextPosition(root, end));\n }\n }]);\n\n return TextRange;\n}();\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/types.js\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction types_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction types_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction types_createClass(Constructor, protoProps, staticProps) { if (protoProps) types_defineProperties(Constructor.prototype, protoProps); if (staticProps) types_defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This module exports a set of classes for converting between DOM `Range`\n * objects and different types of selectors. It is mostly a thin wrapper around a\n * set of anchoring libraries. It serves two main purposes:\n *\n * 1. Providing a consistent interface across different types of anchors.\n * 2. Insulating the rest of the code from API changes in the underlying anchoring\n * libraries.\n */\n\n\n\n/**\n * @typedef {import(\'../../types/api\').RangeSelector} RangeSelector\n * @typedef {import(\'../../types/api\').TextPositionSelector} TextPositionSelector\n * @typedef {import(\'../../types/api\').TextQuoteSelector} TextQuoteSelector\n */\n\n/**\n * Converts between `RangeSelector` selectors and `Range` objects.\n */\n\nvar RangeAnchor = /*#__PURE__*/(/* unused pure expression or super */ null && (function () {\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n function RangeAnchor(root, range) {\n types_classCallCheck(this, RangeAnchor);\n\n this.root = root;\n this.range = range;\n }\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n\n\n types_createClass(RangeAnchor, [{\n key: "toRange",\n value: function toRange() {\n return this.range;\n }\n /**\n * @return {RangeSelector}\n */\n\n }, {\n key: "toSelector",\n value: function toSelector() {\n // "Shrink" the range so that it tightly wraps its text. This ensures more\n // predictable output for a given text selection.\n var normalizedRange = TextRange.fromRange(this.range).toRange();\n var textRange = TextRange.fromRange(normalizedRange);\n var startContainer = xpathFromNode(textRange.start.element, this.root);\n var endContainer = xpathFromNode(textRange.end.element, this.root);\n return {\n type: \'RangeSelector\',\n startContainer: startContainer,\n startOffset: textRange.start.offset,\n endContainer: endContainer,\n endOffset: textRange.end.offset\n };\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n return new RangeAnchor(root, range);\n }\n /**\n * Create an anchor from a serialized `RangeSelector` selector.\n *\n * @param {Element} root - A root element from which to anchor.\n * @param {RangeSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var startContainer = nodeFromXPath(selector.startContainer, root);\n\n if (!startContainer) {\n throw new Error(\'Failed to resolve startContainer XPath\');\n }\n\n var endContainer = nodeFromXPath(selector.endContainer, root);\n\n if (!endContainer) {\n throw new Error(\'Failed to resolve endContainer XPath\');\n }\n\n var startPos = TextPosition.fromCharOffset(startContainer, selector.startOffset);\n var endPos = TextPosition.fromCharOffset(endContainer, selector.endOffset);\n var range = new TextRange(startPos, endPos).toRange();\n return new RangeAnchor(root, range);\n }\n }]);\n\n return RangeAnchor;\n}()));\n/**\n * Converts between `TextPositionSelector` selectors and `Range` objects.\n */\n\nvar TextPositionAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n function TextPositionAnchor(root, start, end) {\n types_classCallCheck(this, TextPositionAnchor);\n\n this.root = root;\n this.start = start;\n this.end = end;\n }\n /**\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextPositionAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextPositionSelector}\n */\n function toSelector() {\n return {\n type: \'TextPositionSelector\',\n start: this.start,\n end: this.end\n };\n }\n }, {\n key: "toRange",\n value: function toRange() {\n return text_range_TextRange.fromOffsets(this.root, this.start, this.end).toRange();\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n return new TextPositionAnchor(root, textRange.start.offset, textRange.end.offset);\n }\n /**\n * @param {Element} root\n * @param {TextPositionSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n return new TextPositionAnchor(root, selector.start, selector.end);\n }\n }]);\n\n return TextPositionAnchor;\n}();\n/**\n * @typedef QuoteMatchOptions\n * @prop {number} [hint] - Expected position of match in text. See `matchQuote`.\n */\n\n/**\n * Converts between `TextQuoteSelector` selectors and `Range` objects.\n */\n\nvar TextQuoteAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root - A root element from which to anchor.\n * @param {string} exact\n * @param {Object} context\n * @param {string} [context.prefix]\n * @param {string} [context.suffix]\n */\n function TextQuoteAnchor(root, exact) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n types_classCallCheck(this, TextQuoteAnchor);\n\n this.root = root;\n this.exact = exact;\n this.context = context;\n }\n /**\n * Create a `TextQuoteAnchor` from a range.\n *\n * Will throw if `range` does not contain any text nodes.\n *\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextQuoteAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextQuoteSelector}\n */\n function toSelector() {\n return {\n type: \'TextQuoteSelector\',\n exact: this.exact,\n prefix: this.context.prefix,\n suffix: this.context.suffix\n };\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return this.toPositionAnchor(options).toRange();\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toPositionAnchor",\n value: function toPositionAnchor() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var text =\n /** @type {string} */\n this.root.textContent;\n var match = matchQuote(text, this.exact, _objectSpread(_objectSpread({}, this.context), {}, {\n hint: options.hint\n }));\n\n if (!match) {\n throw new Error(\'Quote not found\');\n }\n\n return new TextPositionAnchor(this.root, match.start, match.end);\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var text =\n /** @type {string} */\n root.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n var start = textRange.start.offset;\n var end = textRange.end.offset; // Number of characters around the quote to capture as context. We currently\n // always use a fixed amount, but it would be better if this code was aware\n // of logical boundaries in the document (paragraph, article etc.) to avoid\n // capturing text unrelated to the quote.\n //\n // In regular prose the ideal content would often be the surrounding sentence.\n // This is a natural unit of meaning which enables displaying quotes in\n // context even when the document is not available. We could use `Intl.Segmenter`\n // for this when available.\n\n var contextLen = 32;\n return new TextQuoteAnchor(root, text.slice(start, end), {\n prefix: text.slice(Math.max(0, start - contextLen), start),\n suffix: text.slice(end, Math.min(text.length, end + contextLen))\n });\n }\n /**\n * @param {Element} root\n * @param {TextQuoteSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var prefix = selector.prefix,\n suffix = selector.suffix;\n return new TextQuoteAnchor(root, selector.exact, {\n prefix: prefix,\n suffix: suffix\n });\n }\n }]);\n\n return TextQuoteAnchor;\n}();\n;// CONCATENATED MODULE: ./src/utils.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = utils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction utils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return utils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return utils_arrayLikeToArray(o, minLen); }\n\nfunction utils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n // Catch JS errors to log them in the app.\n\nwindow.addEventListener("error", function (event) {\n Android.logError(event.message, event.filename, event.lineno);\n}, false);\nwindow.addEventListener("load", function () {\n var observer = new ResizeObserver(function () {\n onViewportWidthChanged();\n snapCurrentOffset();\n });\n observer.observe(document.body);\n}, false);\n/**\n * Having an odd number of columns when displaying two columns per screen causes snapping and page\n * turning issues. To fix this, we insert a blank virtual column at the end of the resource.\n */\n\nfunction appendVirtualColumnIfNeeded() {\n var id = "readium-virtual-page";\n var virtualCol = document.getElementById(id);\n\n if (isScrollModeEnabled() || getColumnCountPerScreen() != 2) {\n if (virtualCol) {\n virtualCol.remove();\n }\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var colCount = documentWidth / pageWidth;\n var hasOddColCount = Math.round(colCount * 2) / 2 % 1 > 0.1;\n\n if (hasOddColCount) {\n if (virtualCol) {\n virtualCol.remove();\n } else {\n virtualCol = document.createElement("div");\n virtualCol.setAttribute("id", id);\n virtualCol.style.breakBefore = "column";\n virtualCol.innerHTML = "​"; // zero-width space\n\n document.body.appendChild(virtualCol);\n }\n }\n }\n}\n\nvar pageWidth = 1;\n\nfunction onViewportWidthChanged() {\n // We can\'t rely on window.innerWidth for the pageWidth on Android, because if the\n // device pixel ratio is not an integer, we get rounding issues offsetting the pages.\n //\n // See https://github.com/readium/readium-css/issues/97\n // and https://github.com/readium/r2-navigator-kotlin/issues/146\n var width = Android.getViewportWidth();\n pageWidth = width / window.devicePixelRatio;\n setProperty("--RS__viewportWidth", "calc(" + width + "px / " + window.devicePixelRatio + ")");\n appendVirtualColumnIfNeeded();\n}\n\nfunction getColumnCountPerScreen() {\n return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n}\nfunction isScrollModeEnabled() {\n var style = document.documentElement.style;\n return style.getPropertyValue("--USER__view").trim() == "readium-scroll-on" || // FIXME: Will need to be removed in Readium 3.0, --USER__scroll was incorrect.\n style.getPropertyValue("--USER__scroll").trim() == "readium-scroll-on";\n}\nfunction isRTL() {\n return document.body.dir.toLowerCase() == "rtl";\n} // Scroll to the given TagId in document and snap.\n\nfunction scrollToId(id) {\n var element = document.getElementById(id);\n\n if (!element) {\n return false;\n }\n\n return scrollToRect(element.getBoundingClientRect());\n} // Position must be in the range [0 - 1], 0-100%.\n\nfunction scrollToPosition(position) {\n // Android.log("scrollToPosition " + position);\n if (position < 0 || position > 1) {\n throw "scrollToPosition() must be given a position from 0.0 to 1.0";\n }\n\n var offset;\n\n if (isScrollModeEnabled()) {\n offset = document.scrollingElement.scrollHeight * position;\n document.scrollingElement.scrollTop = offset; // window.scrollTo(0, offset);\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var factor = isRTL() ? -1 : 1;\n offset = documentWidth * position * factor;\n document.scrollingElement.scrollLeft = snapOffset(offset);\n }\n} // Scrolls to the first occurrence of the given text snippet.\n//\n// The expected text argument is a Locator Text object, as defined here:\n// https://readium.org/architecture/models/locators/\n\nfunction scrollToText(text) {\n var range = rangeFromLocator({\n text: text\n });\n\n if (!range) {\n return false;\n }\n\n scrollToRange(range);\n return true;\n}\n\nfunction scrollToRange(range) {\n return scrollToRect(range.getBoundingClientRect());\n}\n\nfunction scrollToRect(rect) {\n if (isScrollModeEnabled()) {\n document.scrollingElement.scrollTop = rect.top + window.scrollY - window.innerHeight / 2;\n } else {\n document.scrollingElement.scrollLeft = snapOffset(rect.left + window.scrollX);\n }\n\n return true;\n}\n\nfunction scrollToStart() {\n // Android.log("scrollToStart");\n if (!isScrollModeEnabled()) {\n document.scrollingElement.scrollLeft = 0;\n } else {\n document.scrollingElement.scrollTop = 0;\n window.scrollTo(0, 0);\n }\n}\nfunction scrollToEnd() {\n // Android.log("scrollToEnd");\n if (!isScrollModeEnabled()) {\n var factor = isRTL() ? -1 : 1;\n document.scrollingElement.scrollLeft = snapOffset(document.scrollingElement.scrollWidth * factor);\n } else {\n document.scrollingElement.scrollTop = document.body.scrollHeight;\n window.scrollTo(0, document.body.scrollHeight);\n }\n} // Returns false if the page is already at the left-most scroll offset.\n\nfunction scrollLeft() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX - pageWidth;\n var minOffset = isRTL() ? -(documentWidth - pageWidth) : 0;\n return scrollToOffset(Math.max(offset, minOffset));\n} // Returns false if the page is already at the right-most scroll offset.\n\nfunction scrollRight() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX + pageWidth;\n var maxOffset = isRTL() ? 0 : documentWidth - pageWidth;\n return scrollToOffset(Math.min(offset, maxOffset));\n} // Scrolls to the given left offset.\n// Returns false if the page scroll position is already close enough to the given offset.\n\nfunction scrollToOffset(offset) {\n // Android.log("scrollToOffset " + offset);\n if (isScrollModeEnabled()) {\n throw "Called scrollToOffset() with scroll mode enabled. This can only be used in paginated mode.";\n }\n\n var currentOffset = window.scrollX;\n document.scrollingElement.scrollLeft = snapOffset(offset); // In some case the scrollX cannot reach the position respecting to innerWidth\n\n var diff = Math.abs(currentOffset - offset) / pageWidth;\n return diff > 0.01;\n} // Snap the offset to the screen width (page width).\n\n\nfunction snapOffset(offset) {\n var value = offset + (isRTL() ? -1 : 1);\n return value - value % pageWidth;\n} // Snaps the current offset to the page width.\n\n\nfunction snapCurrentOffset() {\n // Android.log("snapCurrentOffset");\n if (isScrollModeEnabled()) {\n return;\n }\n\n var currentOffset = window.scrollX; // Adds half a page to make sure we don\'t snap to the previous page.\n\n var factor = isRTL() ? -1 : 1;\n var delta = factor * (pageWidth / 2);\n document.scrollingElement.scrollLeft = snapOffset(currentOffset + delta);\n}\nfunction rangeFromLocator(locator) {\n try {\n var locations = locator.locations;\n var text = locator.text;\n\n if (text && text.highlight) {\n var root;\n\n if (locations && locations.cssSelector) {\n root = document.querySelector(locations.cssSelector);\n }\n\n if (!root) {\n root = document.body;\n }\n\n var anchor = new TextQuoteAnchor(root, text.highlight, {\n prefix: text.before,\n suffix: text.after\n });\n return anchor.toRange();\n }\n\n if (locations) {\n var element = null;\n\n if (!element && locations.cssSelector) {\n element = document.querySelector(locations.cssSelector);\n }\n\n if (!element && locations.fragments) {\n var _iterator = _createForOfIteratorHelper(locations.fragments),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var htmlId = _step.value;\n element = document.getElementById(htmlId);\n\n if (element) {\n break;\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n if (element) {\n var range = document.createRange();\n range.setStartBefore(element);\n range.setEndAfter(element);\n return range;\n }\n }\n } catch (e) {\n logError(e);\n }\n\n return null;\n} /// User Settings.\n\nfunction setCSSProperties(properties) {\n for (var name in properties) {\n setProperty(name, properties[name]);\n }\n} // For setting user setting.\n\nfunction setProperty(key, value) {\n if (value === null || value === "") {\n removeProperty(key);\n } else {\n var root = document.documentElement; // The `!important` annotation is added with `setProperty()` because if it\'s part of the\n // `value`, it will be ignored by the Web View.\n\n root.style.setProperty(key, value, "important");\n }\n} // For removing user setting.\n\nfunction removeProperty(key) {\n var root = document.documentElement;\n root.style.removeProperty(key);\n} /// Toolkit\n\nfunction log() {\n var message = Array.prototype.slice.call(arguments).join(" ");\n Android.log(message);\n}\nfunction logError(message) {\n Android.logError(message, "", 0);\n}\n;// CONCATENATED MODULE: ./src/rect.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction rect_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = rect_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction rect_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return rect_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return rect_arrayLikeToArray(o, minLen); }\n\nfunction rect_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nvar debug = false;\n/**\n * Converts a DOMRect into a JSON object understandable by the native side.\n */\n\nfunction toNativeRect(rect) {\n var pixelRatio = window.devicePixelRatio;\n var width = rect.width * pixelRatio;\n var height = rect.height * pixelRatio;\n var left = rect.left * pixelRatio;\n var top = rect.top * pixelRatio;\n var right = left + width;\n var bottom = top + height;\n return {\n width: width,\n height: height,\n left: left,\n top: top,\n right: right,\n bottom: bottom\n };\n}\nfunction getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var clientRects = range.getClientRects();\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator = rect_createForOfIteratorHelper(clientRects),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var rangeClientRect = _step.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n var mergedRects = mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = removeContainedRects(mergedRects, tolerance);\n var newRects = replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n rect_log("CLIENT RECT: remove small");\n newRects.splice(j, 1);\n } else {\n rect_log("CLIENT RECT: remove small, but keep otherwise empty!");\n break;\n }\n }\n }\n\n rect_log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n return newRects;\n}\n\nfunction mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("mergeTouchingRects rect1 === rect2 ??!");\n return "continue";\n }\n\n var rectsLineUpVertically = almostEqual(rect1.top, rect2.top, tolerance) && almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = almostEqual(rect1.left, rect2.left, tolerance) && almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n rect_log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret = _loop(j);\n\n if (_ret === "continue") continue;\n if (_typeof(_ret) === "object") return _ret.v;\n }\n }\n\n return rects;\n}\n\nfunction getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator2 = rect_createForOfIteratorHelper(rects),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var rect = _step2.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n rect_log("CLIENT RECT: remove tiny");\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator3 = rect_createForOfIteratorHelper(rects),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var possiblyContainingRect = _step3.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (rectContains(possiblyContainingRect, rect, tolerance)) {\n rect_log("CLIENT RECT: remove contained");\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction rectContains(rect1, rect2, tolerance) {\n return rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || almostEqual(rect.left, x, tolerance)) && (rect.right > x || almostEqual(rect.right, x, tolerance)) && (rect.top < y || almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("replaceOverlapingRects rect1 === rect2 ??!");\n continue;\n }\n\n if (rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret2 = function () {\n var toAdd = [];\n var toRemove = void 0;\n var subtractRects1 = rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n var subtractRects2 = rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n }\n }\n\n rect_log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: replaceOverlapingRects(newRects)\n };\n }();\n\n if (_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction rectSubtract(rect1, rect2) {\n var rectIntersected = rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n return {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n}\n\nfunction rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction rect_log() {\n if (debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/decorator.js\nfunction decorator_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = decorator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction decorator_slicedToArray(arr, i) { return decorator_arrayWithHoles(arr) || decorator_iterableToArrayLimit(arr, i) || decorator_unsupportedIterableToArray(arr, i) || decorator_nonIterableRest(); }\n\nfunction decorator_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction decorator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return decorator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return decorator_arrayLikeToArray(o, minLen); }\n\nfunction decorator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction decorator_iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction decorator_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nvar styles = new Map();\nvar groups = new Map();\nvar lastGroupId = 0;\n/**\n * Registers a list of additional supported Decoration Templates.\n *\n * Each template object is indexed by the style ID.\n */\n\nfunction registerTemplates(newStyles) {\n var stylesheet = "";\n\n for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = decorator_slicedToArray(_Object$entries[_i], 2),\n id = _Object$entries$_i[0],\n style = _Object$entries$_i[1];\n\n styles.set(id, style);\n\n if (style.stylesheet) {\n stylesheet += style.stylesheet + "\\n";\n }\n }\n\n if (stylesheet) {\n var styleElement = document.createElement("style");\n styleElement.innerHTML = stylesheet;\n document.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n}\n/**\n * Returns an instance of DecorationGroup for the given group name.\n */\n\nfunction getDecorations(groupName) {\n var group = groups.get(groupName);\n\n if (!group) {\n var id = "r2-decoration-" + lastGroupId++;\n group = DecorationGroup(id, groupName);\n groups.set(groupName, group);\n }\n\n return group;\n}\n/**\n * Handles click events on a Decoration.\n * Returns whether a decoration matched this event.\n */\n\nfunction handleDecorationClickEvent(event, clickEvent) {\n if (groups.size === 0) {\n return false;\n }\n\n function findTarget() {\n var _iterator = decorator_createForOfIteratorHelper(groups),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = decorator_slicedToArray(_step.value, 2),\n group = _step$value[0],\n groupContent = _step$value[1];\n\n var _iterator2 = decorator_createForOfIteratorHelper(groupContent.items.reverse()),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var item = _step2.value;\n\n if (!item.clickableElements) {\n continue;\n }\n\n var _iterator3 = decorator_createForOfIteratorHelper(item.clickableElements),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var element = _step3.value;\n var rect = element.getBoundingClientRect().toJSON();\n\n if (rectContainsPoint(rect, event.clientX, event.clientY, 1)) {\n return {\n group: group,\n item: item,\n element: element,\n rect: rect\n };\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var target = findTarget();\n\n if (!target) {\n return false;\n }\n\n return Android.onDecorationActivated(JSON.stringify({\n id: target.item.decoration.id,\n group: target.group,\n rect: toNativeRect(target.item.range.getBoundingClientRect()),\n click: clickEvent\n }));\n}\n/**\n * Creates a DecorationGroup object from a unique HTML ID and its name.\n */\n\nfunction DecorationGroup(groupId, groupName) {\n var items = [];\n var lastItemId = 0;\n var container = null;\n /**\n * Adds a new decoration to the group.\n */\n\n function add(decoration) {\n var id = groupId + "-" + lastItemId++;\n var range = rangeFromLocator(decoration.locator);\n\n if (!range) {\n log("Can\'t locate DOM range for decoration", decoration);\n return;\n }\n\n var item = {\n id: id,\n decoration: decoration,\n range: range\n };\n items.push(item);\n layout(item);\n }\n /**\n * Removes the decoration with given ID from the group.\n */\n\n\n function remove(decorationId) {\n var index = items.findIndex(function (i) {\n return i.decoration.id === decorationId;\n });\n\n if (index === -1) {\n return;\n }\n\n var item = items[index];\n items.splice(index, 1);\n item.clickableElements = null;\n\n if (item.container) {\n item.container.remove();\n item.container = null;\n }\n }\n /**\n * Notifies that the given decoration was modified and needs to be updated.\n */\n\n\n function update(decoration) {\n remove(decoration.id);\n add(decoration);\n }\n /**\n * Removes all decorations from this group.\n */\n\n\n function clear() {\n clearContainer();\n items.length = 0;\n }\n /**\n * Recreates the decoration elements.\n *\n * To be called after reflowing the resource, for example.\n */\n\n\n function requestLayout() {\n clearContainer();\n items.forEach(function (item) {\n return layout(item);\n });\n }\n /**\n * Layouts a single Decoration item.\n */\n\n\n function layout(item) {\n var groupContainer = requireContainer();\n var style = styles.get(item.decoration.style);\n\n if (!style) {\n logError("Unknown decoration style: ".concat(item.decoration.style));\n return;\n }\n\n var itemContainer = document.createElement("div");\n itemContainer.setAttribute("id", item.id);\n itemContainer.setAttribute("data-style", item.decoration.style);\n itemContainer.style.setProperty("pointer-events", "none");\n var viewportWidth = window.innerWidth;\n var columnCount = parseInt(getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n var pageWidth = viewportWidth / (columnCount || 1);\n var scrollingElement = document.scrollingElement;\n var xOffset = scrollingElement.scrollLeft;\n var yOffset = scrollingElement.scrollTop;\n\n function positionElement(element, rect, boundingRect) {\n element.style.position = "absolute";\n\n if (style.width === "wrap") {\n element.style.width = "".concat(rect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(rect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "viewport") {\n element.style.width = "".concat(viewportWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n var left = Math.floor(rect.left / viewportWidth) * viewportWidth;\n element.style.left = "".concat(left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "bounds") {\n element.style.width = "".concat(boundingRect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(boundingRect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "page") {\n element.style.width = "".concat(pageWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n\n var _left = Math.floor(rect.left / pageWidth) * pageWidth;\n\n element.style.left = "".concat(_left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n }\n }\n\n var boundingRect = item.range.getBoundingClientRect();\n var elementTemplate;\n\n try {\n var template = document.createElement("template");\n template.innerHTML = item.decoration.element.trim();\n elementTemplate = template.content.firstElementChild;\n } catch (error) {\n logError("Invalid decoration element \\"".concat(item.decoration.element, "\\": ").concat(error.message));\n return;\n }\n\n if (style.layout === "boxes") {\n var doNotMergeHorizontallyAlignedRects = true;\n var clientRects = getClientRectsNoOverlap(item.range, doNotMergeHorizontallyAlignedRects);\n clientRects = clientRects.sort(function (r1, r2) {\n if (r1.top < r2.top) {\n return -1;\n } else if (r1.top > r2.top) {\n return 1;\n } else {\n return 0;\n }\n });\n\n var _iterator4 = decorator_createForOfIteratorHelper(clientRects),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var clientRect = _step4.value;\n var line = elementTemplate.cloneNode(true);\n line.style.setProperty("pointer-events", "none");\n positionElement(line, clientRect, boundingRect);\n itemContainer.append(line);\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n } else if (style.layout === "bounds") {\n var bounds = elementTemplate.cloneNode(true);\n bounds.style.setProperty("pointer-events", "none");\n positionElement(bounds, boundingRect, boundingRect);\n itemContainer.append(bounds);\n }\n\n groupContainer.append(itemContainer);\n item.container = itemContainer;\n item.clickableElements = Array.from(itemContainer.querySelectorAll("[data-activable=\'1\']"));\n\n if (item.clickableElements.length === 0) {\n item.clickableElements = Array.from(itemContainer.children);\n }\n }\n /**\n * Returns the group container element, after making sure it exists.\n */\n\n\n function requireContainer() {\n if (!container) {\n container = document.createElement("div");\n container.setAttribute("id", groupId);\n container.setAttribute("data-group", groupName);\n container.style.setProperty("pointer-events", "none");\n document.body.append(container);\n }\n\n return container;\n }\n /**\n * Removes the group container.\n */\n\n\n function clearContainer() {\n if (container) {\n container.remove();\n container = null;\n }\n }\n\n return {\n add: add,\n remove: remove,\n update: update,\n clear: clear,\n items: items,\n requestLayout: requestLayout\n };\n}\nwindow.addEventListener("load", function () {\n // Will relayout all the decorations when the document body is resized.\n var body = document.body;\n var lastSize = {\n width: 0,\n height: 0\n };\n var observer = new ResizeObserver(function () {\n if (lastSize.width === body.clientWidth && lastSize.height === body.clientHeight) {\n return;\n }\n\n lastSize = {\n width: body.clientWidth,\n height: body.clientHeight\n };\n groups.forEach(function (group) {\n group.requestLayout();\n });\n });\n observer.observe(body);\n}, false);\n// EXTERNAL MODULE: ./node_modules/css-selector-generator/build/index.js\nvar build = __webpack_require__(4766);\n;// CONCATENATED MODULE: ./src/dom.js\n//\n// Copyright 2022 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n // See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling\n\nfunction nearestInteractiveElement(element) {\n if (element == null) {\n return null;\n }\n\n var interactiveTags = ["a", "audio", "button", "canvas", "details", "input", "label", "option", "select", "submit", "textarea", "video"];\n\n if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) {\n return element.outerHTML;\n } // Checks whether the element is editable by the user.\n\n\n if (element.hasAttribute("contenteditable") && element.getAttribute("contenteditable").toLowerCase() != "false") {\n return element.outerHTML;\n } // Checks parents recursively because the touch might be for example on an inside a .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n}\n;// CONCATENATED MODULE: ./src/keyboard.js\n//\n// Copyright 2023 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nwindow.addEventListener("keydown", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "down");\n});\nwindow.addEventListener("keyup", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "up");\n});\n\nfunction shouldIgnoreEvent(event) {\n return event.defaultPrevented || nearestInteractiveElement(document.activeElement) != null;\n} // We prevent the default behavior for keyboard events, otherwise the web view\n// might scroll.\n\n\nfunction preventDefault(event) {\n event.stopPropagation();\n event.preventDefault();\n}\n\nfunction sendPressKeyMessage(event, type) {\n if (event.repeat) return;\n var keyEvent = {\n type: type,\n code: event.code,\n characters: String.fromCharCode(event.keyCode),\n alt: event.altKey,\n control: event.ctrlKey,\n shift: event.shiftKey,\n meta: event.metaKey\n };\n Android.onKey(JSON.stringify(keyEvent));\n}\n;// CONCATENATED MODULE: ./src/highlight.js\nfunction highlight_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { highlight_typeof = function _typeof(obj) { return typeof obj; }; } else { highlight_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return highlight_typeof(obj); }\n\nfunction highlight_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = highlight_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction highlight_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return highlight_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return highlight_arrayLikeToArray(o, minLen); }\n\nfunction highlight_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/* eslint-disable */\n//\n// highlight.js\n// r2-navigator-kotlin\n//\n// Organized by Taehyun Kim on 6/27/19 from r2-navigator-js.\n//\n// Copyright 2019 Readium Foundation. All rights reserved.\n// Use of this source code is governed by a BSD-style license which is detailed\n// in the LICENSE file present in the project repository where this source code is maintained.\n//\nvar ROOT_CLASS_REDUCE_MOTION = "r2-reduce-motion";\nvar ROOT_CLASS_NO_FOOTNOTES = "r2-no-popup-foonotes";\nvar POPUP_DIALOG_CLASS = "r2-popup-dialog";\nvar FOOTNOTES_CONTAINER_CLASS = "r2-footnote-container";\nvar FOOTNOTES_CLOSE_BUTTON_CLASS = "r2-footnote-close";\nvar FOOTNOTE_FORCE_SHOW = "r2-footnote-force-show";\nvar TTS_ID_PREVIOUS = "r2-tts-previous";\nvar TTS_ID_NEXT = "r2-tts-next";\nvar TTS_ID_SLIDER = "r2-tts-slider";\nvar TTS_ID_ACTIVE_WORD = "r2-tts-active-word";\nvar TTS_ID_CONTAINER = "r2-tts-txt";\nvar TTS_ID_INFO = "r2-tts-info";\nvar TTS_NAV_BUTTON_CLASS = "r2-tts-button";\nvar TTS_ID_SPEAKING_DOC_ELEMENT = "r2-tts-speaking-el";\nvar TTS_CLASS_INJECTED_SPAN = "r2-tts-speaking-txt";\nvar TTS_CLASS_INJECTED_SUBSPAN = "r2-tts-speaking-word";\nvar TTS_ID_INJECTED_PARENT = "r2-tts-speaking-txt-parent";\nvar ID_HIGHLIGHTS_CONTAINER = "R2_ID_HIGHLIGHTS_CONTAINER";\nvar ID_ANNOTATION_CONTAINER = "R2_ID_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_CONTAINER = "R2_CLASS_HIGHLIGHT_CONTAINER";\nvar CLASS_ANNOTATION_CONTAINER = "R2_CLASS_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_AREA = "R2_CLASS_HIGHLIGHT_AREA";\nvar CLASS_ANNOTATION_AREA = "R2_CLASS_ANNOTATION_AREA";\nvar CLASS_HIGHLIGHT_BOUNDING_AREA = "R2_CLASS_HIGHLIGHT_BOUNDING_AREA";\nvar CLASS_ANNOTATION_BOUNDING_AREA = "R2_CLASS_ANNOTATION_BOUNDING_AREA"; // tslint:disable-next-line:max-line-length\n\nvar _blacklistIdClassForCFI = [POPUP_DIALOG_CLASS, TTS_CLASS_INJECTED_SPAN, TTS_CLASS_INJECTED_SUBSPAN, ID_HIGHLIGHTS_CONTAINER, CLASS_HIGHLIGHT_CONTAINER, CLASS_HIGHLIGHT_AREA, CLASS_HIGHLIGHT_BOUNDING_AREA, "resize-sensor"];\nvar CLASS_PAGINATED = "r2-css-paginated"; //const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");\n\nvar IS_DEV = false;\nvar _highlights = [];\n\nvar _highlightsContainer;\n\nvar _annotationContainer;\n\nvar lastMouseDownX = -1;\nvar lastMouseDownY = -1;\nvar bodyEventListenersSet = false;\nvar USE_SVG = false;\nvar DEFAULT_BACKGROUND_COLOR_OPACITY = 0.3;\nvar ALT_BACKGROUND_COLOR_OPACITY = 0.45; //const DEBUG_VISUALS = false;\n\nvar DEBUG_VISUALS = false;\nvar DEFAULT_BACKGROUND_COLOR = {\n blue: 100,\n green: 50,\n red: 230\n};\nvar ANNOTATION_WIDTH = 15;\n\nfunction resetHighlightBoundingStyle(_win, highlightBounding) {\n if (highlightBounding.getAttribute("class") == CLASS_ANNOTATION_BOUNDING_AREA) {\n return;\n }\n\n highlightBounding.style.outline = "none";\n highlightBounding.style.setProperty("background-color", "transparent", "important");\n}\n\nfunction setHighlightAreaStyle(win, highlightAreas, highlight) {\n var useSVG = !DEBUG_VISUALS && USE_SVG;\n\n var _iterator = highlight_createForOfIteratorHelper(highlightAreas),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var highlightArea = _step.value;\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var opacity = ALT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n}\n\nfunction resetHighlightAreaStyle(win, highlightArea) {\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var id = isSVG ? highlightArea.parentNode && highlightArea.parentNode.parentNode && highlightArea.parentNode.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.parentNode.getAttribute ? highlightArea.parentNode.parentNode.getAttribute("id") : undefined : highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.getAttribute ? highlightArea.parentNode.getAttribute("id") : undefined;\n\n if (id) {\n var highlight = _highlights.find(function (h) {\n return h.id === id;\n });\n\n if (highlight) {\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n }\n}\n\nfunction processTouchEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.changedTouches[0].clientX;\n var y = ev.changedTouches[0].clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect; // _highlights.sort(function(a, b) {\n // console.log(JSON.stringify(a.selectionInfo))\n // return a.selectionInfo.cleanText.length < b.selectionInfo.cleanText.length\n // })\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator2 = highlight_createForOfIteratorHelper(highlightFragments),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var highlightFragment = _step2.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator3 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var highlightBounding = _step3.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i = 0, _allHighlightAreas = allHighlightAreas; _i < _allHighlightAreas.length; _i++) {\n var highlightArea = _allHighlightAreas[_i];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas2 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator4 = highlight_createForOfIteratorHelper(_allHighlightAreas2),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var _highlightArea = _step4.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea) < 0) {\n resetHighlightAreaStyle(win, _highlightArea);\n }\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator5 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step5;\n\n try {\n for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {\n var _highlightBounding = _step5.value;\n\n if (!foundElementHighlightBounding || _highlightBounding !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding);\n }\n }\n } catch (err) {\n _iterator5.e(err);\n } finally {\n _iterator5.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "touchstart" || ev.type === "touchend") {\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight.id,\n size: size\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n console.log(foundHighlight.id.includes("R2_ANNOTATION_"));\n\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n}\n\nfunction processMouseEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.clientX;\n var y = ev.clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect;\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator6 = highlight_createForOfIteratorHelper(highlightFragments),\n _step6;\n\n try {\n for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {\n var highlightFragment = _step6.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator6.e(err);\n } finally {\n _iterator6.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator7 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step7;\n\n try {\n for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {\n var highlightBounding = _step7.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator7.e(err);\n } finally {\n _iterator7.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i2 = 0, _allHighlightAreas3 = allHighlightAreas; _i2 < _allHighlightAreas3.length; _i2++) {\n var highlightArea = _allHighlightAreas3[_i2];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas4 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator8 = highlight_createForOfIteratorHelper(_allHighlightAreas4),\n _step8;\n\n try {\n for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {\n var _highlightArea2 = _step8.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea2) < 0) {\n resetHighlightAreaStyle(win, _highlightArea2);\n }\n }\n } catch (err) {\n _iterator8.e(err);\n } finally {\n _iterator8.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator9 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step9;\n\n try {\n for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {\n var _highlightBounding2 = _step9.value;\n\n if (!foundElementHighlightBounding || _highlightBounding2 !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding2);\n }\n }\n } catch (err) {\n _iterator9.e(err);\n } finally {\n _iterator9.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "mouseup" || ev.type === "touchend") {\n var touchedPosition = {\n screenWidth: window.outerWidth,\n screenHeight: window.innerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight,\n position: touchedPosition\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n }\n }\n}\n\nfunction highlight_rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && highlight_almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && highlight_almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && highlight_almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && highlight_almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction highlight_replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("replaceOverlapingRects rect1 === rect2 ??!");\n }\n\n continue;\n }\n\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret = function () {\n var toAdd = [];\n var toRemove = void 0;\n var toPreserve = void 0;\n var subtractRects1 = highlight_rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n var subtractRects2 = highlight_rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n toPreserve = rect1;\n }\n }\n\n if (IS_DEV) {\n var toCheck = [];\n toCheck.push(toPreserve);\n Array.prototype.push.apply(toCheck, toAdd);\n checkOverlaps(toCheck);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: highlight_replaceOverlapingRects(newRects)\n };\n }();\n\n if (highlight_typeof(_ret) === "object") return _ret.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction checkOverlaps(rects) {\n var stillOverlapingRects = [];\n\n var _iterator10 = highlight_createForOfIteratorHelper(rects),\n _step10;\n\n try {\n for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {\n var rect1 = _step10.value;\n\n var _iterator11 = highlight_createForOfIteratorHelper(rects),\n _step11;\n\n try {\n for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {\n var rect2 = _step11.value;\n\n if (rect1 === rect2) {\n continue;\n }\n\n var has1 = stillOverlapingRects.indexOf(rect1) >= 0;\n var has2 = stillOverlapingRects.indexOf(rect2) >= 0;\n\n if (!has1 || !has2) {\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n if (!has1) {\n stillOverlapingRects.push(rect1);\n }\n\n if (!has2) {\n stillOverlapingRects.push(rect2);\n }\n\n console.log("CLIENT RECT: overlap ---");\n console.log("#1 TOP:".concat(rect1.top, " BOTTOM:").concat(rect1.bottom, " LEFT:").concat(rect1.left, " RIGHT:").concat(rect1.right, " WIDTH:").concat(rect1.width, " HEIGHT:").concat(rect1.height));\n console.log("#2 TOP:".concat(rect2.top, " BOTTOM:").concat(rect2.bottom, " LEFT:").concat(rect2.left, " RIGHT:").concat(rect2.right, " WIDTH:").concat(rect2.width, " HEIGHT:").concat(rect2.height));\n var xOverlap = getRectOverlapX(rect1, rect2);\n console.log("xOverlap: ".concat(xOverlap));\n var yOverlap = getRectOverlapY(rect1, rect2);\n console.log("yOverlap: ".concat(yOverlap));\n }\n }\n }\n } catch (err) {\n _iterator11.e(err);\n } finally {\n _iterator11.f();\n }\n }\n } catch (err) {\n _iterator10.e(err);\n } finally {\n _iterator10.f();\n }\n\n if (stillOverlapingRects.length) {\n console.log("CLIENT RECT: overlaps ".concat(stillOverlapingRects.length));\n }\n}\n\nfunction highlight_removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator12 = highlight_createForOfIteratorHelper(rects),\n _step12;\n\n try {\n for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {\n var rect = _step12.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove tiny");\n }\n\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator13 = highlight_createForOfIteratorHelper(rects),\n _step13;\n\n try {\n for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {\n var possiblyContainingRect = _step13.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (highlight_rectContains(possiblyContainingRect, rect, tolerance)) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove contained");\n }\n\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator13.e(err);\n } finally {\n _iterator13.f();\n }\n }\n } catch (err) {\n _iterator12.e(err);\n } finally {\n _iterator12.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction highlight_almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction highlight_rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n var rect = {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n return rect;\n}\n\nfunction highlight_rectSubtract(rect1, rect2) {\n var rectIntersected = highlight_rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction highlight_rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || highlight_almostEqual(rect.left, x, tolerance)) && (rect.right > x || highlight_almostEqual(rect.right, x, tolerance)) && (rect.top < y || highlight_almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || highlight_almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction highlight_rectContains(rect1, rect2, tolerance) {\n return highlight_rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction highlight_getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction highlight_mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("mergeTouchingRects rect1 === rect2 ??!");\n }\n\n return "continue";\n }\n\n var rectsLineUpVertically = highlight_almostEqual(rect1.top, rect2.top, tolerance) && highlight_almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = highlight_almostEqual(rect1.left, rect2.left, tolerance) && highlight_almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && highlight_rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n if (IS_DEV) {\n console.log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = highlight_getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: highlight_mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret2 = _loop(j);\n\n if (_ret2 === "continue") continue;\n if (highlight_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n\n return rects;\n}\n\nfunction highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var rangeClientRects = range.getClientRects();\n return getClientRectsNoOverlap_(rangeClientRects, doNotMergeHorizontallyAlignedRects);\n}\n\nfunction getClientRectsNoOverlap_(clientRects, doNotMergeHorizontallyAlignedRects) {\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator14 = highlight_createForOfIteratorHelper(clientRects),\n _step14;\n\n try {\n for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {\n var rangeClientRect = _step14.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator14.e(err);\n } finally {\n _iterator14.f();\n }\n\n var mergedRects = highlight_mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = highlight_removeContainedRects(mergedRects, tolerance);\n var newRects = highlight_replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small");\n }\n\n newRects.splice(j, 1);\n } else {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small, but keep otherwise empty!");\n }\n\n break;\n }\n }\n }\n\n if (IS_DEV) {\n checkOverlaps(newRects);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n }\n\n return newRects;\n}\n\nfunction isPaginated(document) {\n return document && document.documentElement && document.documentElement.classList.contains(CLASS_PAGINATED);\n}\n\nfunction getScrollingElement(document) {\n if (document.scrollingElement) {\n return document.scrollingElement;\n }\n\n return document.body;\n}\n\nfunction ensureContainer(win, annotationFlag) {\n var document = win.document;\n\n if (!_highlightsContainer) {\n if (!bodyEventListenersSet) {\n bodyEventListenersSet = true;\n document.body.addEventListener("mousedown", function (ev) {\n lastMouseDownX = ev.clientX;\n lastMouseDownY = ev.clientY;\n }, false);\n document.body.addEventListener("mouseup", function (ev) {\n if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {\n processMouseEvent(win, ev);\n }\n }, false);\n document.body.addEventListener("mousemove", function (ev) {\n processMouseEvent(win, ev);\n }, false);\n document.body.addEventListener("touchend", function touchEnd(e) {\n processTouchEvent(win, e);\n }, false);\n }\n\n _highlightsContainer = document.createElement("div");\n\n _highlightsContainer.setAttribute("id", ID_HIGHLIGHTS_CONTAINER);\n\n _highlightsContainer.style.setProperty("pointer-events", "none");\n\n document.body.append(_highlightsContainer);\n }\n\n return _highlightsContainer;\n}\n\nfunction hideAllhighlights() {\n if (_highlightsContainer) {\n _highlightsContainer.remove();\n\n _highlightsContainer = null;\n }\n}\n\nfunction destroyAllhighlights() {\n hideAllhighlights();\n\n _highlights.splice(0, _highlights.length);\n}\n\nfunction destroyHighlight(id) {\n var i = -1;\n var _document = window.document;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (highlight && i >= 0 && i < _highlights.length) {\n _highlights.splice(i, 1);\n }\n\n var highlightContainer = _document.getElementById(id);\n\n if (highlightContainer) {\n highlightContainer.remove();\n }\n}\n\nfunction isCfiTextNode(node) {\n return node.nodeType !== Node.ELEMENT_NODE;\n}\n\nfunction getChildTextNodeCfiIndex(element, child) {\n var found = -1;\n var textNodeIndex = -1;\n var previousWasElement = false;\n\n for (var i = 0; i < element.childNodes.length; i++) {\n var childNode = element.childNodes[i];\n var isText = isCfiTextNode(childNode);\n\n if (isText || previousWasElement) {\n textNodeIndex += 2;\n }\n\n if (isText) {\n if (childNode === child) {\n found = textNodeIndex;\n break;\n }\n }\n\n previousWasElement = childNode.nodeType === Node.ELEMENT_NODE;\n }\n\n return found;\n}\n\nfunction getCommonAncestorElement(node1, node2) {\n if (node1.nodeType === Node.ELEMENT_NODE && node1 === node2) {\n return node1;\n }\n\n if (node1.nodeType === Node.ELEMENT_NODE && node1.contains(node2)) {\n return node1;\n }\n\n if (node2.nodeType === Node.ELEMENT_NODE && node2.contains(node1)) {\n return node2;\n }\n\n var node1ElementAncestorChain = [];\n var parent = node1.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node1ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var node2ElementAncestorChain = [];\n parent = node2.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node2ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var commonAncestor = node1ElementAncestorChain.find(function (node1ElementAncestor) {\n return node2ElementAncestorChain.indexOf(node1ElementAncestor) >= 0;\n });\n\n if (!commonAncestor) {\n commonAncestor = node2ElementAncestorChain.find(function (node2ElementAncestor) {\n return node1ElementAncestorChain.indexOf(node2ElementAncestor) >= 0;\n });\n }\n\n return commonAncestor;\n}\n\nfunction fullQualifiedSelector(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n return lowerCaseName;\n } //return cssPath(node, justSelector);\n\n\n return cssPath(node, true);\n}\n\nfunction getCurrentSelectionInfo() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n console.log("^^^ SELECTION COLLAPSED.");\n return undefined;\n }\n\n var rawText = selection.toString();\n var cleanText = rawText.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanText.length === 0) {\n console.log("^^^ SELECTION TEXT EMPTY.");\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n console.log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var rangeInfo = convertRange(range, fullQualifiedSelector, computeCFI);\n\n if (!rangeInfo) {\n console.log("^^^ SELECTION RANGE INFO FAIL?!");\n return undefined;\n }\n\n if (IS_DEV && DEBUG_VISUALS) {\n var restoredRange = convertRangeInfo(win.document, rangeInfo);\n\n if (restoredRange) {\n if (restoredRange.startOffset === range.startOffset && restoredRange.endOffset === range.endOffset && restoredRange.startContainer === range.startContainer && restoredRange.endContainer === range.endContainer) {\n console.log("SELECTION RANGE RESTORED OKAY (dev check).");\n } else {\n console.log("SELECTION RANGE RESTORE FAIL (dev check).");\n dumpDebug("SELECTION", selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset, getCssSelector);\n dumpDebug("ORDERED RANGE FROM SELECTION", range.startContainer, range.startOffset, range.endContainer, range.endOffset, getCssSelector);\n dumpDebug("RESTORED RANGE", restoredRange.startContainer, restoredRange.startOffset, restoredRange.endContainer, restoredRange.endOffset, getCssSelector);\n }\n } else {\n console.log("CANNOT RESTORE SELECTION RANGE ??!");\n }\n } else {}\n\n return {\n locations: rangeInfo2Location(rangeInfo),\n text: {\n highlight: rawText\n }\n };\n}\n\nfunction checkBlacklisted(el) {\n var blacklistedId;\n var id = el.getAttribute("id");\n\n if (id && _blacklistIdClassForCFI.indexOf(id) >= 0) {\n console.log("checkBlacklisted ID: " + id);\n blacklistedId = id;\n }\n\n var blacklistedClass;\n\n var _iterator15 = highlight_createForOfIteratorHelper(_blacklistIdClassForCFI),\n _step15;\n\n try {\n for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {\n var item = _step15.value;\n\n if (el.classList.contains(item)) {\n console.log("checkBlacklisted CLASS: " + item);\n blacklistedClass = item;\n break;\n }\n }\n } catch (err) {\n _iterator15.e(err);\n } finally {\n _iterator15.f();\n }\n\n if (blacklistedId || blacklistedClass) {\n return true;\n }\n\n return false;\n}\n\nfunction cssPath(node, optimized) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return "";\n }\n\n var steps = [];\n var contextNode = node;\n\n while (contextNode) {\n var step = _cssPathStep(contextNode, !!optimized, contextNode === node);\n\n if (!step) {\n break; // Error - bail out early.\n }\n\n steps.push(step.value);\n\n if (step.optimized) {\n break;\n }\n\n contextNode = contextNode.parentNode;\n }\n\n steps.reverse();\n return steps.join(" > ");\n} // tslint:disable-next-line:max-line-length\n// https://chromium.googlesource.com/chromium/blink/+/master/Source/devtools/front_end/components/DOMPresentationUtils.js#316\n\n\nfunction _cssPathStep(node, optimized, isTargetNode) {\n function prefixedElementClassNames(nd) {\n var classAttribute = nd.getAttribute("class");\n\n if (!classAttribute) {\n return [];\n }\n\n return classAttribute.split(/\\s+/g).filter(Boolean).map(function (nm) {\n // The prefix is required to store "__proto__" in a object-based map.\n return "$" + nm;\n });\n }\n\n function idSelector(idd) {\n return "#" + escapeIdentifierIfNeeded(idd);\n }\n\n function escapeIdentifierIfNeeded(ident) {\n if (isCSSIdentifier(ident)) {\n return ident;\n }\n\n var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);\n var lastIndex = ident.length - 1;\n return ident.replace(/./g, function (c, ii) {\n return shouldEscapeFirst && ii === 0 || !isCSSIdentChar(c) ? escapeAsciiChar(c, ii === lastIndex) : c;\n });\n }\n\n function escapeAsciiChar(c, isLast) {\n return "\\\\" + toHexByte(c) + (isLast ? "" : " ");\n }\n\n function toHexByte(c) {\n var hexByte = c.charCodeAt(0).toString(16);\n\n if (hexByte.length === 1) {\n hexByte = "0" + hexByte;\n }\n\n return hexByte;\n }\n\n function isCSSIdentChar(c) {\n if (/[a-zA-Z0-9_-]/.test(c)) {\n return true;\n }\n\n return c.charCodeAt(0) >= 0xa0;\n }\n\n function isCSSIdentifier(value) {\n return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n var element = node;\n var id = element.getAttribute("id");\n\n if (optimized) {\n if (id) {\n return {\n optimized: true,\n value: idSelector(id)\n };\n }\n\n if (lowerCaseName === "body" || lowerCaseName === "head" || lowerCaseName === "html") {\n return {\n optimized: true,\n value: lowerCaseName // node.nodeNameInCorrectCase(),\n\n };\n }\n }\n\n var nodeName = lowerCaseName; // node.nodeNameInCorrectCase();\n\n if (id) {\n return {\n optimized: true,\n value: nodeName + idSelector(id)\n };\n }\n\n var parent = node.parentNode;\n\n if (!parent || parent.nodeType === Node.DOCUMENT_NODE) {\n return {\n optimized: true,\n value: nodeName\n };\n }\n\n var prefixedOwnClassNamesArray_ = prefixedElementClassNames(element);\n var prefixedOwnClassNamesArray = []; // .keySet()\n\n prefixedOwnClassNamesArray_.forEach(function (arrItem) {\n if (prefixedOwnClassNamesArray.indexOf(arrItem) < 0) {\n prefixedOwnClassNamesArray.push(arrItem);\n }\n });\n var needsClassNames = false;\n var needsNthChild = false;\n var ownIndex = -1;\n var elementIndex = -1;\n var siblings = parent.children;\n\n var _loop2 = function _loop2(i) {\n var sibling = siblings[i];\n\n if (sibling.nodeType !== Node.ELEMENT_NODE) {\n return "continue";\n }\n\n elementIndex += 1;\n\n if (sibling === node) {\n ownIndex = elementIndex;\n return "continue";\n }\n\n if (needsNthChild) {\n return "continue";\n } // sibling.nodeNameInCorrectCase()\n\n\n var siblingName = sibling.localName && sibling.localName.toLowerCase() || sibling.nodeName.toLowerCase();\n\n if (siblingName !== nodeName) {\n return "continue";\n }\n\n needsClassNames = true;\n var ownClassNames = [];\n prefixedOwnClassNamesArray.forEach(function (arrItem) {\n ownClassNames.push(arrItem);\n });\n var ownClassNameCount = ownClassNames.length;\n\n if (ownClassNameCount === 0) {\n needsNthChild = true;\n return "continue";\n }\n\n var siblingClassNamesArray_ = prefixedElementClassNames(sibling);\n var siblingClassNamesArray = []; // .keySet()\n\n siblingClassNamesArray_.forEach(function (arrItem) {\n if (siblingClassNamesArray.indexOf(arrItem) < 0) {\n siblingClassNamesArray.push(arrItem);\n }\n });\n\n for (var _i3 = 0, _siblingClassNamesArr = siblingClassNamesArray; _i3 < _siblingClassNamesArr.length; _i3++) {\n var siblingClass = _siblingClassNamesArr[_i3];\n var ind = ownClassNames.indexOf(siblingClass);\n\n if (ind < 0) {\n continue;\n }\n\n ownClassNames.splice(ind, 1); // delete ownClassNames[siblingClass];\n\n if (! --ownClassNameCount) {\n needsNthChild = true;\n break;\n }\n }\n };\n\n for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {\n var _ret3 = _loop2(i);\n\n if (_ret3 === "continue") continue;\n }\n\n var result = nodeName;\n\n if (isTargetNode && nodeName === "input" && element.getAttribute("type") && !element.getAttribute("id") && !element.getAttribute("class")) {\n result += \'[type="\' + element.getAttribute("type") + \'"]\';\n }\n\n if (needsNthChild) {\n result += ":nth-child(" + (ownIndex + 1) + ")";\n } else if (needsClassNames) {\n var _iterator16 = highlight_createForOfIteratorHelper(prefixedOwnClassNamesArray),\n _step16;\n\n try {\n for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {\n var prefixedName = _step16.value;\n result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));\n }\n } catch (err) {\n _iterator16.e(err);\n } finally {\n _iterator16.f();\n }\n }\n\n return {\n optimized: false,\n value: result\n };\n}\n\nfunction computeCFI(node) {\n // TODO: handle character position inside text node\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var cfi = "";\n var currentElement = node;\n\n while (currentElement.parentNode && currentElement.parentNode.nodeType === Node.ELEMENT_NODE) {\n var blacklisted = checkBlacklisted(currentElement);\n\n if (!blacklisted) {\n var currentElementParentChildren = currentElement.parentNode.children;\n var currentElementIndex = -1;\n\n for (var i = 0; i < currentElementParentChildren.length; i++) {\n if (currentElement === currentElementParentChildren[i]) {\n currentElementIndex = i;\n break;\n }\n }\n\n if (currentElementIndex >= 0) {\n var cfiIndex = (currentElementIndex + 1) * 2;\n cfi = cfiIndex + (currentElement.id ? "[" + currentElement.id + "]" : "") + (cfi.length ? "/" + cfi : "");\n }\n }\n\n currentElement = currentElement.parentNode;\n }\n\n return "/" + cfi;\n}\n\nfunction _createHighlight(locations, color, pointerInteraction, type) {\n var rangeInfo = location2RangeInfo(locations);\n var uniqueStr = "".concat(rangeInfo.cfi).concat(rangeInfo.startContainerElementCssSelector).concat(rangeInfo.startContainerChildTextNodeIndex).concat(rangeInfo.startOffset).concat(rangeInfo.endContainerElementCssSelector).concat(rangeInfo.endContainerChildTextNodeIndex).concat(rangeInfo.endOffset);\n\n var hash = __webpack_require__(3715);\n\n var sha256Hex = hash.sha256().update(uniqueStr).digest("hex");\n var id;\n\n if (type == ID_HIGHLIGHTS_CONTAINER) {\n id = "R2_HIGHLIGHT_" + sha256Hex;\n } else {\n id = "R2_ANNOTATION_" + sha256Hex;\n }\n\n destroyHighlight(id);\n var highlight = {\n color: color ? color : DEFAULT_BACKGROUND_COLOR,\n id: id,\n pointerInteraction: pointerInteraction,\n rangeInfo: rangeInfo\n };\n\n _highlights.push(highlight);\n\n createHighlightDom(window, highlight, type == ID_ANNOTATION_CONTAINER ? true : false);\n return highlight;\n}\n\nfunction createHighlight(selectionInfo, color, pointerInteraction) {\n return _createHighlight(selectionInfo, color, pointerInteraction, ID_HIGHLIGHTS_CONTAINER);\n}\nfunction createAnnotation(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (i == _highlights.length) return;\n var locations = {\n locations: rangeInfo2Location(highlight.rangeInfo)\n };\n return _createHighlight(locations, highlight.color, true, ID_ANNOTATION_CONTAINER);\n}\n\nfunction createHighlightDom(win, highlight, annotationFlag) {\n var document = win.document;\n var scale = 1 / (win.READIUM2 && win.READIUM2.isFixedLayout ? win.READIUM2.fxlViewportScale : 1);\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var paginated = isPaginated(document);\n var highlightsContainer = ensureContainer(win, annotationFlag);\n var highlightParent = document.createElement("div");\n highlightParent.setAttribute("id", highlight.id);\n highlightParent.setAttribute("class", CLASS_HIGHLIGHT_CONTAINER);\n document.body.style.position = "relative";\n highlightParent.style.setProperty("pointer-events", "none");\n\n if (highlight.pointerInteraction) {\n highlightParent.setAttribute("data-click", "1");\n }\n\n var bodyRect = document.body.getBoundingClientRect();\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var highlightAreaSVGDocFrag;\n var roundedCorner = 3;\n var underlineThickness = 2;\n var strikeThroughLineThickness = 3;\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n var extra = "";\n var rangeAnnotationBoundingClientRect = frameForHighlightAnnotationMarkWithID(win, highlight.id);\n var xOffset;\n var yOffset;\n var annotationOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n annotationOffset = parseInt((rangeAnnotationBoundingClientRect.right - xOffset) / window.innerWidth) + 1;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n annotationOffset = parseInt(rangeAnnotationBoundingClientRect.right / window.innerWidth + 1);\n }\n\n var _iterator17 = highlight_createForOfIteratorHelper(clientRects),\n _step17;\n\n try {\n for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {\n var clientRect = _step17.value;\n\n if (useSVG) {\n var borderThickness = 0;\n\n if (!highlightAreaSVGDocFrag) {\n highlightAreaSVGDocFrag = document.createDocumentFragment();\n }\n\n var highlightAreaSVGRect = document.createElementNS(SVG_XML_NAMESPACE, "rect");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGRect.setAttribute("style", "fill: rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; fill-opacity: ").concat(opacity, " !important; stroke-width: 0;"));\n highlightAreaSVGRect.scale = scale;\n /*\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGRect.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaSVGRect.setAttribute("rx", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("ry", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("x", "".concat((highlightAreaSVGRect.rect.left - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("y", "".concat((highlightAreaSVGRect.rect.top - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("height", "".concat((highlightAreaSVGRect.rect.height + borderThickness * 2) * scale));\n highlightAreaSVGRect.setAttribute("width", "".concat((highlightAreaSVGRect.rect.width + borderThickness * 2) * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGRect);\n\n if (drawUnderline) {\n var highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGLine.setAttribute("style", "stroke-linecap: round; stroke-width: ".concat(underlineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n var lineOffset = highlightAreaSVGLine.rect.width > roundedCorner ? roundedCorner : 0;\n highlightAreaSVGLine.setAttribute("x1", "".concat((highlightAreaSVGLine.rect.left + lineOffset) * scale));\n highlightAreaSVGLine.setAttribute("x2", "".concat((highlightAreaSVGLine.rect.left + highlightAreaSVGLine.rect.width - lineOffset) * scale));\n var y = (highlightAreaSVGLine.rect.top + highlightAreaSVGLine.rect.height - underlineThickness / 2) * scale;\n highlightAreaSVGLine.setAttribute("y1", "".concat(y));\n highlightAreaSVGLine.setAttribute("y2", "".concat(y));\n highlightAreaSVGLine.setAttribute("height", "".concat(highlightAreaSVGLine.rect.height * scale));\n highlightAreaSVGLine.setAttribute("width", "".concat(highlightAreaSVGLine.rect.width * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGLine);\n }\n\n if (drawStrikeThrough) {\n var _highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n _highlightAreaSVGLine.setAttribute("style", "stroke-linecap: butt; stroke-width: ".concat(strikeThroughLineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n\n _highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n _highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n _highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n _highlightAreaSVGLine.setAttribute("x1", "".concat(_highlightAreaSVGLine.rect.left * scale));\n\n _highlightAreaSVGLine.setAttribute("x2", "".concat((_highlightAreaSVGLine.rect.left + _highlightAreaSVGLine.rect.width) * scale));\n\n var _lineOffset = _highlightAreaSVGLine.rect.height / 2;\n\n var _y = (_highlightAreaSVGLine.rect.top + _lineOffset) * scale;\n\n _highlightAreaSVGLine.setAttribute("y1", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("y2", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("height", "".concat(_highlightAreaSVGLine.rect.height * scale));\n\n _highlightAreaSVGLine.setAttribute("width", "".concat(_highlightAreaSVGLine.rect.width * scale));\n\n highlightAreaSVGDocFrag.appendChild(_highlightAreaSVGLine);\n }\n } else {\n var highlightArea = document.createElement("div");\n highlightArea.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n if (DEBUG_VISUALS) {\n var rgb = Math.round(0xffffff * Math.random());\n var r = rgb >> 16;\n var g = rgb >> 8 & 255;\n var b = rgb & 255;\n extra = "outline-color: rgb(".concat(r, ", ").concat(g, ", ").concat(b, "); outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n } else {\n if (drawUnderline) {\n extra += "border-bottom: ".concat(underlineThickness * scale, "px solid rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important");\n }\n }\n\n highlightArea.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n highlightArea.style.setProperty("pointer-events", "none");\n highlightArea.style.position = paginated ? "fixed" : "absolute";\n highlightArea.scale = scale;\n /*\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightArea.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightArea.style.width = "".concat(highlightArea.rect.width * scale, "px");\n highlightArea.style.height = "".concat(highlightArea.rect.height * scale, "px");\n highlightArea.style.left = "".concat(highlightArea.rect.left * scale, "px");\n highlightArea.style.top = "".concat(highlightArea.rect.top * scale, "px");\n highlightParent.append(highlightArea);\n\n if (!DEBUG_VISUALS && drawStrikeThrough) {\n //if (drawStrikeThrough) {\n var highlightAreaLine = document.createElement("div");\n highlightAreaLine.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaLine.setAttribute("style", "background-color: rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important;"));\n highlightAreaLine.style.setProperty("pointer-events", "none");\n highlightAreaLine.style.position = paginated ? "fixed" : "absolute";\n highlightAreaLine.scale = scale;\n /*\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaLine.style.width = "".concat(highlightAreaLine.rect.width * scale, "px");\n highlightAreaLine.style.height = "".concat(strikeThroughLineThickness * scale, "px");\n highlightAreaLine.style.left = "".concat(highlightAreaLine.rect.left * scale, "px");\n highlightAreaLine.style.top = "".concat((highlightAreaLine.rect.top + highlightAreaLine.rect.height / 2 - strikeThroughLineThickness / 2) * scale, "px");\n highlightParent.append(highlightAreaLine);\n }\n }\n\n if (annotationFlag) {\n break;\n }\n }\n } catch (err) {\n _iterator17.e(err);\n } finally {\n _iterator17.f();\n }\n\n if (useSVG && highlightAreaSVGDocFrag) {\n var highlightAreaSVG = document.createElementNS(SVG_XML_NAMESPACE, "svg");\n highlightAreaSVG.setAttribute("pointer-events", "none");\n highlightAreaSVG.style.position = paginated ? "fixed" : "absolute";\n highlightAreaSVG.style.overflow = "visible";\n highlightAreaSVG.style.left = "0";\n highlightAreaSVG.style.top = "0";\n highlightAreaSVG.append(highlightAreaSVGDocFrag);\n highlightParent.append(highlightAreaSVG);\n }\n\n var highlightBounding = document.createElement("div");\n\n if (annotationFlag) {\n highlightBounding.setAttribute("class", CLASS_ANNOTATION_BOUNDING_AREA);\n highlightBounding.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n } else {\n highlightBounding.setAttribute("class", CLASS_HIGHLIGHT_BOUNDING_AREA);\n }\n\n highlightBounding.style.setProperty("pointer-events", "none");\n highlightBounding.style.position = paginated ? "fixed" : "absolute";\n highlightBounding.scale = scale;\n\n if (DEBUG_VISUALS) {\n highlightBounding.setAttribute("style", "outline-color: magenta; outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n }\n\n if (annotationFlag) {\n highlightBounding.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n var rangeBoundingClientRect = range.getBoundingClientRect();\n highlightBounding.rect = {\n height: rangeBoundingClientRect.height,\n left: rangeBoundingClientRect.left - xOffset,\n top: rangeBoundingClientRect.top - yOffset,\n width: rangeBoundingClientRect.width\n };\n }\n\n highlightBounding.style.width = "".concat(highlightBounding.rect.width * scale, "px");\n highlightBounding.style.height = "".concat(highlightBounding.rect.height * scale, "px");\n highlightBounding.style.left = "".concat(highlightBounding.rect.left * scale, "px");\n highlightBounding.style.top = "".concat(highlightBounding.rect.top * scale, "px");\n highlightParent.append(highlightBounding);\n highlightsContainer.append(highlightParent);\n return highlightParent;\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n console.log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n console.log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n console.log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRange(range, getCssSelector, computeElementCFI) {\n var startIsElement = range.startContainer.nodeType === Node.ELEMENT_NODE;\n var startContainerElement = startIsElement ? range.startContainer : range.startContainer.parentNode && range.startContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.startContainer.parentNode : undefined;\n\n if (!startContainerElement) {\n return undefined;\n }\n\n var startContainerChildTextNodeIndex = startIsElement ? -1 : Array.from(startContainerElement.childNodes).indexOf(range.startContainer);\n\n if (startContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var startContainerElementCssSelector = getCssSelector(startContainerElement);\n var endIsElement = range.endContainer.nodeType === Node.ELEMENT_NODE;\n var endContainerElement = endIsElement ? range.endContainer : range.endContainer.parentNode && range.endContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.endContainer.parentNode : undefined;\n\n if (!endContainerElement) {\n return undefined;\n }\n\n var endContainerChildTextNodeIndex = endIsElement ? -1 : Array.from(endContainerElement.childNodes).indexOf(range.endContainer);\n\n if (endContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var endContainerElementCssSelector = getCssSelector(endContainerElement);\n var commonElementAncestor = getCommonAncestorElement(range.startContainer, range.endContainer);\n\n if (!commonElementAncestor) {\n console.log("^^^ NO RANGE COMMON ANCESTOR?!");\n return undefined;\n }\n\n if (range.commonAncestorContainer) {\n var rangeCommonAncestorElement = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? range.commonAncestorContainer : range.commonAncestorContainer.parentNode;\n\n if (rangeCommonAncestorElement && rangeCommonAncestorElement.nodeType === Node.ELEMENT_NODE) {\n if (commonElementAncestor !== rangeCommonAncestorElement) {\n console.log(">>>>>> COMMON ANCESTOR CONTAINER DIFF??!");\n console.log(getCssSelector(commonElementAncestor));\n console.log(getCssSelector(rangeCommonAncestorElement));\n }\n }\n }\n\n var rootElementCfi = computeElementCFI(commonElementAncestor);\n var startElementCfi = computeElementCFI(startContainerElement);\n var endElementCfi = computeElementCFI(endContainerElement);\n var cfi;\n\n if (rootElementCfi && startElementCfi && endElementCfi) {\n var startElementOrTextCfi = startElementCfi;\n\n if (!startIsElement) {\n var startContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(startContainerElement, range.startContainer);\n startElementOrTextCfi = startElementCfi + "/" + startContainerChildTextNodeIndexForCfi + ":" + range.startOffset;\n } else {\n if (range.startOffset >= 0 && range.startOffset < startContainerElement.childNodes.length) {\n var childNode = startContainerElement.childNodes[range.startOffset];\n\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (range.startOffset + 1) * 2;\n } else {\n var cfiTextNodeIndex = getChildTextNodeCfiIndex(startContainerElement, childNode);\n startElementOrTextCfi = startElementCfi + "/" + cfiTextNodeIndex;\n }\n } else {\n var cfiIndexOfLastElement = startContainerElement.childElementCount * 2;\n var lastChildNode = startContainerElement.childNodes[startContainerElement.childNodes.length - 1];\n\n if (lastChildNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 1);\n } else {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 2);\n }\n }\n }\n\n var endElementOrTextCfi = endElementCfi;\n\n if (!endIsElement) {\n var endContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(endContainerElement, range.endContainer);\n endElementOrTextCfi = endElementCfi + "/" + endContainerChildTextNodeIndexForCfi + ":" + range.endOffset;\n } else {\n if (range.endOffset >= 0 && range.endOffset < endContainerElement.childNodes.length) {\n var _childNode = endContainerElement.childNodes[range.endOffset];\n\n if (_childNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (range.endOffset + 1) * 2;\n } else {\n var _cfiTextNodeIndex = getChildTextNodeCfiIndex(endContainerElement, _childNode);\n\n endElementOrTextCfi = endElementCfi + "/" + _cfiTextNodeIndex;\n }\n } else {\n var _cfiIndexOfLastElement = endContainerElement.childElementCount * 2;\n\n var _lastChildNode = endContainerElement.childNodes[endContainerElement.childNodes.length - 1];\n\n if (_lastChildNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 1);\n } else {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 2);\n }\n }\n }\n\n cfi = rootElementCfi + "," + startElementOrTextCfi.replace(rootElementCfi, "") + "," + endElementOrTextCfi.replace(rootElementCfi, "");\n }\n\n return {\n cfi: cfi,\n endContainerChildTextNodeIndex: endContainerChildTextNodeIndex,\n endContainerElementCssSelector: endContainerElementCssSelector,\n endOffset: range.endOffset,\n startContainerChildTextNodeIndex: startContainerChildTextNodeIndex,\n startContainerElementCssSelector: startContainerElementCssSelector,\n startOffset: range.startOffset\n };\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n console.log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n console.log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\n\nfunction frameForHighlightAnnotationMarkWithID(win, id) {\n var clientRects = frameForHighlightWithID(id);\n if (!clientRects) return;\n var topClientRect = clientRects[0];\n var maxHeight = topClientRect.height;\n\n var _iterator18 = highlight_createForOfIteratorHelper(clientRects),\n _step18;\n\n try {\n for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {\n var clientRect = _step18.value;\n if (clientRect.top < topClientRect.top) topClientRect = clientRect;\n if (clientRect.height > maxHeight) maxHeight = clientRect.height;\n }\n } catch (err) {\n _iterator18.e(err);\n } finally {\n _iterator18.f();\n }\n\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var newTop = topClientRect.top;\n\n if (_highlightsContainer) {\n do {\n var boundingAreas = document.getElementsByClassName(CLASS_ANNOTATION_BOUNDING_AREA);\n var found = false; //for (let i = 0, length = boundingAreas.snapshotLength; i < length; ++i) {\n\n for (var i = 0, len = boundingAreas.length | 0; i < len; i = i + 1 | 0) {\n var boundingArea = boundingAreas[i];\n\n if (Math.abs(boundingArea.rect.top - (newTop - yOffset)) < 3) {\n newTop += boundingArea.rect.height;\n found = true;\n break;\n }\n }\n } while (found);\n }\n\n topClientRect.top = newTop;\n topClientRect.height = maxHeight;\n return topClientRect;\n}\n\nfunction highlightWithID(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n return highlight;\n}\n\nfunction frameForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n return clientRects;\n}\n\nfunction rangeInfo2Location(rangeInfo) {\n return {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n partialCfi: rangeInfo.cfi,\n domRange: {\n start: {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n textNodeIndex: rangeInfo.startContainerChildTextNodeIndex,\n offset: rangeInfo.startOffset\n },\n end: {\n cssSelector: rangeInfo.endContainerElementCssSelector,\n textNodeIndex: rangeInfo.endContainerChildTextNodeIndex,\n offset: rangeInfo.endOffset\n }\n }\n };\n}\n\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n cfi: location.partialCfi,\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction rectangleForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRects[0].left,\n width: clientRects[0].width,\n top: clientRects[0].top,\n height: clientRects[0].height\n };\n return size;\n}\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n var clientRect = range.getBoundingClientRect();\n var handleBounds = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRect.left,\n width: clientRect.width,\n top: clientRect.top,\n height: clientRect.height\n };\n return handleBounds;\n } catch (e) {\n return null;\n }\n}\nfunction setScrollMode(flag) {\n if (!flag) {\n document.documentElement.classList.add(CLASS_PAGINATED);\n } else {\n document.documentElement.classList.remove(CLASS_PAGINATED);\n }\n}\n/*\n if (document.addEventListener) { // IE >= 9; other browsers\n document.addEventListener(\'contextmenu\', function(e) {\n //alert("You\'ve tried to open context menu"); //here you draw your own menu\n //e.preventDefault();\n //let getCssSelector = fullQualifiedSelector;\n \n\t\t\tlet str = window.getSelection();\n\t\t\tlet selectionInfo = getCurrentSelectionInfo();\n\t\t\tlet pos = createHighlight(selectionInfo,{red:10,green:50,blue:230},true);\n\t\t\tlet ret2 = createAnnotation(pos.id);\n\t\t\t\n }, false);\n } else { // IE < 9\n document.attachEvent(\'oncontextmenu\', function() {\n alert("You\'ve tried to open context menu");\n window.event.returnValue = false;\n });\n }\n*/\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = selection_getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction selection_getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : selection_createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction selection_createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction selection_convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return selection_createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction selection_location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n}; // Legacy highlights API.\n\nwindow.createAnnotation = createAnnotation;\nwindow.createHighlight = createHighlight;\nwindow.destroyHighlight = destroyHighlight;\nwindow.getCurrentSelectionInfo = getCurrentSelectionInfo;\nwindow.getSelectionRect = getSelectionRect;\nwindow.rectangleForHighlightWithID = rectangleForHighlightWithID;\nwindow.setScrollMode = setScrollMode;\n;// CONCATENATED MODULE: ./src/index-reflowable.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for reflowable resources.\n\nwindow.readium.isReflowable = true;\ndocument.addEventListener("DOMContentLoaded", function () {\n // Setups the `viewport` meta tag to disable zooming.\n var meta = document.createElement("meta");\n meta.setAttribute("name", "viewport");\n meta.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no");\n document.head.appendChild(meta);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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a0IsTUFBbEIsRUFBMEIsVUFBMUI7QUFDQWdSLEVBQUFBLElBQUksQ0FBQ2hSLFlBQUwsQ0FDRSxTQURGLEVBRUUsOEZBRkY7QUFJQXBFLEVBQUFBLFFBQVEsQ0FBQ3lwQixJQUFULENBQWNqbEIsV0FBZCxDQUEwQjRRLElBQTFCO0FBQ0QsQ0FURCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL21hdGNoLXF1b3RlLmpzP2RkNmEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZS5qcz9mZGVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzLmpzPzQwMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy91dGlscy5qcz8wMjVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvcmVjdC5qcz80ZDVhIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZGVjb3JhdG9yLmpzPzFiMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kb20uanM/Y2JmMCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2dlc3R1cmVzLmpzPzE0YzIiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9rZXlib2FyZC5qcz8xOGUzIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaGlnaGxpZ2h0LmpzPzhkYTgiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9zZWxlY3Rpb24uanM/NTlhYyIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LmpzP2I2MzUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9pbmRleC1yZWZsb3dhYmxlLmpzPzM5MjUiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFwcHJveFNlYXJjaCBmcm9tICdhcHByb3gtc3RyaW5nLW1hdGNoJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHByb3gtc3RyaW5nLW1hdGNoJykuTWF0Y2h9IFN0cmluZ01hdGNoXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBNYXRjaFxuICogQHByb3Age251bWJlcn0gc3RhcnQgLSBTdGFydCBvZmZzZXQgb2YgbWF0Y2ggaW4gdGV4dFxuICogQHByb3Age251bWJlcn0gZW5kIC0gRW5kIG9mZnNldCBvZiBtYXRjaCBpbiB0ZXh0XG4gKiBAcHJvcCB7bnVtYmVyfSBzY29yZSAtXG4gKiAgIFNjb3JlIGZvciB0aGUgbWF0Y2ggYmV0d2VlbiAwIGFuZCAxLjAsIHdoZXJlIDEuMCBpbmRpY2F0ZXMgYSBwZXJmZWN0IG1hdGNoXG4gKiAgIGZvciB0aGUgcXVvdGUgYW5kIGNvbnRleHQuXG4gKi9cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoZXMgZm9yIGBzdHJgIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhFcnJvcnNcbiAqIEByZXR1cm4ge1N0cmluZ01hdGNoW119XG4gKi9cbmZ1bmN0aW9uIHNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycykge1xuICAvLyBEbyBhIGZhc3Qgc2VhcmNoIGZvciBleGFjdCBtYXRjaGVzLiBUaGUgYGFwcHJveC1zdHJpbmctbWF0Y2hgIGxpYnJhcnlcbiAgLy8gZG9lc24ndCBjdXJyZW50bHkgaW5jb3Jwb3JhdGUgdGhpcyBvcHRpbWl6YXRpb24gaXRzZWxmLlxuICBsZXQgbWF0Y2hQb3MgPSAwO1xuICBsZXQgZXhhY3RNYXRjaGVzID0gW107XG4gIHdoaWxlIChtYXRjaFBvcyAhPT0gLTEpIHtcbiAgICBtYXRjaFBvcyA9IHRleHQuaW5kZXhPZihzdHIsIG1hdGNoUG9zKTtcbiAgICBpZiAobWF0Y2hQb3MgIT09IC0xKSB7XG4gICAgICBleGFjdE1hdGNoZXMucHVzaCh7XG4gICAgICAgIHN0YXJ0OiBtYXRjaFBvcyxcbiAgICAgICAgZW5kOiBtYXRjaFBvcyArIHN0ci5sZW5ndGgsXG4gICAgICAgIGVycm9yczogMCxcbiAgICAgIH0pO1xuICAgICAgbWF0Y2hQb3MgKz0gMTtcbiAgICB9XG4gIH1cbiAgaWYgKGV4YWN0TWF0Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGV4YWN0TWF0Y2hlcztcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBubyBleGFjdCBtYXRjaGVzLCBkbyBhIG1vcmUgZXhwZW5zaXZlIHNlYXJjaCBmb3IgbWF0Y2hlc1xuICAvLyB3aXRoIGVycm9ycy5cbiAgcmV0dXJuIGFwcHJveFNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycyk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSBhIHNjb3JlIGJldHdlZW4gMCBhbmQgMS4wIGZvciB0aGUgc2ltaWxhcml0eSBiZXR3ZWVuIGB0ZXh0YCBhbmQgYHN0cmAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqL1xuZnVuY3Rpb24gdGV4dE1hdGNoU2NvcmUodGV4dCwgc3RyKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0IC0gYHNjb3JlTWF0Y2hgIHdpbGwgbmV2ZXIgcGFzcyBhbiBlbXB0eSBzdHJpbmcgKi9cbiAgaWYgKHN0ci5sZW5ndGggPT09IDAgfHwgdGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gMC4wO1xuICB9XG4gIGNvbnN0IG1hdGNoZXMgPSBzZWFyY2godGV4dCwgc3RyLCBzdHIubGVuZ3RoKTtcblxuICAvLyBwcmV0dGllci1pZ25vcmVcbiAgcmV0dXJuIDEgLSAobWF0Y2hlc1swXS5lcnJvcnMgLyBzdHIubGVuZ3RoKTtcbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoIGZvciBgcXVvdGVgIGluIGB0ZXh0YC5cbiAqXG4gKiBSZXR1cm5zIGBudWxsYCBpZiBubyBtYXRjaCBleGNlZWRpbmcgdGhlIG1pbmltdW0gcXVhbGl0eSB0aHJlc2hvbGQgd2FzIGZvdW5kLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gRG9jdW1lbnQgdGV4dCB0byBzZWFyY2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBxdW90ZSAtIFN0cmluZyB0byBmaW5kIHdpdGhpbiBgdGV4dGBcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC1cbiAqICAgQ29udGV4dCBpbiB3aGljaCB0aGUgcXVvdGUgb3JpZ2luYWxseSBhcHBlYXJlZC4gVGhpcyBpcyB1c2VkIHRvIGNob29zZSB0aGVcbiAqICAgYmVzdCBtYXRjaC5cbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnByZWZpeF0gLSBFeHBlY3RlZCB0ZXh0IGJlZm9yZSB0aGUgcXVvdGVcbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnN1ZmZpeF0gLSBFeHBlY3RlZCB0ZXh0IGFmdGVyIHRoZSBxdW90ZVxuICogICBAcGFyYW0ge251bWJlcn0gW2NvbnRleHQuaGludF0gLSBFeHBlY3RlZCBvZmZzZXQgb2YgbWF0Y2ggd2l0aGluIHRleHRcbiAqIEByZXR1cm4ge01hdGNofG51bGx9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaFF1b3RlKHRleHQsIHF1b3RlLCBjb250ZXh0ID0ge30pIHtcbiAgaWYgKHF1b3RlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQ2hvb3NlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBlcnJvcnMgdG8gYWxsb3cgZm9yIHRoZSBpbml0aWFsIHNlYXJjaC5cbiAgLy8gVGhpcyBjaG9pY2UgaW52b2x2ZXMgYSB0cmFkZW9mZiBiZXR3ZWVuOlxuICAvL1xuICAvLyAgLSBSZWNhbGwgKHByb3BvcnRpb24gb2YgXCJnb29kXCIgbWF0Y2hlcyBmb3VuZClcbiAgLy8gIC0gUHJlY2lzaW9uIChwcm9wb3J0aW9uIG9mIG1hdGNoZXMgZm91bmQgd2hpY2ggYXJlIFwiZ29vZFwiKVxuICAvLyAgLSBDb3N0IG9mIHRoZSBpbml0aWFsIHNlYXJjaCBhbmQgb2YgcHJvY2Vzc2luZyB0aGUgY2FuZGlkYXRlIG1hdGNoZXMgWzFdXG4gIC8vXG4gIC8vIFsxXSBTcGVjaWZpY2FsbHksIHRoZSBleHBlY3RlZC10aW1lIGNvbXBsZXhpdHkgb2YgdGhlIGluaXRpYWwgc2VhcmNoIGlzXG4gIC8vICAgICBgTygobWF4RXJyb3JzIC8gMzIpICogdGV4dC5sZW5ndGgpYC4gU2VlIGBhcHByb3gtc3RyaW5nLW1hdGNoYCBkb2NzLlxuICBjb25zdCBtYXhFcnJvcnMgPSBNYXRoLm1pbigyNTYsIHF1b3RlLmxlbmd0aCAvIDIpO1xuXG4gIC8vIEZpbmQgY2xvc2VzdCBtYXRjaGVzIGZvciBgcXVvdGVgIGluIGB0ZXh0YCBiYXNlZCBvbiBlZGl0IGRpc3RhbmNlLlxuICBjb25zdCBtYXRjaGVzID0gc2VhcmNoKHRleHQsIHF1b3RlLCBtYXhFcnJvcnMpO1xuXG4gIGlmIChtYXRjaGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEuMCBmb3IgYSBtYXRjaCBjYW5kaWRhdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nTWF0Y2h9IG1hdGNoXG4gICAqL1xuICBjb25zdCBzY29yZU1hdGNoID0gbWF0Y2ggPT4ge1xuICAgIGNvbnN0IHF1b3RlV2VpZ2h0ID0gNTA7IC8vIFNpbWlsYXJpdHkgb2YgbWF0Y2hlZCB0ZXh0IHRvIHF1b3RlLlxuICAgIGNvbnN0IHByZWZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYmVmb3JlIG1hdGNoZWQgdGV4dCB0byBgY29udGV4dC5wcmVmaXhgLlxuICAgIGNvbnN0IHN1ZmZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYWZ0ZXIgbWF0Y2hlZCB0ZXh0IHRvIGBjb250ZXh0LnN1ZmZpeGAuXG4gICAgY29uc3QgcG9zV2VpZ2h0ID0gMjsgLy8gUHJveGltaXR5IHRvIGV4cGVjdGVkIGxvY2F0aW9uLiBVc2VkIGFzIGEgdGllLWJyZWFrZXIuXG5cbiAgICBjb25zdCBxdW90ZVNjb3JlID0gMSAtIG1hdGNoLmVycm9ycyAvIHF1b3RlLmxlbmd0aDtcblxuICAgIGNvbnN0IHByZWZpeFNjb3JlID0gY29udGV4dC5wcmVmaXhcbiAgICAgID8gdGV4dE1hdGNoU2NvcmUoXG4gICAgICAgICAgdGV4dC5zbGljZShNYXRoLm1heCgwLCBtYXRjaC5zdGFydCAtIGNvbnRleHQucHJlZml4Lmxlbmd0aCksIG1hdGNoLnN0YXJ0KSxcbiAgICAgICAgICBjb250ZXh0LnByZWZpeFxuICAgICAgICApXG4gICAgICA6IDEuMDtcbiAgICBjb25zdCBzdWZmaXhTY29yZSA9IGNvbnRleHQuc3VmZml4XG4gICAgICA/IHRleHRNYXRjaFNjb3JlKFxuICAgICAgICAgIHRleHQuc2xpY2UobWF0Y2guZW5kLCBtYXRjaC5lbmQgKyBjb250ZXh0LnN1ZmZpeC5sZW5ndGgpLFxuICAgICAgICAgIGNvbnRleHQuc3VmZml4XG4gICAgICAgIClcbiAgICAgIDogMS4wO1xuXG4gICAgbGV0IHBvc1Njb3JlID0gMS4wO1xuICAgIGlmICh0eXBlb2YgY29udGV4dC5oaW50ID09PSAnbnVtYmVyJykge1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5hYnMobWF0Y2guc3RhcnQgLSBjb250ZXh0LmhpbnQpO1xuICAgICAgcG9zU2NvcmUgPSAxLjAgLSBvZmZzZXQgLyB0ZXh0Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBjb25zdCByYXdTY29yZSA9XG4gICAgICBxdW90ZVdlaWdodCAqIHF1b3RlU2NvcmUgK1xuICAgICAgcHJlZml4V2VpZ2h0ICogcHJlZml4U2NvcmUgK1xuICAgICAgc3VmZml4V2VpZ2h0ICogc3VmZml4U2NvcmUgK1xuICAgICAgcG9zV2VpZ2h0ICogcG9zU2NvcmU7XG4gICAgY29uc3QgbWF4U2NvcmUgPSBxdW90ZVdlaWdodCArIHByZWZpeFdlaWdodCArIHN1ZmZpeFdlaWdodCArIHBvc1dlaWdodDtcbiAgICBjb25zdCBub3JtYWxpemVkU2NvcmUgPSByYXdTY29yZSAvIG1heFNjb3JlO1xuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRTY29yZTtcbiAgfTtcblxuICAvLyBSYW5rIG1hdGNoZXMgYmFzZWQgb24gc2ltaWxhcml0eSBvZiBhY3R1YWwgYW5kIGV4cGVjdGVkIHN1cnJvdW5kaW5nIHRleHRcbiAgLy8gYW5kIGFjdHVhbC9leHBlY3RlZCBvZmZzZXQgaW4gdGhlIGRvY3VtZW50IHRleHQuXG4gIGNvbnN0IHNjb3JlZE1hdGNoZXMgPSBtYXRjaGVzLm1hcChtID0+ICh7XG4gICAgc3RhcnQ6IG0uc3RhcnQsXG4gICAgZW5kOiBtLmVuZCxcbiAgICBzY29yZTogc2NvcmVNYXRjaChtKSxcbiAgfSkpO1xuXG4gIC8vIENob29zZSBtYXRjaCB3aXRoIGhpZ2hlc3Qgc2NvcmUuXG4gIHNjb3JlZE1hdGNoZXMuc29ydCgoYSwgYikgPT4gYi5zY29yZSAtIGEuc2NvcmUpO1xuICByZXR1cm4gc2NvcmVkTWF0Y2hlc1swXTtcbn1cbiIsIi8qKlxuICogUmV0dXJuIHRoZSBjb21iaW5lZCBsZW5ndGggb2YgdGV4dCBub2RlcyBjb250YWluZWQgaW4gYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICovXG5mdW5jdGlvbiBub2RlVGV4dExlbmd0aChub2RlKSB7XG4gIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgIC8vIG5iLiBgdGV4dENvbnRlbnRgIGV4Y2x1ZGVzIHRleHQgaW4gY29tbWVudHMgYW5kIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zXG4gICAgICAvLyB3aGVuIGNhbGxlZCBvbiBhIHBhcmVudCBlbGVtZW50LCBzbyB3ZSBkb24ndCBuZWVkIHRvIHN1YnRyYWN0IHRoYXQgaGVyZS5cblxuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobm9kZS50ZXh0Q29udGVudCkubGVuZ3RoO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gMDtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgdG90YWwgbGVuZ3RoIG9mIHRoZSB0ZXh0IG9mIGFsbCBwcmV2aW91cyBzaWJsaW5ncyBvZiBgbm9kZWAuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKi9cbmZ1bmN0aW9uIHByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoKG5vZGUpIHtcbiAgbGV0IHNpYmxpbmcgPSBub2RlLnByZXZpb3VzU2libGluZztcbiAgbGV0IGxlbmd0aCA9IDA7XG4gIHdoaWxlIChzaWJsaW5nKSB7XG4gICAgbGVuZ3RoICs9IG5vZGVUZXh0TGVuZ3RoKHNpYmxpbmcpO1xuICAgIHNpYmxpbmcgPSBzaWJsaW5nLnByZXZpb3VzU2libGluZztcbiAgfVxuICByZXR1cm4gbGVuZ3RoO1xufVxuXG4vKipcbiAqIFJlc29sdmUgb25lIG9yIG1vcmUgY2hhcmFjdGVyIG9mZnNldHMgd2l0aGluIGFuIGVsZW1lbnQgdG8gKHRleHQgbm9kZSwgcG9zaXRpb24pXG4gKiBwYWlycy5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyW119IG9mZnNldHMgLSBPZmZzZXRzLCB3aGljaCBtdXN0IGJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXJcbiAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfVtdfVxuICovXG5mdW5jdGlvbiByZXNvbHZlT2Zmc2V0cyhlbGVtZW50LCAuLi5vZmZzZXRzKSB7XG4gIGxldCBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICBjb25zdCBub2RlSXRlciA9IC8qKiBAdHlwZSB7RG9jdW1lbnR9ICovIChcbiAgICBlbGVtZW50Lm93bmVyRG9jdW1lbnRcbiAgKS5jcmVhdGVOb2RlSXRlcmF0b3IoZWxlbWVudCwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuICBjb25zdCByZXN1bHRzID0gW107XG5cbiAgbGV0IGN1cnJlbnROb2RlID0gbm9kZUl0ZXIubmV4dE5vZGUoKTtcbiAgbGV0IHRleHROb2RlO1xuICBsZXQgbGVuZ3RoID0gMDtcblxuICAvLyBGaW5kIHRoZSB0ZXh0IG5vZGUgY29udGFpbmluZyB0aGUgYG5leHRPZmZzZXRgdGggY2hhcmFjdGVyIGZyb20gdGhlIHN0YXJ0XG4gIC8vIG9mIGBlbGVtZW50YC5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50Tm9kZSkge1xuICAgIHRleHROb2RlID0gLyoqIEB0eXBlIHtUZXh0fSAqLyAoY3VycmVudE5vZGUpO1xuICAgIGlmIChsZW5ndGggKyB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCA+IG5leHRPZmZzZXQpIHtcbiAgICAgIHJlc3VsdHMucHVzaCh7IG5vZGU6IHRleHROb2RlLCBvZmZzZXQ6IG5leHRPZmZzZXQgLSBsZW5ndGggfSk7XG4gICAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IG5vZGVJdGVyLm5leHROb2RlKCk7XG4gICAgICBsZW5ndGggKz0gdGV4dE5vZGUuZGF0YS5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgLy8gQm91bmRhcnkgY2FzZS5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiB0ZXh0Tm9kZSAmJiBsZW5ndGggPT09IG5leHRPZmZzZXQpIHtcbiAgICByZXN1bHRzLnB1c2goeyBub2RlOiB0ZXh0Tm9kZSwgb2Zmc2V0OiB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCB9KTtcbiAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICB9XG5cbiAgaWYgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPZmZzZXQgZXhjZWVkcyB0ZXh0IGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmV4cG9ydCBsZXQgUkVTT0xWRV9GT1JXQVJEUyA9IDE7XG5leHBvcnQgbGV0IFJFU09MVkVfQkFDS1dBUkRTID0gMjtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIG9mZnNldCB3aXRoaW4gdGhlIHRleHQgY29udGVudCBvZiBhbiBlbGVtZW50LlxuICpcbiAqIFRoaXMgcG9zaXRpb24gY2FuIGJlIHJlc29sdmVkIHRvIGEgc3BlY2lmaWMgZGVzY2VuZGFudCBub2RlIGluIHRoZSBjdXJyZW50XG4gKiBET00gc3VidHJlZSBvZiB0aGUgZWxlbWVudCB1c2luZyB0aGUgYHJlc29sdmVgIG1ldGhvZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbiB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgdGV4dCBwb3NpdGlvbiBgb2Zmc2V0YCB3aXRoaW5cbiAgICogdGhlIHRleHQgY29udGVudCBvZiBgZWxlbWVudGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvZmZzZXQpIHtcbiAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPZmZzZXQgaXMgaW52YWxpZCcpO1xuICAgIH1cblxuICAgIC8qKiBFbGVtZW50IHRoYXQgYG9mZnNldGAgaXMgcmVsYXRpdmUgdG8uICovXG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIC8qKiBDaGFyYWN0ZXIgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBlbGVtZW50J3MgYHRleHRDb250ZW50YC4gKi9cbiAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgcG9zaXRpb24gd2l0aCBvZmZzZXQgcmVsYXRpdmUgdG8gYSBnaXZlbiBhbmNlc3RvclxuICAgKiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHBhcmVudCAtIEFuY2VzdG9yIG9mIGB0aGlzLmVsZW1lbnRgXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHJlbGF0aXZlVG8ocGFyZW50KSB7XG4gICAgaWYgKCFwYXJlbnQuY29udGFpbnModGhpcy5lbGVtZW50KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJlbnQgaXMgbm90IGFuIGFuY2VzdG9yIG9mIGN1cnJlbnQgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIGxldCBlbCA9IHRoaXMuZWxlbWVudDtcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgd2hpbGUgKGVsICE9PSBwYXJlbnQpIHtcbiAgICAgIG9mZnNldCArPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChlbCk7XG4gICAgICBlbCA9IC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKGVsLnBhcmVudEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKGVsLCBvZmZzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIHBvc2l0aW9uIHRvIGEgc3BlY2lmaWMgdGV4dCBub2RlIGFuZCBvZmZzZXQgd2l0aGluIHRoYXQgbm9kZS5cbiAgICpcbiAgICogVGhyb3dzIGlmIGB0aGlzLm9mZnNldGAgZXhjZWVkcyB0aGUgbGVuZ3RoIG9mIHRoZSBlbGVtZW50J3MgdGV4dC4gSW4gdGhlXG4gICAqIGNhc2Ugd2hlcmUgdGhlIGVsZW1lbnQgaGFzIG5vIHRleHQgYW5kIGB0aGlzLm9mZnNldGAgaXMgMCwgdGhlIGBkaXJlY3Rpb25gXG4gICAqIG9wdGlvbiBkZXRlcm1pbmVzIHdoYXQgaGFwcGVucy5cbiAgICpcbiAgICogT2Zmc2V0cyBhdCB0aGUgYm91bmRhcnkgYmV0d2VlbiB0d28gbm9kZXMgYXJlIHJlc29sdmVkIHRvIHRoZSBzdGFydCBvZiB0aGVcbiAgICogbm9kZSB0aGF0IGJlZ2lucyBhdCB0aGUgYm91bmRhcnkuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBAcGFyYW0ge1JFU09MVkVfRk9SV0FSRFN8UkVTT0xWRV9CQUNLV0FSRFN9IFtvcHRpb25zLmRpcmVjdGlvbl0gLVxuICAgKiAgICAgU3BlY2lmaWVzIGluIHdoaWNoIGRpcmVjdGlvbiB0byBzZWFyY2ggZm9yIHRoZSBuZWFyZXN0IHRleHQgbm9kZSBpZlxuICAgKiAgICAgYHRoaXMub2Zmc2V0YCBpcyBgMGAgYW5kIGB0aGlzLmVsZW1lbnRgIGhhcyBubyB0ZXh0LiBJZiBub3Qgc3BlY2lmaWVkXG4gICAqICAgICBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfX1cbiAgICogQHRocm93cyB7UmFuZ2VFcnJvcn1cbiAgICovXG4gIHJlc29sdmUob3B0aW9ucyA9IHt9KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiByZXNvbHZlT2Zmc2V0cyh0aGlzLmVsZW1lbnQsIHRoaXMub2Zmc2V0KVswXTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmICh0aGlzLm9mZnNldCA9PT0gMCAmJiBvcHRpb25zLmRpcmVjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHR3ID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVFxuICAgICAgICApO1xuICAgICAgICB0dy5jdXJyZW50Tm9kZSA9IHRoaXMuZWxlbWVudDtcbiAgICAgICAgY29uc3QgZm9yd2FyZHMgPSBvcHRpb25zLmRpcmVjdGlvbiA9PT0gUkVTT0xWRV9GT1JXQVJEUztcbiAgICAgICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7VGV4dHxudWxsfSAqLyAoXG4gICAgICAgICAgZm9yd2FyZHMgPyB0dy5uZXh0Tm9kZSgpIDogdHcucHJldmlvdXNOb2RlKClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHRleHQsIG9mZnNldDogZm9yd2FyZHMgPyAwIDogdGV4dC5kYXRhLmxlbmd0aCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgYG9mZnNldGB0aCBjaGFyYWN0ZXIgd2l0aGluXG4gICAqIGBub2RlYC5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7VGV4dFBvc2l0aW9ufVxuICAgKi9cbiAgc3RhdGljIGZyb21DaGFyT2Zmc2V0KG5vZGUsIG9mZnNldCkge1xuICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgICAgcmV0dXJuIFRleHRQb3NpdGlvbi5mcm9tUG9pbnQobm9kZSwgb2Zmc2V0KTtcbiAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCBvZmZzZXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb2RlIGlzIG5vdCBhbiBlbGVtZW50IG9yIHRleHQgbm9kZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCByZXByZXNlbnRpbmcgdGhlIHJhbmdlIHN0YXJ0IG9yIGVuZCBwb2ludCAobm9kZSwgb2Zmc2V0KS5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlIC0gVGV4dCBvciBFbGVtZW50IG5vZGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCAtIE9mZnNldCB3aXRoaW4gdGhlIG5vZGUuXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tUG9pbnQobm9kZSwgb2Zmc2V0KSB7XG4gICAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7XG4gICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOiB7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IC8qKiBAdHlwZSB7VGV4dH0gKi8gKG5vZGUpLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IG5vZGUgb2Zmc2V0IGlzIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFub2RlLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RleHQgbm9kZSBoYXMgbm8gcGFyZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcGFyZW50IGVsZW1lbnQuXG4gICAgICAgIGNvbnN0IHRleHRPZmZzZXQgPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChub2RlKSArIG9mZnNldDtcblxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbihub2RlLnBhcmVudEVsZW1lbnQsIHRleHRPZmZzZXQpO1xuICAgICAgfVxuICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERToge1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBub2RlIG9mZnNldCBpcyBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgdGV4dCBsZW5ndGggYmVmb3JlIHRoZSBgb2Zmc2V0YHRoIGNoaWxkIG9mIGVsZW1lbnQuXG4gICAgICAgIGxldCB0ZXh0T2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvZmZzZXQ7IGkrKykge1xuICAgICAgICAgIHRleHRPZmZzZXQgKz0gbm9kZVRleHRMZW5ndGgobm9kZS5jaGlsZE5vZGVzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCB0ZXh0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUG9pbnQgaXMgbm90IGluIGFuIGVsZW1lbnQgb3IgdGV4dCBub2RlJyk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHJlZ2lvbiBvZiBhIGRvY3VtZW50IGFzIGEgKHN0YXJ0LCBlbmQpIHBhaXIgb2YgYFRleHRQb3NpdGlvbmAgcG9pbnRzLlxuICpcbiAqIFJlcHJlc2VudGluZyBhIHJhbmdlIGluIHRoaXMgd2F5IGFsbG93cyBmb3IgY2hhbmdlcyBpbiB0aGUgRE9NIGNvbnRlbnQgb2YgdGhlXG4gKiByYW5nZSB3aGljaCBkb24ndCBhZmZlY3QgaXRzIHRleHQgY29udGVudCwgd2l0aG91dCBhZmZlY3RpbmcgdGhlIHRleHQgY29udGVudFxuICogb2YgdGhlIHJhbmdlIGl0c2VsZi5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRSYW5nZSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYW4gaW1tdXRhYmxlIGBUZXh0UmFuZ2VgIGZyb20gYSBgc3RhcnRgIGFuZCBgZW5kYCBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb259IHN0YXJ0XG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9ufSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5lbmQgPSBlbmQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGlzIHJhbmdlIHdpdGggc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgcmVsYXRpdmUgdG8gYVxuICAgKiBnaXZlbiBhbmNlc3Rvci4gU2VlIGBUZXh0UG9zaXRpb24ucmVsYXRpdmVUb2AuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKi9cbiAgcmVsYXRpdmVUbyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2UoXG4gICAgICB0aGlzLnN0YXJ0LnJlbGF0aXZlVG8oZWxlbWVudCksXG4gICAgICB0aGlzLmVuZC5yZWxhdGl2ZVRvKGVsZW1lbnQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBgVGV4dFJhbmdlYCB0byBhIERPTSByYW5nZS5cbiAgICpcbiAgICogVGhlIHJlc3VsdGluZyBET00gUmFuZ2Ugd2lsbCBhbHdheXMgc3RhcnQgYW5kIGVuZCBpbiBhIGBUZXh0YCBub2RlLlxuICAgKiBIZW5jZSBgVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkudG9SYW5nZSgpYCBjYW4gYmUgdXNlZCB0byBcInNocmlua1wiIGFcbiAgICogcmFuZ2UgdG8gdGhlIHRleHQgaXQgY29udGFpbnMuXG4gICAqXG4gICAqIE1heSB0aHJvdyBpZiB0aGUgYHN0YXJ0YCBvciBgZW5kYCBwb3NpdGlvbnMgY2Fubm90IGJlIHJlc29sdmVkIHRvIGEgcmFuZ2UuXG4gICAqXG4gICAqIEByZXR1cm4ge1JhbmdlfVxuICAgKi9cbiAgdG9SYW5nZSgpIHtcbiAgICBsZXQgc3RhcnQ7XG4gICAgbGV0IGVuZDtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhcnQuZWxlbWVudCA9PT0gdGhpcy5lbmQuZWxlbWVudCAmJlxuICAgICAgdGhpcy5zdGFydC5vZmZzZXQgPD0gdGhpcy5lbmQub2Zmc2V0XG4gICAgKSB7XG4gICAgICAvLyBGYXN0IHBhdGggZm9yIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGluIHNhbWUgZWxlbWVudC5cbiAgICAgIFtzdGFydCwgZW5kXSA9IHJlc29sdmVPZmZzZXRzKFxuICAgICAgICB0aGlzLnN0YXJ0LmVsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhcnQub2Zmc2V0LFxuICAgICAgICB0aGlzLmVuZC5vZmZzZXRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0ID0gdGhpcy5zdGFydC5yZXNvbHZlKHsgZGlyZWN0aW9uOiBSRVNPTFZFX0ZPUldBUkRTIH0pO1xuICAgICAgZW5kID0gdGhpcy5lbmQucmVzb2x2ZSh7IGRpcmVjdGlvbjogUkVTT0xWRV9CQUNLV0FSRFMgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgUmFuZ2UoKTtcbiAgICByYW5nZS5zZXRTdGFydChzdGFydC5ub2RlLCBzdGFydC5vZmZzZXQpO1xuICAgIHJhbmdlLnNldEVuZChlbmQubm9kZSwgZW5kLm9mZnNldCk7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYW4gZXhpc3RpbmcgRE9NIGBSYW5nZWAgdG8gYSBgVGV4dFJhbmdlYFxuICAgKlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZVxuICAgKiBAcmV0dXJuIHtUZXh0UmFuZ2V9XG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJhbmdlKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBUZXh0UG9zaXRpb24uZnJvbVBvaW50KFxuICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgICByYW5nZS5zdGFydE9mZnNldFxuICAgICk7XG4gICAgY29uc3QgZW5kID0gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2Uoc3RhcnQsIGVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgYFRleHRSYW5nZWAgZnJvbSB0aGUgYHN0YXJ0YHRoIHRvIGBlbmRgdGggY2hhcmFjdGVycyBpbiBgcm9vdGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZFxuICAgKi9cbiAgc3RhdGljIGZyb21PZmZzZXRzKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gbmV3IFRleHRSYW5nZShcbiAgICAgIG5ldyBUZXh0UG9zaXRpb24ocm9vdCwgc3RhcnQpLFxuICAgICAgbmV3IFRleHRQb3NpdGlvbihyb290LCBlbmQpXG4gICAgKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBUaGlzIG1vZHVsZSBleHBvcnRzIGEgc2V0IG9mIGNsYXNzZXMgZm9yIGNvbnZlcnRpbmcgYmV0d2VlbiBET00gYFJhbmdlYFxuICogb2JqZWN0cyBhbmQgZGlmZmVyZW50IHR5cGVzIG9mIHNlbGVjdG9ycy4gSXQgaXMgbW9zdGx5IGEgdGhpbiB3cmFwcGVyIGFyb3VuZCBhXG4gKiBzZXQgb2YgYW5jaG9yaW5nIGxpYnJhcmllcy4gSXQgc2VydmVzIHR3byBtYWluIHB1cnBvc2VzOlxuICpcbiAqICAxLiBQcm92aWRpbmcgYSBjb25zaXN0ZW50IGludGVyZmFjZSBhY3Jvc3MgZGlmZmVyZW50IHR5cGVzIG9mIGFuY2hvcnMuXG4gKiAgMi4gSW5zdWxhdGluZyB0aGUgcmVzdCBvZiB0aGUgY29kZSBmcm9tIEFQSSBjaGFuZ2VzIGluIHRoZSB1bmRlcmx5aW5nIGFuY2hvcmluZ1xuICogICAgIGxpYnJhcmllcy5cbiAqL1xuXG5pbXBvcnQgeyBtYXRjaFF1b3RlIH0gZnJvbSAnLi9tYXRjaC1xdW90ZSc7XG5pbXBvcnQgeyBUZXh0UmFuZ2UsIFRleHRQb3NpdGlvbiB9IGZyb20gJy4vdGV4dC1yYW5nZSc7XG5pbXBvcnQgeyBub2RlRnJvbVhQYXRoLCB4cGF0aEZyb21Ob2RlIH0gZnJvbSAnLi94cGF0aCc7XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuUmFuZ2VTZWxlY3Rvcn0gUmFuZ2VTZWxlY3RvclxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuVGV4dFBvc2l0aW9uU2VsZWN0b3J9IFRleHRQb3NpdGlvblNlbGVjdG9yXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi8uLi90eXBlcy9hcGknKS5UZXh0UXVvdGVTZWxlY3Rvcn0gVGV4dFF1b3RlU2VsZWN0b3JcbiAqL1xuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgUmFuZ2VBbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtOb2RlfSByb290IC0gQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgcmFuZ2UpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMucmFuZ2UgPSByYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge05vZGV9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyb290LCByYW5nZSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2VBbmNob3Iocm9vdCwgcmFuZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBhbmNob3IgZnJvbSBhIHNlcmlhbGl6ZWQgYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9yLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2VTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IG5vZGVGcm9tWFBhdGgoc2VsZWN0b3Iuc3RhcnRDb250YWluZXIsIHJvb3QpO1xuICAgIGlmICghc3RhcnRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgc3RhcnRDb250YWluZXIgWFBhdGgnKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmRDb250YWluZXIgPSBub2RlRnJvbVhQYXRoKHNlbGVjdG9yLmVuZENvbnRhaW5lciwgcm9vdCk7XG4gICAgaWYgKCFlbmRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgZW5kQ29udGFpbmVyIFhQYXRoJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBzdGFydENvbnRhaW5lcixcbiAgICAgIHNlbGVjdG9yLnN0YXJ0T2Zmc2V0XG4gICAgKTtcbiAgICBjb25zdCBlbmRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBlbmRDb250YWluZXIsXG4gICAgICBzZWxlY3Rvci5lbmRPZmZzZXRcbiAgICApO1xuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgVGV4dFJhbmdlKHN0YXJ0UG9zLCBlbmRQb3MpLnRvUmFuZ2UoKTtcbiAgICByZXR1cm4gbmV3IFJhbmdlQW5jaG9yKHJvb3QsIHJhbmdlKTtcbiAgfVxuXG4gIHRvUmFuZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMucmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7UmFuZ2VTZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgLy8gXCJTaHJpbmtcIiB0aGUgcmFuZ2Ugc28gdGhhdCBpdCB0aWdodGx5IHdyYXBzIGl0cyB0ZXh0LiBUaGlzIGVuc3VyZXMgbW9yZVxuICAgIC8vIHByZWRpY3RhYmxlIG91dHB1dCBmb3IgYSBnaXZlbiB0ZXh0IHNlbGVjdGlvbi5cbiAgICBjb25zdCBub3JtYWxpemVkUmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHRoaXMucmFuZ2UpLnRvUmFuZ2UoKTtcblxuICAgIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2Uobm9ybWFsaXplZFJhbmdlKTtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IHhwYXRoRnJvbU5vZGUodGV4dFJhbmdlLnN0YXJ0LmVsZW1lbnQsIHRoaXMucm9vdCk7XG4gICAgY29uc3QgZW5kQ29udGFpbmVyID0geHBhdGhGcm9tTm9kZSh0ZXh0UmFuZ2UuZW5kLmVsZW1lbnQsIHRoaXMucm9vdCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1JhbmdlU2VsZWN0b3InLFxuICAgICAgc3RhcnRDb250YWluZXIsXG4gICAgICBzdGFydE9mZnNldDogdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldCxcbiAgICAgIGVuZENvbnRhaW5lcixcbiAgICAgIGVuZE9mZnNldDogdGV4dFJhbmdlLmVuZC5vZmZzZXQsXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFRleHRQb3NpdGlvblNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbkFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICB0aGlzLmVuZCA9IGVuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKFxuICAgICAgcm9vdCxcbiAgICAgIHRleHRSYW5nZS5zdGFydC5vZmZzZXQsXG4gICAgICB0ZXh0UmFuZ2UuZW5kLm9mZnNldFxuICAgICk7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvblNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKHJvb3QsIHNlbGVjdG9yLnN0YXJ0LCBzZWxlY3Rvci5lbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvblNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRQb3NpdGlvblNlbGVjdG9yJyxcbiAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0LFxuICAgICAgZW5kOiB0aGlzLmVuZCxcbiAgICB9O1xuICB9XG5cbiAgdG9SYW5nZSgpIHtcbiAgICByZXR1cm4gVGV4dFJhbmdlLmZyb21PZmZzZXRzKHRoaXMucm9vdCwgdGhpcy5zdGFydCwgdGhpcy5lbmQpLnRvUmFuZ2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIFF1b3RlTWF0Y2hPcHRpb25zXG4gKiBAcHJvcCB7bnVtYmVyfSBbaGludF0gLSBFeHBlY3RlZCBwb3NpdGlvbiBvZiBtYXRjaCBpbiB0ZXh0LiBTZWUgYG1hdGNoUXVvdGVgLlxuICovXG5cbi8qKlxuICogQ29udmVydHMgYmV0d2VlbiBgVGV4dFF1b3RlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgVGV4dFF1b3RlQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdCAtIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXhhY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQucHJlZml4XVxuICAgKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5zdWZmaXhdXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCBleGFjdCwgY29udGV4dCA9IHt9KSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLmV4YWN0ID0gZXhhY3Q7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBgVGV4dFF1b3RlQW5jaG9yYCBmcm9tIGEgcmFuZ2UuXG4gICAqXG4gICAqIFdpbGwgdGhyb3cgaWYgYHJhbmdlYCBkb2VzIG5vdCBjb250YWluIGFueSB0ZXh0IG5vZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyb290LnRleHRDb250ZW50KTtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuXG4gICAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICAgIGNvbnN0IGVuZCA9IHRleHRSYW5nZS5lbmQub2Zmc2V0O1xuXG4gICAgLy8gTnVtYmVyIG9mIGNoYXJhY3RlcnMgYXJvdW5kIHRoZSBxdW90ZSB0byBjYXB0dXJlIGFzIGNvbnRleHQuIFdlIGN1cnJlbnRseVxuICAgIC8vIGFsd2F5cyB1c2UgYSBmaXhlZCBhbW91bnQsIGJ1dCBpdCB3b3VsZCBiZSBiZXR0ZXIgaWYgdGhpcyBjb2RlIHdhcyBhd2FyZVxuICAgIC8vIG9mIGxvZ2ljYWwgYm91bmRhcmllcyBpbiB0aGUgZG9jdW1lbnQgKHBhcmFncmFwaCwgYXJ0aWNsZSBldGMuKSB0byBhdm9pZFxuICAgIC8vIGNhcHR1cmluZyB0ZXh0IHVucmVsYXRlZCB0byB0aGUgcXVvdGUuXG4gICAgLy9cbiAgICAvLyBJbiByZWd1bGFyIHByb3NlIHRoZSBpZGVhbCBjb250ZW50IHdvdWxkIG9mdGVuIGJlIHRoZSBzdXJyb3VuZGluZyBzZW50ZW5jZS5cbiAgICAvLyBUaGlzIGlzIGEgbmF0dXJhbCB1bml0IG9mIG1lYW5pbmcgd2hpY2ggZW5hYmxlcyBkaXNwbGF5aW5nIHF1b3RlcyBpblxuICAgIC8vIGNvbnRleHQgZXZlbiB3aGVuIHRoZSBkb2N1bWVudCBpcyBub3QgYXZhaWxhYmxlLiBXZSBjb3VsZCB1c2UgYEludGwuU2VnbWVudGVyYFxuICAgIC8vIGZvciB0aGlzIHdoZW4gYXZhaWxhYmxlLlxuICAgIGNvbnN0IGNvbnRleHRMZW4gPSAzMjtcblxuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHRleHQuc2xpY2Uoc3RhcnQsIGVuZCksIHtcbiAgICAgIHByZWZpeDogdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIGNvbnRleHRMZW4pLCBzdGFydCksXG4gICAgICBzdWZmaXg6IHRleHQuc2xpY2UoZW5kLCBNYXRoLm1pbih0ZXh0Lmxlbmd0aCwgZW5kICsgY29udGV4dExlbikpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRRdW90ZVNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIGNvbnN0IHsgcHJlZml4LCBzdWZmaXggfSA9IHNlbGVjdG9yO1xuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHNlbGVjdG9yLmV4YWN0LCB7IHByZWZpeCwgc3VmZml4IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRRdW90ZVNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRRdW90ZVNlbGVjdG9yJyxcbiAgICAgIGV4YWN0OiB0aGlzLmV4YWN0LFxuICAgICAgcHJlZml4OiB0aGlzLmNvbnRleHQucHJlZml4LFxuICAgICAgc3VmZml4OiB0aGlzLmNvbnRleHQuc3VmZml4LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtRdW90ZU1hdGNoT3B0aW9uc30gW29wdGlvbnNdXG4gICAqL1xuICB0b1JhbmdlKG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnRvUG9zaXRpb25BbmNob3Iob3B0aW9ucykudG9SYW5nZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVvdGVNYXRjaE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKi9cbiAgdG9Qb3NpdGlvbkFuY2hvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovICh0aGlzLnJvb3QudGV4dENvbnRlbnQpO1xuICAgIGNvbnN0IG1hdGNoID0gbWF0Y2hRdW90ZSh0ZXh0LCB0aGlzLmV4YWN0LCB7XG4gICAgICAuLi50aGlzLmNvbnRleHQsXG4gICAgICBoaW50OiBvcHRpb25zLmhpbnQsXG4gICAgfSk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdRdW90ZSBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb25BbmNob3IodGhpcy5yb290LCBtYXRjaC5zdGFydCwgbWF0Y2guZW5kKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgVGV4dFF1b3RlQW5jaG9yIH0gZnJvbSBcIi4vdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzXCI7XG5cbi8vIENhdGNoIEpTIGVycm9ycyB0byBsb2cgdGhlbSBpbiB0aGUgYXBwLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwiZXJyb3JcIixcbiAgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgQW5kcm9pZC5sb2dFcnJvcihldmVudC5tZXNzYWdlLCBldmVudC5maWxlbmFtZSwgZXZlbnQubGluZW5vKTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIG9uVmlld3BvcnRXaWR0aENoYW5nZWQoKTtcbiAgICAgIHNuYXBDdXJyZW50T2Zmc2V0KCk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudC5ib2R5KTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbi8qKlxuICogSGF2aW5nIGFuIG9kZCBudW1iZXIgb2YgY29sdW1ucyB3aGVuIGRpc3BsYXlpbmcgdHdvIGNvbHVtbnMgcGVyIHNjcmVlbiBjYXVzZXMgc25hcHBpbmcgYW5kIHBhZ2VcbiAqIHR1cm5pbmcgaXNzdWVzLiBUbyBmaXggdGhpcywgd2UgaW5zZXJ0IGEgYmxhbmsgdmlydHVhbCBjb2x1bW4gYXQgdGhlIGVuZCBvZiB0aGUgcmVzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGFwcGVuZFZpcnR1YWxDb2x1bW5JZk5lZWRlZCgpIHtcbiAgY29uc3QgaWQgPSBcInJlYWRpdW0tdmlydHVhbC1wYWdlXCI7XG4gIHZhciB2aXJ0dWFsQ29sID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHx8IGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkgIT0gMikge1xuICAgIGlmICh2aXJ0dWFsQ29sKSB7XG4gICAgICB2aXJ0dWFsQ29sLnJlbW92ZSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGNvbENvdW50ID0gZG9jdW1lbnRXaWR0aCAvIHBhZ2VXaWR0aDtcbiAgICB2YXIgaGFzT2RkQ29sQ291bnQgPSAoTWF0aC5yb3VuZChjb2xDb3VudCAqIDIpIC8gMikgJSAxID4gMC4xO1xuICAgIGlmIChoYXNPZGRDb2xDb3VudCkge1xuICAgICAgaWYgKHZpcnR1YWxDb2wpIHtcbiAgICAgICAgdmlydHVhbENvbC5yZW1vdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpcnR1YWxDb2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICB2aXJ0dWFsQ29sLnNldEF0dHJpYnV0ZShcImlkXCIsIGlkKTtcbiAgICAgICAgdmlydHVhbENvbC5zdHlsZS5icmVha0JlZm9yZSA9IFwiY29sdW1uXCI7XG4gICAgICAgIHZpcnR1YWxDb2wuaW5uZXJIVE1MID0gXCImIzgyMDM7XCI7IC8vIHplcm8td2lkdGggc3BhY2VcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh2aXJ0dWFsQ29sKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHZhciBwYWdlV2lkdGggPSAxO1xuXG5mdW5jdGlvbiBvblZpZXdwb3J0V2lkdGhDaGFuZ2VkKCkge1xuICAvLyBXZSBjYW4ndCByZWx5IG9uIHdpbmRvdy5pbm5lcldpZHRoIGZvciB0aGUgcGFnZVdpZHRoIG9uIEFuZHJvaWQsIGJlY2F1c2UgaWYgdGhlXG4gIC8vIGRldmljZSBwaXhlbCByYXRpbyBpcyBub3QgYW4gaW50ZWdlciwgd2UgZ2V0IHJvdW5kaW5nIGlzc3VlcyBvZmZzZXR0aW5nIHRoZSBwYWdlcy5cbiAgLy9cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFkaXVtL3JlYWRpdW0tY3NzL2lzc3Vlcy85N1xuICAvLyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL3JlYWRpdW0vcjItbmF2aWdhdG9yLWtvdGxpbi9pc3N1ZXMvMTQ2XG4gIHZhciB3aWR0aCA9IEFuZHJvaWQuZ2V0Vmlld3BvcnRXaWR0aCgpO1xuICBwYWdlV2lkdGggPSB3aWR0aCAvIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBzZXRQcm9wZXJ0eShcbiAgICBcIi0tUlNfX3ZpZXdwb3J0V2lkdGhcIixcbiAgICBcImNhbGMoXCIgKyB3aWR0aCArIFwicHggLyBcIiArIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICsgXCIpXCJcbiAgKTtcblxuICBhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkge1xuICByZXR1cm4gcGFyc2VJbnQoXG4gICAgd2luZG93XG4gICAgICAuZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpXG4gICAgICAuZ2V0UHJvcGVydHlWYWx1ZShcImNvbHVtbi1jb3VudFwiKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHtcbiAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGU7XG4gIHJldHVybiAoXG4gICAgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tVVNFUl9fdmlld1wiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiIHx8XG4gICAgLy8gRklYTUU6IFdpbGwgbmVlZCB0byBiZSByZW1vdmVkIGluIFJlYWRpdW0gMy4wLCAtLVVTRVJfX3Njcm9sbCB3YXMgaW5jb3JyZWN0LlxuICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLVVTRVJfX3Njcm9sbFwiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JUTCgpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmJvZHkuZGlyLnRvTG93ZXJDYXNlKCkgPT0gXCJydGxcIjtcbn1cblxuLy8gU2Nyb2xsIHRvIHRoZSBnaXZlbiBUYWdJZCBpbiBkb2N1bWVudCBhbmQgc25hcC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb0lkKGlkKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gc2Nyb2xsVG9SZWN0KGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG4vLyBQb3NpdGlvbiBtdXN0IGJlIGluIHRoZSByYW5nZSBbMCAtIDFdLCAwLTEwMCUuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb1Bvc2l0aW9uIFwiICsgcG9zaXRpb24pO1xuICBpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID4gMSkge1xuICAgIHRocm93IFwic2Nyb2xsVG9Qb3NpdGlvbigpIG11c3QgYmUgZ2l2ZW4gYSBwb3NpdGlvbiBmcm9tIDAuMCB0byAgMS4wXCI7XG4gIH1cblxuICBsZXQgb2Zmc2V0O1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxIZWlnaHQgKiBwb3NpdGlvbjtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IG9mZnNldDtcbiAgICAvLyB3aW5kb3cuc2Nyb2xsVG8oMCwgb2Zmc2V0KTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnRXaWR0aCAqIHBvc2l0aW9uICogZmFjdG9yO1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgfVxufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBnaXZlbiB0ZXh0IHNuaXBwZXQuXG4vL1xuLy8gVGhlIGV4cGVjdGVkIHRleHQgYXJndW1lbnQgaXMgYSBMb2NhdG9yIFRleHQgb2JqZWN0LCBhcyBkZWZpbmVkIGhlcmU6XG4vLyBodHRwczovL3JlYWRpdW0ub3JnL2FyY2hpdGVjdHVyZS9tb2RlbHMvbG9jYXRvcnMvXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9UZXh0KHRleHQpIHtcbiAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcih7IHRleHQgfSk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc2Nyb2xsVG9SYW5nZShyYW5nZSk7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JhbmdlKHJhbmdlKSB7XG4gIHJldHVybiBzY3JvbGxUb1JlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JlY3QocmVjdCkge1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPVxuICAgICAgcmVjdC50b3AgKyB3aW5kb3cuc2Nyb2xsWSAtIHdpbmRvdy5pbm5lckhlaWdodCAvIDI7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChcbiAgICAgIHJlY3QubGVmdCArIHdpbmRvdy5zY3JvbGxYXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9TdGFydCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9TdGFydFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gMDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgMCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvRW5kKCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb0VuZFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KFxuICAgICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aCAqIGZhY3RvclxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQpO1xuICB9XG59XG5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2UgaXMgYWxyZWFkeSBhdCB0aGUgbGVmdC1tb3N0IHNjcm9sbCBvZmZzZXQuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsTGVmdCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggLSBwYWdlV2lkdGg7XG4gIHZhciBtaW5PZmZzZXQgPSBpc1JUTCgpID8gLShkb2N1bWVudFdpZHRoIC0gcGFnZVdpZHRoKSA6IDA7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1heChvZmZzZXQsIG1pbk9mZnNldCkpO1xufVxuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIGlzIGFscmVhZHkgYXQgdGhlIHJpZ2h0LW1vc3Qgc2Nyb2xsIG9mZnNldC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxSaWdodCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggKyBwYWdlV2lkdGg7XG4gIHZhciBtYXhPZmZzZXQgPSBpc1JUTCgpID8gMCA6IGRvY3VtZW50V2lkdGggLSBwYWdlV2lkdGg7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1pbihvZmZzZXQsIG1heE9mZnNldCkpO1xufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBnaXZlbiBsZWZ0IG9mZnNldC5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2Ugc2Nyb2xsIHBvc2l0aW9uIGlzIGFscmVhZHkgY2xvc2UgZW5vdWdoIHRvIHRoZSBnaXZlbiBvZmZzZXQuXG5mdW5jdGlvbiBzY3JvbGxUb09mZnNldChvZmZzZXQpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9PZmZzZXQgXCIgKyBvZmZzZXQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgdGhyb3cgXCJDYWxsZWQgc2Nyb2xsVG9PZmZzZXQoKSB3aXRoIHNjcm9sbCBtb2RlIGVuYWJsZWQuIFRoaXMgY2FuIG9ubHkgYmUgdXNlZCBpbiBwYWdpbmF0ZWQgbW9kZS5cIjtcbiAgfVxuXG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgLy8gSW4gc29tZSBjYXNlIHRoZSBzY3JvbGxYIGNhbm5vdCByZWFjaCB0aGUgcG9zaXRpb24gcmVzcGVjdGluZyB0byBpbm5lcldpZHRoXG4gIHZhciBkaWZmID0gTWF0aC5hYnMoY3VycmVudE9mZnNldCAtIG9mZnNldCkgLyBwYWdlV2lkdGg7XG4gIHJldHVybiBkaWZmID4gMC4wMTtcbn1cblxuLy8gU25hcCB0aGUgb2Zmc2V0IHRvIHRoZSBzY3JlZW4gd2lkdGggKHBhZ2Ugd2lkdGgpLlxuZnVuY3Rpb24gc25hcE9mZnNldChvZmZzZXQpIHtcbiAgdmFyIHZhbHVlID0gb2Zmc2V0ICsgKGlzUlRMKCkgPyAtMSA6IDEpO1xuICByZXR1cm4gdmFsdWUgLSAodmFsdWUgJSBwYWdlV2lkdGgpO1xufVxuXG4vLyBTbmFwcyB0aGUgY3VycmVudCBvZmZzZXQgdG8gdGhlIHBhZ2Ugd2lkdGguXG5leHBvcnQgZnVuY3Rpb24gc25hcEN1cnJlbnRPZmZzZXQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNuYXBDdXJyZW50T2Zmc2V0XCIpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIC8vIEFkZHMgaGFsZiBhIHBhZ2UgdG8gbWFrZSBzdXJlIHdlIGRvbid0IHNuYXAgdG8gdGhlIHByZXZpb3VzIHBhZ2UuXG4gIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICB2YXIgZGVsdGEgPSBmYWN0b3IgKiAocGFnZVdpZHRoIC8gMik7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoY3VycmVudE9mZnNldCArIGRlbHRhKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlRnJvbUxvY2F0b3IobG9jYXRvcikge1xuICB0cnkge1xuICAgIGxldCBsb2NhdGlvbnMgPSBsb2NhdG9yLmxvY2F0aW9ucztcbiAgICBsZXQgdGV4dCA9IGxvY2F0b3IudGV4dDtcbiAgICBpZiAodGV4dCAmJiB0ZXh0LmhpZ2hsaWdodCkge1xuICAgICAgdmFyIHJvb3Q7XG4gICAgICBpZiAobG9jYXRpb25zICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICByb290ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuICAgICAgaWYgKCFyb290KSB7XG4gICAgICAgIHJvb3QgPSBkb2N1bWVudC5ib2R5O1xuICAgICAgfVxuXG4gICAgICBsZXQgYW5jaG9yID0gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCB0ZXh0LmhpZ2hsaWdodCwge1xuICAgICAgICBwcmVmaXg6IHRleHQuYmVmb3JlLFxuICAgICAgICBzdWZmaXg6IHRleHQuYWZ0ZXIsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhbmNob3IudG9SYW5nZSgpO1xuICAgIH1cblxuICAgIGlmIChsb2NhdGlvbnMpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gbnVsbDtcblxuICAgICAgaWYgKCFlbGVtZW50ICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnQgJiYgbG9jYXRpb25zLmZyYWdtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IGh0bWxJZCBvZiBsb2NhdGlvbnMuZnJhZ21lbnRzKSB7XG4gICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGh0bWxJZCk7XG4gICAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBsZXQgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEJlZm9yZShlbGVtZW50KTtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kQWZ0ZXIoZWxlbWVudCk7XG4gICAgICAgIHJldHVybiByYW5nZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dFcnJvcihlKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vLy8gVXNlciBTZXR0aW5ncy5cblxuZXhwb3J0IGZ1bmN0aW9uIHNldENTU1Byb3BlcnRpZXMocHJvcGVydGllcykge1xuICBmb3IgKGNvbnN0IG5hbWUgaW4gcHJvcGVydGllcykge1xuICAgIHNldFByb3BlcnR5KG5hbWUsIHByb3BlcnRpZXNbbmFtZV0pO1xuICB9XG59XG5cbi8vIEZvciBzZXR0aW5nIHVzZXIgc2V0dGluZy5cbmV4cG9ydCBmdW5jdGlvbiBzZXRQcm9wZXJ0eShrZXksIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikge1xuICAgIHJlbW92ZVByb3BlcnR5KGtleSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgLy8gVGhlIGAhaW1wb3J0YW50YCBhbm5vdGF0aW9uIGlzIGFkZGVkIHdpdGggYHNldFByb3BlcnR5KClgIGJlY2F1c2UgaWYgaXQncyBwYXJ0IG9mIHRoZVxuICAgIC8vIGB2YWx1ZWAsIGl0IHdpbGwgYmUgaWdub3JlZCBieSB0aGUgV2ViIFZpZXcuXG4gICAgcm9vdC5zdHlsZS5zZXRQcm9wZXJ0eShrZXksIHZhbHVlLCBcImltcG9ydGFudFwiKTtcbiAgfVxufVxuXG4vLyBGb3IgcmVtb3ZpbmcgdXNlciBzZXR0aW5nLlxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5KGtleSkge1xuICB2YXIgcm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuICByb290LnN0eWxlLnJlbW92ZVByb3BlcnR5KGtleSk7XG59XG5cbi8vLyBUb29sa2l0XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2coKSB7XG4gIHZhciBtZXNzYWdlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKFwiIFwiKTtcbiAgQW5kcm9pZC5sb2cobWVzc2FnZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dFcnJvcihtZXNzYWdlKSB7XG4gIEFuZHJvaWQubG9nRXJyb3IobWVzc2FnZSwgXCJcIiwgMCk7XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBsb2cgYXMgbG9nTmF0aXZlIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuY29uc3QgZGVidWcgPSBmYWxzZTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIERPTVJlY3QgaW50byBhIEpTT04gb2JqZWN0IHVuZGVyc3RhbmRhYmxlIGJ5IHRoZSBuYXRpdmUgc2lkZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvTmF0aXZlUmVjdChyZWN0KSB7XG4gIGNvbnN0IHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgY29uc3Qgd2lkdGggPSByZWN0LndpZHRoICogcGl4ZWxSYXRpbztcbiAgY29uc3QgaGVpZ2h0ID0gcmVjdC5oZWlnaHQgKiBwaXhlbFJhdGlvO1xuICBjb25zdCBsZWZ0ID0gcmVjdC5sZWZ0ICogcGl4ZWxSYXRpbztcbiAgY29uc3QgdG9wID0gcmVjdC50b3AgKiBwaXhlbFJhdGlvO1xuICBjb25zdCByaWdodCA9IGxlZnQgKyB3aWR0aDtcbiAgY29uc3QgYm90dG9tID0gdG9wICsgaGVpZ2h0O1xuICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0LCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20gfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICByYW5nZSxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGxldCBjbGllbnRSZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG5cbiAgY29uc3QgdG9sZXJhbmNlID0gMTtcbiAgY29uc3Qgb3JpZ2luYWxSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJhbmdlQ2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIG9yaWdpbmFsUmVjdHMucHVzaCh7XG4gICAgICBib3R0b206IHJhbmdlQ2xpZW50UmVjdC5ib3R0b20sXG4gICAgICBoZWlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUNsaWVudFJlY3QubGVmdCxcbiAgICAgIHJpZ2h0OiByYW5nZUNsaWVudFJlY3QucmlnaHQsXG4gICAgICB0b3A6IHJhbmdlQ2xpZW50UmVjdC50b3AsXG4gICAgICB3aWR0aDogcmFuZ2VDbGllbnRSZWN0LndpZHRoLFxuICAgIH0pO1xuICB9XG4gIGNvbnN0IG1lcmdlZFJlY3RzID0gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgIG9yaWdpbmFsUmVjdHMsXG4gICAgdG9sZXJhbmNlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgY29uc3Qgbm9Db250YWluZWRSZWN0cyA9IHJlbW92ZUNvbnRhaW5lZFJlY3RzKG1lcmdlZFJlY3RzLCB0b2xlcmFuY2UpO1xuICBjb25zdCBuZXdSZWN0cyA9IHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobm9Db250YWluZWRSZWN0cyk7XG4gIGNvbnN0IG1pbkFyZWEgPSAyICogMjtcbiAgZm9yIChsZXQgaiA9IG5ld1JlY3RzLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgY29uc3QgcmVjdCA9IG5ld1JlY3RzW2pdO1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggKiByZWN0LmhlaWdodCA+IG1pbkFyZWE7XG4gICAgaWYgKCFiaWdFbm91Z2gpIHtcbiAgICAgIGlmIChuZXdSZWN0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGxcIik7XG4gICAgICAgIG5ld1JlY3RzLnNwbGljZShqLCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGwsIGJ1dCBrZWVwIG90aGVyd2lzZSBlbXB0eSFcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBsb2coYENMSUVOVCBSRUNUOiByZWR1Y2VkICR7b3JpZ2luYWxSZWN0cy5sZW5ndGh9IC0tPiAke25ld1JlY3RzLmxlbmd0aH1gKTtcbiAgcmV0dXJuIG5ld1JlY3RzO1xufVxuXG5mdW5jdGlvbiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gIHJlY3RzLFxuICB0b2xlcmFuY2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJtZXJnZVRvdWNoaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0c0xpbmVVcFZlcnRpY2FsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIubGVmdCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCBob3Jpem9udGFsQWxsb3dlZCA9ICFkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzO1xuICAgICAgY29uc3QgYWxpZ25lZCA9XG4gICAgICAgIChyZWN0c0xpbmVVcEhvcml6b250YWxseSAmJiBob3Jpem9udGFsQWxsb3dlZCkgfHxcbiAgICAgICAgKHJlY3RzTGluZVVwVmVydGljYWxseSAmJiAhcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkpO1xuICAgICAgY29uc3QgY2FuTWVyZ2UgPSBhbGlnbmVkICYmIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpO1xuICAgICAgaWYgKGNhbk1lcmdlKSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICBgQ0xJRU5UIFJFQ1Q6IG1lcmdpbmcgdHdvIGludG8gb25lLCBWRVJUSUNBTDogJHtyZWN0c0xpbmVVcFZlcnRpY2FsbHl9IEhPUklaT05UQUw6ICR7cmVjdHNMaW5lVXBIb3Jpem9udGFsbHl9ICgke2RvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHN9KWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gcmVjdDEgJiYgcmVjdCAhPT0gcmVjdDI7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXBsYWNlbWVudENsaWVudFJlY3QgPSBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgbmV3UmVjdHMucHVzaChyZXBsYWNlbWVudENsaWVudFJlY3QpO1xuICAgICAgICByZXR1cm4gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgICAgICAgIG5ld1JlY3RzLFxuICAgICAgICAgIHRvbGVyYW5jZSxcbiAgICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCBsZWZ0ID0gTWF0aC5taW4ocmVjdDEubGVmdCwgcmVjdDIubGVmdCk7XG4gIGNvbnN0IHJpZ2h0ID0gTWF0aC5tYXgocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0KTtcbiAgY29uc3QgdG9wID0gTWF0aC5taW4ocmVjdDEudG9wLCByZWN0Mi50b3ApO1xuICBjb25zdCBib3R0b20gPSBNYXRoLm1heChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSk7XG4gIHJldHVybiB7XG4gICAgYm90dG9tLFxuICAgIGhlaWdodDogYm90dG9tIC0gdG9wLFxuICAgIGxlZnQsXG4gICAgcmlnaHQsXG4gICAgdG9wLFxuICAgIHdpZHRoOiByaWdodCAtIGxlZnQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNvbnRhaW5lZFJlY3RzKHJlY3RzLCB0b2xlcmFuY2UpIHtcbiAgY29uc3QgcmVjdHNUb0tlZXAgPSBuZXcgU2V0KHJlY3RzKTtcbiAgZm9yIChjb25zdCByZWN0IG9mIHJlY3RzKSB7XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCA+IDEgJiYgcmVjdC5oZWlnaHQgPiAxO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHRpbnlcIik7XG4gICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwb3NzaWJseUNvbnRhaW5pbmdSZWN0IG9mIHJlY3RzKSB7XG4gICAgICBpZiAocmVjdCA9PT0gcG9zc2libHlDb250YWluaW5nUmVjdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjdHNUb0tlZXAuaGFzKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RDb250YWlucyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0LCByZWN0LCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgY29udGFpbmVkXCIpO1xuICAgICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gQXJyYXkuZnJvbShyZWN0c1RvS2VlcCk7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWlucyhyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjdENvbnRhaW5zUG9pbnQocmVjdCwgeCwgeSwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QubGVmdCA8IHggfHwgYWxtb3N0RXF1YWwocmVjdC5sZWZ0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnJpZ2h0ID4geCB8fCBhbG1vc3RFcXVhbChyZWN0LnJpZ2h0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnRvcCA8IHkgfHwgYWxtb3N0RXF1YWwocmVjdC50b3AsIHksIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QuYm90dG9tID4geSB8fCBhbG1vc3RFcXVhbChyZWN0LmJvdHRvbSwgeSwgdG9sZXJhbmNlKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhyZWN0cykge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgbGV0IHRvQWRkID0gW107XG4gICAgICAgIGxldCB0b1JlbW92ZTtcbiAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czEgPSByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMiA9IHJlY3RTdWJ0cmFjdChyZWN0MiwgcmVjdDEpO1xuICAgICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPCBzdWJ0cmFjdFJlY3RzMi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMyO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbG9nKGBDTElFTlQgUkVDVDogb3ZlcmxhcCwgY3V0IG9uZSByZWN0IGludG8gJHt0b0FkZC5sZW5ndGh9YCk7XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHRvUmVtb3ZlO1xuICAgICAgICB9KTtcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkobmV3UmVjdHMsIHRvQWRkKTtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobmV3UmVjdHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgcmVjdEludGVyc2VjdGVkID0gcmVjdEludGVyc2VjdChyZWN0MiwgcmVjdDEpO1xuICBpZiAocmVjdEludGVyc2VjdGVkLmhlaWdodCA9PT0gMCB8fCByZWN0SW50ZXJzZWN0ZWQud2lkdGggPT09IDApIHtcbiAgICByZXR1cm4gW3JlY3QxXTtcbiAgfVxuICBjb25zdCByZWN0cyA9IFtdO1xuICB7XG4gICAgY29uc3QgcmVjdEEgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3QxLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEEud2lkdGggPSByZWN0QS5yaWdodCAtIHJlY3RBLmxlZnQ7XG4gICAgcmVjdEEuaGVpZ2h0ID0gcmVjdEEuYm90dG9tIC0gcmVjdEEudG9wO1xuICAgIGlmIChyZWN0QS5oZWlnaHQgIT09IDAgJiYgcmVjdEEud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEEpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEIgPSB7XG4gICAgICBib3R0b206IHJlY3RJbnRlcnNlY3RlZC50b3AsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEIud2lkdGggPSByZWN0Qi5yaWdodCAtIHJlY3RCLmxlZnQ7XG4gICAgcmVjdEIuaGVpZ2h0ID0gcmVjdEIuYm90dG9tIC0gcmVjdEIudG9wO1xuICAgIGlmIChyZWN0Qi5oZWlnaHQgIT09IDAgJiYgcmVjdEIud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEIpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEMgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdEludGVyc2VjdGVkLmJvdHRvbSxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEMud2lkdGggPSByZWN0Qy5yaWdodCAtIHJlY3RDLmxlZnQ7XG4gICAgcmVjdEMuaGVpZ2h0ID0gcmVjdEMuYm90dG9tIC0gcmVjdEMudG9wO1xuICAgIGlmIChyZWN0Qy5oZWlnaHQgIT09IDAgJiYgcmVjdEMud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEMpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEQgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHJpZ2h0OiByZWN0MS5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0RC53aWR0aCA9IHJlY3RELnJpZ2h0IC0gcmVjdEQubGVmdDtcbiAgICByZWN0RC5oZWlnaHQgPSByZWN0RC5ib3R0b20gLSByZWN0RC50b3A7XG4gICAgaWYgKHJlY3RELmhlaWdodCAhPT0gMCAmJiByZWN0RC53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0RCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gcmVjdEludGVyc2VjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbWF4TGVmdCA9IE1hdGgubWF4KHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCBtaW5SaWdodCA9IE1hdGgubWluKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IG1heFRvcCA9IE1hdGgubWF4KHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgbWluQm90dG9tID0gTWF0aC5taW4ocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbTogbWluQm90dG9tLFxuICAgIGhlaWdodDogTWF0aC5tYXgoMCwgbWluQm90dG9tIC0gbWF4VG9wKSxcbiAgICBsZWZ0OiBtYXhMZWZ0LFxuICAgIHJpZ2h0OiBtaW5SaWdodCxcbiAgICB0b3A6IG1heFRvcCxcbiAgICB3aWR0aDogTWF0aC5tYXgoMCwgbWluUmlnaHQgLSBtYXhMZWZ0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0MS5sZWZ0IDwgcmVjdDIucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLmxlZnQgPCByZWN0MS5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLmxlZnQsIHJlY3QxLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDEudG9wIDwgcmVjdDIuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi50b3AgPCByZWN0MS5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi50b3AsIHJlY3QxLmJvdHRvbSwgdG9sZXJhbmNlKSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGFsbW9zdEVxdWFsKGEsIGIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gTWF0aC5hYnMoYSAtIGIpIDw9IHRvbGVyYW5jZTtcbn1cblxuZnVuY3Rpb24gbG9nKCkge1xuICBpZiAoZGVidWcpIHtcbiAgICBsb2dOYXRpdmUuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHtcbiAgZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAsXG4gIHJlY3RDb250YWluc1BvaW50LFxuICB0b05hdGl2ZVJlY3QsXG59IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IGxvZywgbG9nRXJyb3IsIHJhbmdlRnJvbUxvY2F0b3IgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5sZXQgc3R5bGVzID0gbmV3IE1hcCgpO1xubGV0IGdyb3VwcyA9IG5ldyBNYXAoKTtcbnZhciBsYXN0R3JvdXBJZCA9IDA7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgbGlzdCBvZiBhZGRpdGlvbmFsIHN1cHBvcnRlZCBEZWNvcmF0aW9uIFRlbXBsYXRlcy5cbiAqXG4gKiBFYWNoIHRlbXBsYXRlIG9iamVjdCBpcyBpbmRleGVkIGJ5IHRoZSBzdHlsZSBJRC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyVGVtcGxhdGVzKG5ld1N0eWxlcykge1xuICB2YXIgc3R5bGVzaGVldCA9IFwiXCI7XG5cbiAgZm9yIChjb25zdCBbaWQsIHN0eWxlXSBvZiBPYmplY3QuZW50cmllcyhuZXdTdHlsZXMpKSB7XG4gICAgc3R5bGVzLnNldChpZCwgc3R5bGUpO1xuICAgIGlmIChzdHlsZS5zdHlsZXNoZWV0KSB7XG4gICAgICBzdHlsZXNoZWV0ICs9IHN0eWxlLnN0eWxlc2hlZXQgKyBcIlxcblwiO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdHlsZXNoZWV0KSB7XG4gICAgbGV0IHN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICBzdHlsZUVsZW1lbnQuaW5uZXJIVE1MID0gc3R5bGVzaGVldDtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRGVjb3JhdGlvbkdyb3VwIGZvciB0aGUgZ2l2ZW4gZ3JvdXAgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlY29yYXRpb25zKGdyb3VwTmFtZSkge1xuICB2YXIgZ3JvdXAgPSBncm91cHMuZ2V0KGdyb3VwTmFtZSk7XG4gIGlmICghZ3JvdXApIHtcbiAgICBsZXQgaWQgPSBcInIyLWRlY29yYXRpb24tXCIgKyBsYXN0R3JvdXBJZCsrO1xuICAgIGdyb3VwID0gRGVjb3JhdGlvbkdyb3VwKGlkLCBncm91cE5hbWUpO1xuICAgIGdyb3Vwcy5zZXQoZ3JvdXBOYW1lLCBncm91cCk7XG4gIH1cbiAgcmV0dXJuIGdyb3VwO1xufVxuXG4vKipcbiAqIEhhbmRsZXMgY2xpY2sgZXZlbnRzIG9uIGEgRGVjb3JhdGlvbi5cbiAqIFJldHVybnMgd2hldGhlciBhIGRlY29yYXRpb24gbWF0Y2hlZCB0aGlzIGV2ZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQoZXZlbnQsIGNsaWNrRXZlbnQpIHtcbiAgaWYgKGdyb3Vwcy5zaXplID09PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZFRhcmdldCgpIHtcbiAgICBmb3IgKGNvbnN0IFtncm91cCwgZ3JvdXBDb250ZW50XSBvZiBncm91cHMpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBncm91cENvbnRlbnQuaXRlbXMucmV2ZXJzZSgpKSB7XG4gICAgICAgIGlmICghaXRlbS5jbGlja2FibGVFbGVtZW50cykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzKSB7XG4gICAgICAgICAgbGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvSlNPTigpO1xuICAgICAgICAgIGlmIChyZWN0Q29udGFpbnNQb2ludChyZWN0LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCAxKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgZ3JvdXAsIGl0ZW0sIGVsZW1lbnQsIHJlY3QgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgdGFyZ2V0ID0gZmluZFRhcmdldCgpO1xuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBBbmRyb2lkLm9uRGVjb3JhdGlvbkFjdGl2YXRlZChcbiAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBpZDogdGFyZ2V0Lml0ZW0uZGVjb3JhdGlvbi5pZCxcbiAgICAgIGdyb3VwOiB0YXJnZXQuZ3JvdXAsXG4gICAgICByZWN0OiB0b05hdGl2ZVJlY3QodGFyZ2V0Lml0ZW0ucmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpLFxuICAgICAgY2xpY2s6IGNsaWNrRXZlbnQsXG4gICAgfSlcbiAgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgRGVjb3JhdGlvbkdyb3VwIG9iamVjdCBmcm9tIGEgdW5pcXVlIEhUTUwgSUQgYW5kIGl0cyBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gRGVjb3JhdGlvbkdyb3VwKGdyb3VwSWQsIGdyb3VwTmFtZSkge1xuICB2YXIgaXRlbXMgPSBbXTtcbiAgdmFyIGxhc3RJdGVtSWQgPSAwO1xuICB2YXIgY29udGFpbmVyID0gbnVsbDtcblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBkZWNvcmF0aW9uIHRvIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIGFkZChkZWNvcmF0aW9uKSB7XG4gICAgbGV0IGlkID0gZ3JvdXBJZCArIFwiLVwiICsgbGFzdEl0ZW1JZCsrO1xuXG4gICAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcihkZWNvcmF0aW9uLmxvY2F0b3IpO1xuICAgIGlmICghcmFuZ2UpIHtcbiAgICAgIGxvZyhcIkNhbid0IGxvY2F0ZSBET00gcmFuZ2UgZm9yIGRlY29yYXRpb25cIiwgZGVjb3JhdGlvbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSB7IGlkLCBkZWNvcmF0aW9uLCByYW5nZSB9O1xuICAgIGl0ZW1zLnB1c2goaXRlbSk7XG4gICAgbGF5b3V0KGl0ZW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGRlY29yYXRpb24gd2l0aCBnaXZlbiBJRCBmcm9tIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZShkZWNvcmF0aW9uSWQpIHtcbiAgICBsZXQgaW5kZXggPSBpdGVtcy5maW5kSW5kZXgoKGkpID0+IGkuZGVjb3JhdGlvbi5pZCA9PT0gZGVjb3JhdGlvbklkKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSBpdGVtc1tpbmRleF07XG4gICAgaXRlbXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gbnVsbDtcbiAgICBpZiAoaXRlbS5jb250YWluZXIpIHtcbiAgICAgIGl0ZW0uY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgaXRlbS5jb250YWluZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZmllcyB0aGF0IHRoZSBnaXZlbiBkZWNvcmF0aW9uIHdhcyBtb2RpZmllZCBhbmQgbmVlZHMgdG8gYmUgdXBkYXRlZC5cbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZShkZWNvcmF0aW9uKSB7XG4gICAgcmVtb3ZlKGRlY29yYXRpb24uaWQpO1xuICAgIGFkZChkZWNvcmF0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFsbCBkZWNvcmF0aW9ucyBmcm9tIHRoaXMgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICBjbGVhckNvbnRhaW5lcigpO1xuICAgIGl0ZW1zLmxlbmd0aCA9IDA7XG4gIH1cblxuICAvKipcbiAgICogUmVjcmVhdGVzIHRoZSBkZWNvcmF0aW9uIGVsZW1lbnRzLlxuICAgKlxuICAgKiBUbyBiZSBjYWxsZWQgYWZ0ZXIgcmVmbG93aW5nIHRoZSByZXNvdXJjZSwgZm9yIGV4YW1wbGUuXG4gICAqL1xuICBmdW5jdGlvbiByZXF1ZXN0TGF5b3V0KCkge1xuICAgIGNsZWFyQ29udGFpbmVyKCk7XG4gICAgaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4gbGF5b3V0KGl0ZW0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXlvdXRzIGEgc2luZ2xlIERlY29yYXRpb24gaXRlbS5cbiAgICovXG4gIGZ1bmN0aW9uIGxheW91dChpdGVtKSB7XG4gICAgbGV0IGdyb3VwQ29udGFpbmVyID0gcmVxdWlyZUNvbnRhaW5lcigpO1xuXG4gICAgbGV0IHN0eWxlID0gc3R5bGVzLmdldChpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGlmICghc3R5bGUpIHtcbiAgICAgIGxvZ0Vycm9yKGBVbmtub3duIGRlY29yYXRpb24gc3R5bGU6ICR7aXRlbS5kZWNvcmF0aW9uLnN0eWxlfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBpdGVtQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIGl0ZW0uaWQpO1xuICAgIGl0ZW1Db250YWluZXIuc2V0QXR0cmlidXRlKFwiZGF0YS1zdHlsZVwiLCBpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGl0ZW1Db250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG5cbiAgICBsZXQgdmlld3BvcnRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgIGxldCBjb2x1bW5Db3VudCA9IHBhcnNlSW50KFxuICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXG4gICAgICAgIFwiY29sdW1uLWNvdW50XCJcbiAgICAgIClcbiAgICApO1xuICAgIGxldCBwYWdlV2lkdGggPSB2aWV3cG9ydFdpZHRoIC8gKGNvbHVtbkNvdW50IHx8IDEpO1xuICAgIGxldCBzY3JvbGxpbmdFbGVtZW50ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudDtcbiAgICBsZXQgeE9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICBsZXQgeU9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgZnVuY3Rpb24gcG9zaXRpb25FbGVtZW50KGVsZW1lbnQsIHJlY3QsIGJvdW5kaW5nUmVjdCkge1xuICAgICAgZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblxuICAgICAgaWYgKHN0eWxlLndpZHRoID09PSBcIndyYXBcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtyZWN0LmxlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJ2aWV3cG9ydFwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHt2aWV3cG9ydFdpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGxldCBsZWZ0ID0gTWF0aC5mbG9vcihyZWN0LmxlZnQgLyB2aWV3cG9ydFdpZHRoKSAqIHZpZXdwb3J0V2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJib3VuZHNcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7Ym91bmRpbmdSZWN0LndpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2JvdW5kaW5nUmVjdC5sZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwicGFnZVwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtwYWdlV2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgbGV0IGxlZnQgPSBNYXRoLmZsb29yKHJlY3QubGVmdCAvIHBhZ2VXaWR0aCkgKiBwYWdlV2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBib3VuZGluZ1JlY3QgPSBpdGVtLnJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgbGV0IGVsZW1lbnRUZW1wbGF0ZTtcbiAgICB0cnkge1xuICAgICAgbGV0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gaXRlbS5kZWNvcmF0aW9uLmVsZW1lbnQudHJpbSgpO1xuICAgICAgZWxlbWVudFRlbXBsYXRlID0gdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGRlY29yYXRpb24gZWxlbWVudCBcIiR7aXRlbS5kZWNvcmF0aW9uLmVsZW1lbnR9XCI6ICR7ZXJyb3IubWVzc2FnZX1gXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm94ZXNcIikge1xuICAgICAgbGV0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSB0cnVlO1xuICAgICAgbGV0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgICAgIGl0ZW0ucmFuZ2UsXG4gICAgICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgICAgICk7XG5cbiAgICAgIGNsaWVudFJlY3RzID0gY2xpZW50UmVjdHMuc29ydCgocjEsIHIyKSA9PiB7XG4gICAgICAgIGlmIChyMS50b3AgPCByMi50b3ApIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH0gZWxzZSBpZiAocjEudG9wID4gcjIudG9wKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBmb3IgKGxldCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBlbGVtZW50VGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBsaW5lLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICBwb3NpdGlvbkVsZW1lbnQobGluZSwgY2xpZW50UmVjdCwgYm91bmRpbmdSZWN0KTtcbiAgICAgICAgaXRlbUNvbnRhaW5lci5hcHBlbmQobGluZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm91bmRzXCIpIHtcbiAgICAgIGNvbnN0IGJvdW5kcyA9IGVsZW1lbnRUZW1wbGF0ZS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICBib3VuZHMuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBwb3NpdGlvbkVsZW1lbnQoYm91bmRzLCBib3VuZGluZ1JlY3QsIGJvdW5kaW5nUmVjdCk7XG5cbiAgICAgIGl0ZW1Db250YWluZXIuYXBwZW5kKGJvdW5kcyk7XG4gICAgfVxuXG4gICAgZ3JvdXBDb250YWluZXIuYXBwZW5kKGl0ZW1Db250YWluZXIpO1xuICAgIGl0ZW0uY29udGFpbmVyID0gaXRlbUNvbnRhaW5lcjtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gQXJyYXkuZnJvbShcbiAgICAgIGl0ZW1Db250YWluZXIucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWFjdGl2YWJsZT0nMSddXCIpXG4gICAgKTtcbiAgICBpZiAoaXRlbS5jbGlja2FibGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGl0ZW0uY2xpY2thYmxlRWxlbWVudHMgPSBBcnJheS5mcm9tKGl0ZW1Db250YWluZXIuY2hpbGRyZW4pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBncm91cCBjb250YWluZXIgZWxlbWVudCwgYWZ0ZXIgbWFraW5nIHN1cmUgaXQgZXhpc3RzLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVxdWlyZUNvbnRhaW5lcigpIHtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBncm91cElkKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJkYXRhLWdyb3VwXCIsIGdyb3VwTmFtZSk7XG4gICAgICBjb250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChjb250YWluZXIpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdyb3VwIGNvbnRhaW5lci5cbiAgICovXG4gIGZ1bmN0aW9uIGNsZWFyQ29udGFpbmVyKCkge1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGNvbnRhaW5lciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgYWRkLCByZW1vdmUsIHVwZGF0ZSwgY2xlYXIsIGl0ZW1zLCByZXF1ZXN0TGF5b3V0IH07XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIC8vIFdpbGwgcmVsYXlvdXQgYWxsIHRoZSBkZWNvcmF0aW9ucyB3aGVuIHRoZSBkb2N1bWVudCBib2R5IGlzIHJlc2l6ZWQuXG4gICAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgdmFyIGxhc3RTaXplID0geyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBsYXN0U2l6ZS53aWR0aCA9PT0gYm9keS5jbGllbnRXaWR0aCAmJlxuICAgICAgICBsYXN0U2l6ZS5oZWlnaHQgPT09IGJvZHkuY2xpZW50SGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbGFzdFNpemUgPSB7XG4gICAgICAgIHdpZHRoOiBib2R5LmNsaWVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGJvZHkuY2xpZW50SGVpZ2h0LFxuICAgICAgfTtcblxuICAgICAgZ3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIGdyb3VwLnJlcXVlc3RMYXlvdXQoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoYm9keSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMiBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgaXNTY3JvbGxNb2RlRW5hYmxlZCB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBnZXRDc3NTZWxlY3RvciB9IGZyb20gXCJjc3Mtc2VsZWN0b3ItZ2VuZXJhdG9yXCI7XG5cbi8vIFNlZS4gaHR0cHM6Ly9naXRodWIuY29tL0pheVBhbm96L2FyY2hpdGVjdHVyZS90cmVlL3RvdWNoLWhhbmRsaW5nL21pc2MvdG91Y2gtaGFuZGxpbmdcbmV4cG9ydCBmdW5jdGlvbiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciBpbnRlcmFjdGl2ZVRhZ3MgPSBbXG4gICAgXCJhXCIsXG4gICAgXCJhdWRpb1wiLFxuICAgIFwiYnV0dG9uXCIsXG4gICAgXCJjYW52YXNcIixcbiAgICBcImRldGFpbHNcIixcbiAgICBcImlucHV0XCIsXG4gICAgXCJsYWJlbFwiLFxuICAgIFwib3B0aW9uXCIsXG4gICAgXCJzZWxlY3RcIixcbiAgICBcInN1Ym1pdFwiLFxuICAgIFwidGV4dGFyZWFcIixcbiAgICBcInZpZGVvXCIsXG4gIF07XG4gIGlmIChpbnRlcmFjdGl2ZVRhZ3MuaW5kZXhPZihlbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpICE9IC0xKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQub3V0ZXJIVE1MO1xuICB9XG5cbiAgLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgZWRpdGFibGUgYnkgdGhlIHVzZXIuXG4gIGlmIChcbiAgICBlbGVtZW50Lmhhc0F0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKSAmJlxuICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiY29udGVudGVkaXRhYmxlXCIpLnRvTG93ZXJDYXNlKCkgIT0gXCJmYWxzZVwiXG4gICkge1xuICAgIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgfVxuXG4gIC8vIENoZWNrcyBwYXJlbnRzIHJlY3Vyc2l2ZWx5IGJlY2F1c2UgdGhlIHRvdWNoIG1pZ2h0IGJlIGZvciBleGFtcGxlIG9uIGFuIDxlbT4gaW5zaWRlIGEgPGE+LlxuICBpZiAoZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XG4gICAgcmV0dXJuIG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZWxlbWVudC5wYXJlbnRFbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IoKSB7XG4gIGNvbnN0IGVsZW1lbnQgPSBmaW5kRWxlbWVudChkb2N1bWVudC5ib2R5KTtcbiAgcmV0dXJuIHtcbiAgICBocmVmOiBcIiNcIixcbiAgICB0eXBlOiBcImFwcGxpY2F0aW9uL3hodG1sK3htbFwiLFxuICAgIGxvY2F0aW9uczoge1xuICAgICAgY3NzU2VsZWN0b3I6IGdldENzc1NlbGVjdG9yKGVsZW1lbnQpLFxuICAgIH0sXG4gICAgdGV4dDoge1xuICAgICAgaGlnaGxpZ2h0OiBlbGVtZW50LnRleHRDb250ZW50LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZpbmRFbGVtZW50KHJvb3RFbGVtZW50KSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcm9vdEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGlsZCA9IHJvb3RFbGVtZW50LmNoaWxkcmVuW2ldO1xuICAgIGlmICghc2hvdWxkSWdub3JlRWxlbWVudChjaGlsZCkgJiYgaXNFbGVtZW50VmlzaWJsZShjaGlsZCkpIHtcbiAgICAgIHJldHVybiBmaW5kRWxlbWVudChjaGlsZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByb290RWxlbWVudDtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50VmlzaWJsZShlbGVtZW50KSB7XG4gIGlmIChyZWFkaXVtLmlzRml4ZWRMYXlvdXQpIHJldHVybiB0cnVlO1xuXG4gIGlmIChlbGVtZW50ID09PSBkb2N1bWVudC5ib2R5IHx8IGVsZW1lbnQgPT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmICghZG9jdW1lbnQgfHwgIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCAhZG9jdW1lbnQuYm9keSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuIHJlY3QuYm90dG9tID4gMCAmJiByZWN0LnRvcCA8IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5sZWZ0IDwgd2luZG93LmlubmVyV2lkdGg7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlRWxlbWVudChlbGVtZW50KSB7XG4gIGNvbnN0IGVsU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICBpZiAoZWxTdHlsZSkge1xuICAgIGNvbnN0IGRpc3BsYXkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJkaXNwbGF5XCIpO1xuICAgIGlmIChkaXNwbGF5ICE9IFwiYmxvY2tcIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENhbm5vdCBiZSByZWxpZWQgdXBvbiwgYmVjYXVzZSB3ZWIgYnJvd3NlciBlbmdpbmUgcmVwb3J0cyBpbnZpc2libGUgd2hlbiBvdXQgb2YgdmlldyBpblxuICAgIC8vIHNjcm9sbGVkIGNvbHVtbnMhXG4gICAgLy8gY29uc3QgdmlzaWJpbGl0eSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcInZpc2liaWxpdHlcIik7XG4gICAgLy8gaWYgKHZpc2liaWxpdHkgPT09IFwiaGlkZGVuXCIpIHtcbiAgICAvLyAgICAgcmV0dXJuIGZhbHNlO1xuICAgIC8vIH1cbiAgICBjb25zdCBvcGFjaXR5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwib3BhY2l0eVwiKTtcbiAgICBpZiAob3BhY2l0eSA9PT0gXCIwXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2VcbiAqIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbiAqL1xuXG5pbXBvcnQgeyBoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudCB9IGZyb20gXCIuL2RlY29yYXRvclwiO1xuaW1wb3J0IHsgbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudCB9IGZyb20gXCIuL2RvbVwiO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgZnVuY3Rpb24gKCkge1xuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgb25DbGljaywgZmFsc2UpO1xuICBiaW5kRHJhZ0dlc3R1cmUoZG9jdW1lbnQpO1xufSk7XG5cbmZ1bmN0aW9uIG9uQ2xpY2soZXZlbnQpIHtcbiAgaWYgKCF3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuaXNDb2xsYXBzZWQpIHtcbiAgICAvLyBUaGVyZSdzIGFuIG9uLWdvaW5nIHNlbGVjdGlvbiwgdGhlIHRhcCB3aWxsIGRpc21pc3MgaXQgc28gd2UgZG9uJ3QgZm9yd2FyZCBpdC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBsZXQgY2xpY2tFdmVudCA9IHtcbiAgICBkZWZhdWx0UHJldmVudGVkOiBldmVudC5kZWZhdWx0UHJldmVudGVkLFxuICAgIHg6IGV2ZW50LmNsaWVudFggKiBwaXhlbFJhdGlvLFxuICAgIHk6IGV2ZW50LmNsaWVudFkgKiBwaXhlbFJhdGlvLFxuICAgIHRhcmdldEVsZW1lbnQ6IGV2ZW50LnRhcmdldC5vdXRlckhUTUwsXG4gICAgaW50ZXJhY3RpdmVFbGVtZW50OiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGV2ZW50LnRhcmdldCksXG4gIH07XG5cbiAgaWYgKGhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50KGV2ZW50LCBjbGlja0V2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFNlbmQgdGhlIHRhcCBkYXRhIG92ZXIgdGhlIEpTIGJyaWRnZSBldmVuIGlmIGl0J3MgYmVlbiBoYW5kbGVkIHdpdGhpbiB0aGUgd2ViIHZpZXcsIHNvIHRoYXRcbiAgLy8gaXQgY2FuIGJlIHByZXNlcnZlZCBhbmQgdXNlZCBieSB0aGUgdG9vbGtpdCBpZiBuZWVkZWQuXG4gIHZhciBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25UYXAoSlNPTi5zdHJpbmdpZnkoY2xpY2tFdmVudCkpO1xuXG4gIGlmIChzaG91bGRQcmV2ZW50RGVmYXVsdCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYmluZERyYWdHZXN0dXJlKGVsZW1lbnQpIHtcbiAgLy8gcGFzc2l2ZTogZmFsc2UgaXMgbmVjZXNzYXJ5IHRvIGJlIGFibGUgdG8gcHJldmVudCB0aGUgZGVmYXVsdCBiZWhhdmlvci5cbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCBvblN0YXJ0LCB7IHBhc3NpdmU6IGZhbHNlIH0pO1xuICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBvbkVuZCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIG9uTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcblxuICB2YXIgc3RhdGUgPSB1bmRlZmluZWQ7XG4gIHZhciBpc1N0YXJ0aW5nRHJhZyA9IGZhbHNlO1xuICBjb25zdCBwaXhlbFJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG5cbiAgZnVuY3Rpb24gb25TdGFydChldmVudCkge1xuICAgIGlzU3RhcnRpbmdEcmFnID0gdHJ1ZTtcblxuICAgIGNvbnN0IHN0YXJ0WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAqIHBpeGVsUmF0aW87XG4gICAgY29uc3Qgc3RhcnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZSA9IHtcbiAgICAgIGRlZmF1bHRQcmV2ZW50ZWQ6IGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQsXG4gICAgICBzdGFydFg6IHN0YXJ0WCxcbiAgICAgIHN0YXJ0WTogc3RhcnRZLFxuICAgICAgY3VycmVudFg6IHN0YXJ0WCxcbiAgICAgIGN1cnJlbnRZOiBzdGFydFksXG4gICAgICBvZmZzZXRYOiAwLFxuICAgICAgb2Zmc2V0WTogMCxcbiAgICAgIGludGVyYWN0aXZlRWxlbWVudDogbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChldmVudC50YXJnZXQpLFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBvbk1vdmUoZXZlbnQpIHtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG5cbiAgICBzdGF0ZS5jdXJyZW50WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUuY3VycmVudFkgPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlLm9mZnNldFggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLnN0YXJ0WDtcbiAgICBzdGF0ZS5vZmZzZXRZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5zdGFydFk7XG5cbiAgICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBmYWxzZTtcbiAgICAvLyBXYWl0IGZvciBhIG1vdmVtZW50IG9mIGF0IGxlYXN0IDYgcGl4ZWxzIGJlZm9yZSByZXBvcnRpbmcgYSBkcmFnLlxuICAgIGlmIChpc1N0YXJ0aW5nRHJhZykge1xuICAgICAgaWYgKE1hdGguYWJzKHN0YXRlLm9mZnNldFgpID49IDYgfHwgTWF0aC5hYnMoc3RhdGUub2Zmc2V0WSkgPj0gNikge1xuICAgICAgICBpc1N0YXJ0aW5nRHJhZyA9IGZhbHNlO1xuICAgICAgICBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnU3RhcnQoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ01vdmUoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbkVuZChldmVudCkge1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcblxuICAgIGNvbnN0IHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdFbmQoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgc3RhdGUgPSB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjMgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQgfSBmcm9tIFwiLi9kb21cIjtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChldmVudCkgPT4ge1xuICBpZiAoc2hvdWxkSWdub3JlRXZlbnQoZXZlbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJldmVudERlZmF1bHQoZXZlbnQpO1xuICBzZW5kUHJlc3NLZXlNZXNzYWdlKGV2ZW50LCBcImRvd25cIik7XG59KTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXl1cFwiLCAoZXZlbnQpID0+IHtcbiAgaWYgKHNob3VsZElnbm9yZUV2ZW50KGV2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcbiAgc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgXCJ1cFwiKTtcbn0pO1xuXG5mdW5jdGlvbiBzaG91bGRJZ25vcmVFdmVudChldmVudCkge1xuICByZXR1cm4gKFxuICAgIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHxcbiAgICBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpICE9IG51bGxcbiAgKTtcbn1cblxuLy8gV2UgcHJldmVudCB0aGUgZGVmYXVsdCBiZWhhdmlvciBmb3Iga2V5Ym9hcmQgZXZlbnRzLCBvdGhlcndpc2UgdGhlIHdlYiB2aWV3XG4vLyBtaWdodCBzY3JvbGwuXG5mdW5jdGlvbiBwcmV2ZW50RGVmYXVsdChldmVudCkge1xuICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbn1cblxuZnVuY3Rpb24gc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgdHlwZSkge1xuICBpZiAoZXZlbnQucmVwZWF0KSByZXR1cm47XG5cbiAgbGV0IGtleUV2ZW50ID0ge1xuICAgIHR5cGU6IHR5cGUsXG4gICAgY29kZTogZXZlbnQuY29kZSxcbiAgICBjaGFyYWN0ZXJzOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LmtleUNvZGUpLFxuICAgIGFsdDogZXZlbnQuYWx0S2V5LFxuICAgIGNvbnRyb2w6IGV2ZW50LmN0cmxLZXksXG4gICAgc2hpZnQ6IGV2ZW50LnNoaWZ0S2V5LFxuICAgIG1ldGE6IGV2ZW50Lm1ldGFLZXksXG4gIH07XG5cbiAgQW5kcm9pZC5vbktleShKU09OLnN0cmluZ2lmeShrZXlFdmVudCkpO1xufVxuIiwiLyogZXNsaW50LWRpc2FibGUgKi9cbi8vXG4vLyAgaGlnaGxpZ2h0LmpzXG4vLyAgcjItbmF2aWdhdG9yLWtvdGxpblxuLy9cbi8vICBPcmdhbml6ZWQgYnkgVGFlaHl1biBLaW0gb24gNi8yNy8xOSBmcm9tIHIyLW5hdmlnYXRvci1qcy5cbi8vXG4vLyAgQ29weXJpZ2h0IDIwMTkgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2Ugd2hpY2ggaXMgZGV0YWlsZWRcbi8vICBpbiB0aGUgTElDRU5TRSBmaWxlIHByZXNlbnQgaW4gdGhlIHByb2plY3QgcmVwb3NpdG9yeSB3aGVyZSB0aGlzIHNvdXJjZSBjb2RlIGlzIG1haW50YWluZWQuXG4vL1xuXG5jb25zdCBST09UX0NMQVNTX1JFRFVDRV9NT1RJT04gPSBcInIyLXJlZHVjZS1tb3Rpb25cIjtcbmNvbnN0IFJPT1RfQ0xBU1NfTk9fRk9PVE5PVEVTID0gXCJyMi1uby1wb3B1cC1mb29ub3Rlc1wiO1xuY29uc3QgUE9QVVBfRElBTE9HX0NMQVNTID0gXCJyMi1wb3B1cC1kaWFsb2dcIjtcbmNvbnN0IEZPT1ROT1RFU19DT05UQUlORVJfQ0xBU1MgPSBcInIyLWZvb3Rub3RlLWNvbnRhaW5lclwiO1xuY29uc3QgRk9PVE5PVEVTX0NMT1NFX0JVVFRPTl9DTEFTUyA9IFwicjItZm9vdG5vdGUtY2xvc2VcIjtcbmNvbnN0IEZPT1ROT1RFX0ZPUkNFX1NIT1cgPSBcInIyLWZvb3Rub3RlLWZvcmNlLXNob3dcIjtcbmNvbnN0IFRUU19JRF9QUkVWSU9VUyA9IFwicjItdHRzLXByZXZpb3VzXCI7XG5jb25zdCBUVFNfSURfTkVYVCA9IFwicjItdHRzLW5leHRcIjtcbmNvbnN0IFRUU19JRF9TTElERVIgPSBcInIyLXR0cy1zbGlkZXJcIjtcbmNvbnN0IFRUU19JRF9BQ1RJVkVfV09SRCA9IFwicjItdHRzLWFjdGl2ZS13b3JkXCI7XG5jb25zdCBUVFNfSURfQ09OVEFJTkVSID0gXCJyMi10dHMtdHh0XCI7XG5jb25zdCBUVFNfSURfSU5GTyA9IFwicjItdHRzLWluZm9cIjtcbmNvbnN0IFRUU19OQVZfQlVUVE9OX0NMQVNTID0gXCJyMi10dHMtYnV0dG9uXCI7XG5jb25zdCBUVFNfSURfU1BFQUtJTkdfRE9DX0VMRU1FTlQgPSBcInIyLXR0cy1zcGVha2luZy1lbFwiO1xuY29uc3QgVFRTX0NMQVNTX0lOSkVDVEVEX1NQQU4gPSBcInIyLXR0cy1zcGVha2luZy10eHRcIjtcbmNvbnN0IFRUU19DTEFTU19JTkpFQ1RFRF9TVUJTUEFOID0gXCJyMi10dHMtc3BlYWtpbmctd29yZFwiO1xuY29uc3QgVFRTX0lEX0lOSkVDVEVEX1BBUkVOVCA9IFwicjItdHRzLXNwZWFraW5nLXR4dC1wYXJlbnRcIjtcbmNvbnN0IElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSID0gXCJSMl9JRF9ISUdITElHSFRTX0NPTlRBSU5FUlwiO1xuY29uc3QgSURfQU5OT1RBVElPTl9DT05UQUlORVIgPSBcIlIyX0lEX0FOTk9UQVRJT05fQ09OVEFJTkVSXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSID0gXCJSMl9DTEFTU19ISUdITElHSFRfQ09OVEFJTkVSXCI7XG5jb25zdCBDTEFTU19BTk5PVEFUSU9OX0NPTlRBSU5FUiA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9DT05UQUlORVJcIjtcbmNvbnN0IENMQVNTX0hJR0hMSUdIVF9BUkVBID0gXCJSMl9DTEFTU19ISUdITElHSFRfQVJFQVwiO1xuY29uc3QgQ0xBU1NfQU5OT1RBVElPTl9BUkVBID0gXCJSMl9DTEFTU19BTk5PVEFUSU9OX0FSRUFcIjtcbmNvbnN0IENMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBID0gXCJSMl9DTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQVwiO1xuY29uc3QgQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBID0gXCJSMl9DTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcIjtcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbmNvbnN0IF9ibGFja2xpc3RJZENsYXNzRm9yQ0ZJID0gW1xuICBQT1BVUF9ESUFMT0dfQ0xBU1MsXG4gIFRUU19DTEFTU19JTkpFQ1RFRF9TUEFOLFxuICBUVFNfQ0xBU1NfSU5KRUNURURfU1VCU1BBTixcbiAgSURfSElHSExJR0hUU19DT05UQUlORVIsXG4gIENMQVNTX0hJR0hMSUdIVF9DT05UQUlORVIsXG4gIENMQVNTX0hJR0hMSUdIVF9BUkVBLFxuICBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSxcbiAgXCJyZXNpemUtc2Vuc29yXCIsXG5dO1xuY29uc3QgQ0xBU1NfUEFHSU5BVEVEID0gXCJyMi1jc3MtcGFnaW5hdGVkXCI7XG5cbi8vY29uc3QgSVNfREVWID0gKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcImRldmVsb3BtZW50XCIgfHwgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwiZGV2XCIpO1xuY29uc3QgSVNfREVWID0gZmFsc2U7XG5jb25zdCBfaGlnaGxpZ2h0cyA9IFtdO1xuXG5sZXQgX2hpZ2hsaWdodHNDb250YWluZXI7XG5sZXQgX2Fubm90YXRpb25Db250YWluZXI7XG5sZXQgbGFzdE1vdXNlRG93blggPSAtMTtcbmxldCBsYXN0TW91c2VEb3duWSA9IC0xO1xubGV0IGJvZHlFdmVudExpc3RlbmVyc1NldCA9IGZhbHNlO1xuXG5jb25zdCBVU0VfU1ZHID0gZmFsc2U7XG5jb25zdCBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWSA9IDAuMztcbmNvbnN0IEFMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkgPSAwLjQ1O1xuXG4vL2NvbnN0IERFQlVHX1ZJU1VBTFMgPSBmYWxzZTtcbmNvbnN0IERFQlVHX1ZJU1VBTFMgPSBmYWxzZTtcbmNvbnN0IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUiA9IHtcbiAgYmx1ZTogMTAwLFxuICBncmVlbjogNTAsXG4gIHJlZDogMjMwLFxufTtcblxuY29uc3QgQU5OT1RBVElPTl9XSURUSCA9IDE1O1xuXG5mdW5jdGlvbiByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUoX3dpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpIHtcbiAgaWYgKFxuICAgIGhpZ2hsaWdodEJvdW5kaW5nLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpID09IENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQVxuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUub3V0bGluZSA9IFwibm9uZVwiO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICBcImJhY2tncm91bmQtY29sb3JcIixcbiAgICBcInRyYW5zcGFyZW50XCIsXG4gICAgXCJpbXBvcnRhbnRcIlxuICApO1xufVxuXG5mdW5jdGlvbiBzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhcywgaGlnaGxpZ2h0KSB7XG4gIGNvbnN0IHVzZVNWRyA9ICFERUJVR19WSVNVQUxTICYmIFVTRV9TVkc7XG4gIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBoaWdobGlnaHRBcmVhcykge1xuICAgIGNvbnN0IGlzU1ZHID0gdXNlU1ZHICYmIGhpZ2hsaWdodEFyZWEubmFtZXNwYWNlVVJJID09PSBTVkdfWE1MX05BTUVTUEFDRTtcbiAgICBjb25zdCBvcGFjaXR5ID0gQUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWTtcbiAgICBpZiAoaXNTVkcpIHtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwiZmlsbFwiLFxuICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwiZmlsbC1vcGFjaXR5XCIsXG4gICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwic3Ryb2tlXCIsXG4gICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiLFxuICAgICAgICBgJHtvcGFjaXR5fWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiLFxuICAgICAgICBgcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSkge1xuICBjb25zdCB1c2VTVkcgPSAhREVCVUdfVklTVUFMUyAmJiBVU0VfU1ZHO1xuICAvL2NvbnN0IHVzZVNWRyA9IFVTRV9TVkc7XG4gIGNvbnN0IGlzU1ZHID0gdXNlU1ZHICYmIGhpZ2hsaWdodEFyZWEubmFtZXNwYWNlVVJJID09PSBTVkdfWE1MX05BTUVTUEFDRTtcbiAgY29uc3QgaWQgPSBpc1NWR1xuICAgID8gaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUucGFyZW50Tm9kZSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGVcbiAgICAgID8gaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKFwiaWRcIilcbiAgICAgIDogdW5kZWZpbmVkXG4gICAgOiBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGVcbiAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUoXCJpZFwiKVxuICAgIDogdW5kZWZpbmVkO1xuICBpZiAoaWQpIHtcbiAgICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoKSA9PiB7XG4gICAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gICAgfSk7XG4gICAgaWYgKGhpZ2hsaWdodCkge1xuICAgICAgY29uc3Qgb3BhY2l0eSA9IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZO1xuICAgICAgaWYgKGlzU1ZHKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJmaWxsXCIsXG4gICAgICAgICAgYHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KWAsXG4gICAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiZmlsbC1vcGFjaXR5XCIsXG4gICAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcInN0cm9rZVwiLFxuICAgICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcInN0cm9rZS1vcGFjaXR5XCIsXG4gICAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCIsXG4gICAgICAgICAgYHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSlgLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHByb2Nlc3NUb3VjaEV2ZW50KHdpbiwgZXYpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgeCA9IGV2LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFg7XG4gIGNvbnN0IHkgPSBldi5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRZO1xuICBpZiAoIV9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeE9mZnNldDtcbiAgbGV0IHlPZmZzZXQ7XG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBib2R5UmVjdC5sZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICBsZXQgZm91bmRIaWdobGlnaHQ7XG4gIGxldCBmb3VuZEVsZW1lbnQ7XG4gIGxldCBmb3VuZFJlY3Q7XG4gIC8vICAgIF9oaWdobGlnaHRzLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAvLyAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoYS5zZWxlY3Rpb25JbmZvKSlcbiAgLy8gICAgICAgIHJldHVybiBhLnNlbGVjdGlvbkluZm8uY2xlYW5UZXh0Lmxlbmd0aCA8IGIuc2VsZWN0aW9uSW5mby5jbGVhblRleHQubGVuZ3RoXG4gIC8vICAgIH0pXG4gIGZvciAobGV0IGkgPSBfaGlnaGxpZ2h0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzW2ldO1xuICAgIGxldCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGhpZ2hsaWdodFBhcmVudCA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYCMke2hpZ2hsaWdodC5pZH1gKTtcbiAgICB9XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBsZXQgaGl0ID0gZmFsc2U7XG4gICAgY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnRzID0gaGlnaGxpZ2h0UGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRGcmFnbWVudCBvZiBoaWdobGlnaHRGcmFnbWVudHMpIHtcbiAgICAgIGNvbnN0IHdpdGhSZWN0ID0gaGlnaGxpZ2h0RnJhZ21lbnQ7XG4gICAgICBjb25zdCBsZWZ0ID0gd2l0aFJlY3QucmVjdC5sZWZ0ICsgeE9mZnNldDtcbiAgICAgIGNvbnN0IHRvcCA9IHdpdGhSZWN0LnJlY3QudG9wICsgeU9mZnNldDtcbiAgICAgIGZvdW5kUmVjdCA9IHdpdGhSZWN0LnJlY3Q7XG4gICAgICBpZiAoXG4gICAgICAgIHggPj0gbGVmdCAmJlxuICAgICAgICB4IDwgbGVmdCArIHdpdGhSZWN0LnJlY3Qud2lkdGggJiZcbiAgICAgICAgeSA+PSB0b3AgJiZcbiAgICAgICAgeSA8IHRvcCArIHdpdGhSZWN0LnJlY3QuaGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgaGl0ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChoaXQpIHtcbiAgICAgIGZvdW5kSGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgZm91bmRFbGVtZW50ID0gaGlnaGxpZ2h0UGFyZW50O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmICghZm91bmRIaWdobGlnaHQgfHwgIWZvdW5kRWxlbWVudCkge1xuICAgIGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5ncyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRCb3VuZGluZyBvZiBoaWdobGlnaHRCb3VuZGluZ3MpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICB9XG4gICAgY29uc3QgYWxsSGlnaGxpZ2h0QXJlYXMgPSBBcnJheS5mcm9tKFxuICAgICAgX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YClcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBhbGxIaWdobGlnaHRBcmVhcykge1xuICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGZvdW5kRWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNsaWNrXCIpKSB7XG4gICAgaWYgKGV2LnR5cGUgPT09IFwibW91c2Vtb3ZlXCIpIHtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgICAgZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0QXJlYXMgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBhbGxIaWdobGlnaHRBcmVhcykge1xuICAgICAgICBpZiAoZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMuaW5kZXhPZihoaWdobGlnaHRBcmVhKSA8IDApIHtcbiAgICAgICAgICByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcywgZm91bmRIaWdobGlnaHQpO1xuICAgICAgY29uc3QgZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcgPSBmb3VuZEVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBjb25zdCBhbGxIaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcgfHxcbiAgICAgICAgICBoaWdobGlnaHRCb3VuZGluZyAhPT0gZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmdcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKHdpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcpIHtcbiAgICAgICAgaWYgKERFQlVHX1ZJU1VBTFMpIHtcbiAgICAgICAgICBzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKFxuICAgICAgICAgICAgd2luLFxuICAgICAgICAgICAgZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcsXG4gICAgICAgICAgICBmb3VuZEhpZ2hsaWdodFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2LnR5cGUgPT09IFwidG91Y2hzdGFydFwiIHx8IGV2LnR5cGUgPT09IFwidG91Y2hlbmRcIikge1xuICAgICAgY29uc3Qgc2l6ZSA9IHtcbiAgICAgICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgICAgICBzY3JlZW5IZWlnaHQ6IHdpbmRvdy5vdXRlckhlaWdodCxcbiAgICAgICAgbGVmdDogZm91bmRSZWN0LmxlZnQsXG4gICAgICAgIHdpZHRoOiBmb3VuZFJlY3Qud2lkdGgsXG4gICAgICAgIHRvcDogZm91bmRSZWN0LnRvcCxcbiAgICAgICAgaGVpZ2h0OiBmb3VuZFJlY3QuaGVpZ2h0LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGhpZ2hsaWdodDogZm91bmRIaWdobGlnaHQuaWQsXG4gICAgICAgIHNpemU6IHNpemUsXG4gICAgICB9O1xuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIHdpbmRvdy5wcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHdpbmRvdy5wcm9jZXNzLnR5cGUgPT09IFwicmVuZGVyZXJcIlxuICAgICAgKSB7XG4gICAgICAgIGVsZWN0cm9uXzEuaXBjUmVuZGVyZXIuc2VuZFRvSG9zdChSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0ssIHBheWxvYWQpO1xuICAgICAgfSBlbHNlIGlmICh3aW5kb3cud2Via2l0VVJMKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGZvdW5kSGlnaGxpZ2h0LmlkLmluY2x1ZGVzKFwiUjJfQU5OT1RBVElPTl9cIikpO1xuICAgICAgICBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfQU5OT1RBVElPTl9cIikgPj0gMCkge1xuICAgICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgICAgICAgICBBbmRyb2lkLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0LmlkXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChmb3VuZEhpZ2hsaWdodC5pZC5zZWFyY2goXCJSMl9ISUdITElHSFRfXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBY3RpdmF0ZWQoZm91bmRIaWdobGlnaHQuaWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgICAgICAgICAgd2Via2l0Lm1lc3NhZ2VIYW5kbGVycy5oaWdobGlnaHRBY3RpdmF0ZWQucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0LmlkXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NNb3VzZUV2ZW50KHdpbiwgZXYpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgeCA9IGV2LmNsaWVudFg7XG4gIGNvbnN0IHkgPSBldi5jbGllbnRZO1xuICBpZiAoIV9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBib2R5UmVjdCA9IGRvY3VtZW50LmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGxldCB4T2Zmc2V0O1xuICBsZXQgeU9mZnNldDtcbiAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCA6IGJvZHlSZWN0LmxlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCA6IGJvZHlSZWN0LnRvcDtcbiAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICB9XG4gIGxldCBmb3VuZEhpZ2hsaWdodDtcbiAgbGV0IGZvdW5kRWxlbWVudDtcbiAgbGV0IGZvdW5kUmVjdDtcbiAgZm9yIChsZXQgaSA9IF9oaWdobGlnaHRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHNbaV07XG4gICAgbGV0IGhpZ2hsaWdodFBhcmVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGAke2hpZ2hsaWdodC5pZH1gKTtcbiAgICBpZiAoIWhpZ2hsaWdodFBhcmVudCkge1xuICAgICAgaGlnaGxpZ2h0UGFyZW50ID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvcihgIyR7aGlnaGxpZ2h0LmlkfWApO1xuICAgIH1cbiAgICBpZiAoIWhpZ2hsaWdodFBhcmVudCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGxldCBoaXQgPSBmYWxzZTtcbiAgICBjb25zdCBoaWdobGlnaHRGcmFnbWVudHMgPSBoaWdobGlnaHRQYXJlbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEZyYWdtZW50IG9mIGhpZ2hsaWdodEZyYWdtZW50cykge1xuICAgICAgY29uc3Qgd2l0aFJlY3QgPSBoaWdobGlnaHRGcmFnbWVudDtcbiAgICAgIGNvbnN0IGxlZnQgPSB3aXRoUmVjdC5yZWN0LmxlZnQgKyB4T2Zmc2V0O1xuICAgICAgY29uc3QgdG9wID0gd2l0aFJlY3QucmVjdC50b3AgKyB5T2Zmc2V0O1xuICAgICAgZm91bmRSZWN0ID0gd2l0aFJlY3QucmVjdDtcbiAgICAgIGlmIChcbiAgICAgICAgeCA+PSBsZWZ0ICYmXG4gICAgICAgIHggPCBsZWZ0ICsgd2l0aFJlY3QucmVjdC53aWR0aCAmJlxuICAgICAgICB5ID49IHRvcCAmJlxuICAgICAgICB5IDwgdG9wICsgd2l0aFJlY3QucmVjdC5oZWlnaHRcbiAgICAgICkge1xuICAgICAgICBoaXQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGhpdCkge1xuICAgICAgZm91bmRIaWdobGlnaHQgPSBoaWdobGlnaHQ7XG4gICAgICBmb3VuZEVsZW1lbnQgPSBoaWdobGlnaHRQYXJlbnQ7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoIWZvdW5kSGlnaGxpZ2h0IHx8ICFmb3VuZEVsZW1lbnQpIHtcbiAgICBjb25zdCBoaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgaGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgfVxuICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmb3VuZEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jbGlja1wiKSkge1xuICAgIGlmIChldi50eXBlID09PSBcIm1vdXNlbW92ZVwiKSB7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICAgIGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLmluZGV4T2YoaGlnaGxpZ2h0QXJlYSkgPCAwKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMsIGZvdW5kSGlnaGxpZ2h0KTtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nID0gZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGFsbEhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIHx8XG4gICAgICAgICAgaGlnaGxpZ2h0Qm91bmRpbmcgIT09IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nXG4gICAgICAgICkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gICAgICAgIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgICAgICAgc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZShcbiAgICAgICAgICAgIHdpbixcbiAgICAgICAgICAgIGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nLFxuICAgICAgICAgICAgZm91bmRIaWdobGlnaHRcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChldi50eXBlID09PSBcIm1vdXNldXBcIiB8fCBldi50eXBlID09PSBcInRvdWNoZW5kXCIpIHtcbiAgICAgIGNvbnN0IHRvdWNoZWRQb3NpdGlvbiA9IHtcbiAgICAgICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgICAgICBzY3JlZW5IZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICAgICAgbGVmdDogZm91bmRSZWN0LmxlZnQsXG4gICAgICAgIHdpZHRoOiBmb3VuZFJlY3Qud2lkdGgsXG4gICAgICAgIHRvcDogZm91bmRSZWN0LnRvcCxcbiAgICAgICAgaGVpZ2h0OiBmb3VuZFJlY3QuaGVpZ2h0LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgaGlnaGxpZ2h0OiBmb3VuZEhpZ2hsaWdodCxcbiAgICAgICAgcG9zaXRpb246IHRvdWNoZWRQb3NpdGlvbixcbiAgICAgIH07XG5cbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICB0eXBlb2Ygd2luZG93LnByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgd2luZG93LnByb2Nlc3MudHlwZSA9PT0gXCJyZW5kZXJlclwiXG4gICAgICApIHtcbiAgICAgICAgZWxlY3Ryb25fMS5pcGNSZW5kZXJlci5zZW5kVG9Ib3N0KFIyX0VWRU5UX0hJR0hMSUdIVF9DTElDSywgcGF5bG9hZCk7XG4gICAgICB9IGVsc2UgaWYgKHdpbmRvdy53ZWJraXRVUkwpIHtcbiAgICAgICAgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0FOTk9UQVRJT05fXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfSElHSExJR0hUX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICAocmVjdDEubGVmdCA8IHJlY3QyLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi5sZWZ0IDwgcmVjdDEucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi5sZWZ0LCByZWN0MS5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QxLnRvcCA8IHJlY3QyLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIudG9wIDwgcmVjdDEuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIudG9wLCByZWN0MS5ib3R0b20sIHRvbGVyYW5jZSkpKVxuICApO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKHJlY3RzKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCByZWN0cy5sZW5ndGg7IGorKykge1xuICAgICAgY29uc3QgcmVjdDEgPSByZWN0c1tpXTtcbiAgICAgIGNvbnN0IHJlY3QyID0gcmVjdHNbal07XG4gICAgICBpZiAocmVjdDEgPT09IHJlY3QyKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcInJlcGxhY2VPdmVybGFwaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgLTEpKSB7XG4gICAgICAgIGxldCB0b0FkZCA9IFtdO1xuICAgICAgICBsZXQgdG9SZW1vdmU7XG4gICAgICAgIGxldCB0b1ByZXNlcnZlO1xuICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMSA9IHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpO1xuICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMTtcbiAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgIHRvUHJlc2VydmUgPSByZWN0MjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMiA9IHJlY3RTdWJ0cmFjdChyZWN0MiwgcmVjdDEpO1xuICAgICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPCBzdWJ0cmFjdFJlY3RzMi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgICAgdG9QcmVzZXJ2ZSA9IHJlY3QyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMyO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MjtcbiAgICAgICAgICAgIHRvUHJlc2VydmUgPSByZWN0MTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnN0IHRvQ2hlY2sgPSBbXTtcbiAgICAgICAgICB0b0NoZWNrLnB1c2godG9QcmVzZXJ2ZSk7XG4gICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkodG9DaGVjaywgdG9BZGQpO1xuICAgICAgICAgIGNoZWNrT3ZlcmxhcHModG9DaGVjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYENMSUVOVCBSRUNUOiBvdmVybGFwLCBjdXQgb25lIHJlY3QgaW50byAke3RvQWRkLmxlbmd0aH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSB0b1JlbW92ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KG5ld1JlY3RzLCB0b0FkZCk7XG4gICAgICAgIHJldHVybiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5ld1JlY3RzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiBjaGVja092ZXJsYXBzKHJlY3RzKSB7XG4gIGNvbnN0IHN0aWxsT3ZlcmxhcGluZ1JlY3RzID0gW107XG4gIGZvciAoY29uc3QgcmVjdDEgb2YgcmVjdHMpIHtcbiAgICBmb3IgKGNvbnN0IHJlY3QyIG9mIHJlY3RzKSB7XG4gICAgICBpZiAocmVjdDEgPT09IHJlY3QyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgaGFzMSA9IHN0aWxsT3ZlcmxhcGluZ1JlY3RzLmluZGV4T2YocmVjdDEpID49IDA7XG4gICAgICBjb25zdCBoYXMyID0gc3RpbGxPdmVybGFwaW5nUmVjdHMuaW5kZXhPZihyZWN0MikgPj0gMDtcbiAgICAgIGlmICghaGFzMSB8fCAhaGFzMikge1xuICAgICAgICBpZiAocmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIC0xKSkge1xuICAgICAgICAgIGlmICghaGFzMSkge1xuICAgICAgICAgICAgc3RpbGxPdmVybGFwaW5nUmVjdHMucHVzaChyZWN0MSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghaGFzMikge1xuICAgICAgICAgICAgc3RpbGxPdmVybGFwaW5nUmVjdHMucHVzaChyZWN0Mik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IG92ZXJsYXAgLS0tXCIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYCMxIFRPUDoke3JlY3QxLnRvcH0gQk9UVE9NOiR7cmVjdDEuYm90dG9tfSBMRUZUOiR7cmVjdDEubGVmdH0gUklHSFQ6JHtyZWN0MS5yaWdodH0gV0lEVEg6JHtyZWN0MS53aWR0aH0gSEVJR0hUOiR7cmVjdDEuaGVpZ2h0fWBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYCMyIFRPUDoke3JlY3QyLnRvcH0gQk9UVE9NOiR7cmVjdDIuYm90dG9tfSBMRUZUOiR7cmVjdDIubGVmdH0gUklHSFQ6JHtyZWN0Mi5yaWdodH0gV0lEVEg6JHtyZWN0Mi53aWR0aH0gSEVJR0hUOiR7cmVjdDIuaGVpZ2h0fWBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHhPdmVybGFwID0gZ2V0UmVjdE92ZXJsYXBYKHJlY3QxLCByZWN0Mik7XG4gICAgICAgICAgY29uc29sZS5sb2coYHhPdmVybGFwOiAke3hPdmVybGFwfWApO1xuICAgICAgICAgIGNvbnN0IHlPdmVybGFwID0gZ2V0UmVjdE92ZXJsYXBZKHJlY3QxLCByZWN0Mik7XG4gICAgICAgICAgY29uc29sZS5sb2coYHlPdmVybGFwOiAke3lPdmVybGFwfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChzdGlsbE92ZXJsYXBpbmdSZWN0cy5sZW5ndGgpIHtcbiAgICBjb25zb2xlLmxvZyhgQ0xJRU5UIFJFQ1Q6IG92ZXJsYXBzICR7c3RpbGxPdmVybGFwaW5nUmVjdHMubGVuZ3RofWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNvbnRhaW5lZFJlY3RzKHJlY3RzLCB0b2xlcmFuY2UpIHtcbiAgY29uc3QgcmVjdHNUb0tlZXAgPSBuZXcgU2V0KHJlY3RzKTtcbiAgZm9yIChjb25zdCByZWN0IG9mIHJlY3RzKSB7XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCA+IDEgJiYgcmVjdC5oZWlnaHQgPiAxO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSB0aW55XCIpO1xuICAgICAgfVxuICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcG9zc2libHlDb250YWluaW5nUmVjdCBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QgPT09IHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIXJlY3RzVG9LZWVwLmhhcyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0Q29udGFpbnMocG9zc2libHlDb250YWluaW5nUmVjdCwgcmVjdCwgdG9sZXJhbmNlKSkge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIGNvbnRhaW5lZFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gQXJyYXkuZnJvbShyZWN0c1RvS2VlcCk7XG59XG5cbmZ1bmN0aW9uIGFsbW9zdEVxdWFsKGEsIGIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gTWF0aC5hYnMoYSAtIGIpIDw9IHRvbGVyYW5jZTtcbn1cblxuZnVuY3Rpb24gcmVjdEludGVyc2VjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbWF4TGVmdCA9IE1hdGgubWF4KHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCBtaW5SaWdodCA9IE1hdGgubWluKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IG1heFRvcCA9IE1hdGgubWF4KHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgbWluQm90dG9tID0gTWF0aC5taW4ocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICBjb25zdCByZWN0ID0ge1xuICAgIGJvdHRvbTogbWluQm90dG9tLFxuICAgIGhlaWdodDogTWF0aC5tYXgoMCwgbWluQm90dG9tIC0gbWF4VG9wKSxcbiAgICBsZWZ0OiBtYXhMZWZ0LFxuICAgIHJpZ2h0OiBtaW5SaWdodCxcbiAgICB0b3A6IG1heFRvcCxcbiAgICB3aWR0aDogTWF0aC5tYXgoMCwgbWluUmlnaHQgLSBtYXhMZWZ0KSxcbiAgfTtcbiAgcmV0dXJuIHJlY3Q7XG59XG5cbmZ1bmN0aW9uIHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgcmVjdEludGVyc2VjdGVkID0gcmVjdEludGVyc2VjdChyZWN0MiwgcmVjdDEpO1xuICBpZiAocmVjdEludGVyc2VjdGVkLmhlaWdodCA9PT0gMCB8fCByZWN0SW50ZXJzZWN0ZWQud2lkdGggPT09IDApIHtcbiAgICByZXR1cm4gW3JlY3QxXTtcbiAgfVxuICBjb25zdCByZWN0cyA9IFtdO1xuICB7XG4gICAgY29uc3QgcmVjdEEgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3QxLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEEud2lkdGggPSByZWN0QS5yaWdodCAtIHJlY3RBLmxlZnQ7XG4gICAgcmVjdEEuaGVpZ2h0ID0gcmVjdEEuYm90dG9tIC0gcmVjdEEudG9wO1xuICAgIGlmIChyZWN0QS5oZWlnaHQgIT09IDAgJiYgcmVjdEEud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEEpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEIgPSB7XG4gICAgICBib3R0b206IHJlY3RJbnRlcnNlY3RlZC50b3AsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEIud2lkdGggPSByZWN0Qi5yaWdodCAtIHJlY3RCLmxlZnQ7XG4gICAgcmVjdEIuaGVpZ2h0ID0gcmVjdEIuYm90dG9tIC0gcmVjdEIudG9wO1xuICAgIGlmIChyZWN0Qi5oZWlnaHQgIT09IDAgJiYgcmVjdEIud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEIpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEMgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdEludGVyc2VjdGVkLmJvdHRvbSxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEMud2lkdGggPSByZWN0Qy5yaWdodCAtIHJlY3RDLmxlZnQ7XG4gICAgcmVjdEMuaGVpZ2h0ID0gcmVjdEMuYm90dG9tIC0gcmVjdEMudG9wO1xuICAgIGlmIChyZWN0Qy5oZWlnaHQgIT09IDAgJiYgcmVjdEMud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEMpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEQgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHJpZ2h0OiByZWN0MS5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0RC53aWR0aCA9IHJlY3RELnJpZ2h0IC0gcmVjdEQubGVmdDtcbiAgICByZWN0RC5oZWlnaHQgPSByZWN0RC5ib3R0b20gLSByZWN0RC50b3A7XG4gICAgaWYgKHJlY3RELmhlaWdodCAhPT0gMCAmJiByZWN0RC53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0RCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gcmVjdENvbnRhaW5zUG9pbnQocmVjdCwgeCwgeSwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QubGVmdCA8IHggfHwgYWxtb3N0RXF1YWwocmVjdC5sZWZ0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnJpZ2h0ID4geCB8fCBhbG1vc3RFcXVhbChyZWN0LnJpZ2h0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnRvcCA8IHkgfHwgYWxtb3N0RXF1YWwocmVjdC50b3AsIHksIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QuYm90dG9tID4geSB8fCBhbG1vc3RFcXVhbChyZWN0LmJvdHRvbSwgeSwgdG9sZXJhbmNlKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVjdENvbnRhaW5zKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLmxlZnQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5yaWdodCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLmxlZnQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5yaWdodCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbGVmdCA9IE1hdGgubWluKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCByaWdodCA9IE1hdGgubWF4KHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IHRvcCA9IE1hdGgubWluKHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgYm90dG9tID0gTWF0aC5tYXgocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbSxcbiAgICBoZWlnaHQ6IGJvdHRvbSAtIHRvcCxcbiAgICBsZWZ0LFxuICAgIHJpZ2h0LFxuICAgIHRvcCxcbiAgICB3aWR0aDogcmlnaHQgLSBsZWZ0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gIHJlY3RzLFxuICB0b2xlcmFuY2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJtZXJnZVRvdWNoaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwVmVydGljYWxseSA9XG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpO1xuICAgICAgY29uc3QgcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0LCB0b2xlcmFuY2UpICYmXG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IGhvcml6b250YWxBbGxvd2VkID0gIWRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHM7XG4gICAgICBjb25zdCBhbGlnbmVkID1cbiAgICAgICAgKHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ICYmIGhvcml6b250YWxBbGxvd2VkKSB8fFxuICAgICAgICAocmVjdHNMaW5lVXBWZXJ0aWNhbGx5ICYmICFyZWN0c0xpbmVVcEhvcml6b250YWxseSk7XG4gICAgICBjb25zdCBjYW5NZXJnZSA9IGFsaWduZWQgJiYgcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSk7XG4gICAgICBpZiAoY2FuTWVyZ2UpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYENMSUVOVCBSRUNUOiBtZXJnaW5nIHR3byBpbnRvIG9uZSwgVkVSVElDQUw6ICR7cmVjdHNMaW5lVXBWZXJ0aWNhbGx5fSBIT1JJWk9OVEFMOiAke3JlY3RzTGluZVVwSG9yaXpvbnRhbGx5fSAoJHtkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzfSlgXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSByZWN0MSAmJiByZWN0ICE9PSByZWN0MjtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcGxhY2VtZW50Q2xpZW50UmVjdCA9IGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpO1xuICAgICAgICBuZXdSZWN0cy5wdXNoKHJlcGxhY2VtZW50Q2xpZW50UmVjdCk7XG4gICAgICAgIHJldHVybiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gICAgICAgICAgbmV3UmVjdHMsXG4gICAgICAgICAgdG9sZXJhbmNlLFxuICAgICAgICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChyYW5nZSwgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cykge1xuICBjb25zdCByYW5nZUNsaWVudFJlY3RzID0gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgcmV0dXJuIGdldENsaWVudFJlY3RzTm9PdmVybGFwXyhcbiAgICByYW5nZUNsaWVudFJlY3RzLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXBfKFxuICBjbGllbnRSZWN0cyxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGNvbnN0IHRvbGVyYW5jZSA9IDE7XG4gIGNvbnN0IG9yaWdpbmFsUmVjdHMgPSBbXTtcbiAgZm9yIChjb25zdCByYW5nZUNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBvcmlnaW5hbFJlY3RzLnB1c2goe1xuICAgICAgYm90dG9tOiByYW5nZUNsaWVudFJlY3QuYm90dG9tLFxuICAgICAgaGVpZ2h0OiByYW5nZUNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgbGVmdDogcmFuZ2VDbGllbnRSZWN0LmxlZnQsXG4gICAgICByaWdodDogcmFuZ2VDbGllbnRSZWN0LnJpZ2h0LFxuICAgICAgdG9wOiByYW5nZUNsaWVudFJlY3QudG9wLFxuICAgICAgd2lkdGg6IHJhbmdlQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9KTtcbiAgfVxuICBjb25zdCBtZXJnZWRSZWN0cyA9IG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICBvcmlnaW5hbFJlY3RzLFxuICAgIHRvbGVyYW5jZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG4gIGNvbnN0IG5vQ29udGFpbmVkUmVjdHMgPSByZW1vdmVDb250YWluZWRSZWN0cyhtZXJnZWRSZWN0cywgdG9sZXJhbmNlKTtcbiAgY29uc3QgbmV3UmVjdHMgPSByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5vQ29udGFpbmVkUmVjdHMpO1xuICBjb25zdCBtaW5BcmVhID0gMiAqIDI7XG4gIGZvciAobGV0IGogPSBuZXdSZWN0cy5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgIGNvbnN0IHJlY3QgPSBuZXdSZWN0c1tqXTtcbiAgICBjb25zdCBiaWdFbm91Z2ggPSByZWN0LndpZHRoICogcmVjdC5oZWlnaHQgPiBtaW5BcmVhO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBpZiAobmV3UmVjdHMubGVuZ3RoID4gMSkge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsXCIpO1xuICAgICAgICB9XG4gICAgICAgIG5ld1JlY3RzLnNwbGljZShqLCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGwsIGJ1dCBrZWVwIG90aGVyd2lzZSBlbXB0eSFcIik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChJU19ERVYpIHtcbiAgICBjaGVja092ZXJsYXBzKG5ld1JlY3RzKTtcbiAgfVxuICBpZiAoSVNfREVWKSB7XG4gICAgY29uc29sZS5sb2coXG4gICAgICBgQ0xJRU5UIFJFQ1Q6IHJlZHVjZWQgJHtvcmlnaW5hbFJlY3RzLmxlbmd0aH0gLS0+ICR7bmV3UmVjdHMubGVuZ3RofWBcbiAgICApO1xuICB9XG4gIHJldHVybiBuZXdSZWN0cztcbn1cblxuZnVuY3Rpb24gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpIHtcbiAgcmV0dXJuIChcbiAgICBkb2N1bWVudCAmJlxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJlxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfUEFHSU5BVEVEKVxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KSB7XG4gIGlmIChkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50KSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQ7XG4gIH1cbiAgcmV0dXJuIGRvY3VtZW50LmJvZHk7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUNvbnRhaW5lcih3aW4sIGFubm90YXRpb25GbGFnKSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuXG4gIGlmICghX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICBpZiAoIWJvZHlFdmVudExpc3RlbmVyc1NldCkge1xuICAgICAgYm9keUV2ZW50TGlzdGVuZXJzU2V0ID0gdHJ1ZTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJtb3VzZWRvd25cIixcbiAgICAgICAgKGV2KSA9PiB7XG4gICAgICAgICAgbGFzdE1vdXNlRG93blggPSBldi5jbGllbnRYO1xuICAgICAgICAgIGxhc3RNb3VzZURvd25ZID0gZXYuY2xpZW50WTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwibW91c2V1cFwiLFxuICAgICAgICAoZXYpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBNYXRoLmFicyhsYXN0TW91c2VEb3duWCAtIGV2LmNsaWVudFgpIDwgMyAmJlxuICAgICAgICAgICAgTWF0aC5hYnMobGFzdE1vdXNlRG93blkgLSBldi5jbGllbnRZKSA8IDNcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHByb2Nlc3NNb3VzZUV2ZW50KHdpbiwgZXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwibW91c2Vtb3ZlXCIsXG4gICAgICAgIChldikgPT4ge1xuICAgICAgICAgIHByb2Nlc3NNb3VzZUV2ZW50KHdpbiwgZXYpO1xuICAgICAgICB9LFxuICAgICAgICBmYWxzZVxuICAgICAgKTtcblxuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcInRvdWNoZW5kXCIsXG4gICAgICAgIGZ1bmN0aW9uIHRvdWNoRW5kKGUpIHtcbiAgICAgICAgICBwcm9jZXNzVG91Y2hFdmVudCh3aW4sIGUpO1xuICAgICAgICB9LFxuICAgICAgICBmYWxzZVxuICAgICAgKTtcbiAgICB9XG4gICAgX2hpZ2hsaWdodHNDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSKTtcblxuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKF9oaWdobGlnaHRzQ29udGFpbmVyKTtcbiAgfVxuXG4gIHJldHVybiBfaGlnaGxpZ2h0c0NvbnRhaW5lcjtcbn1cblxuZnVuY3Rpb24gaGlkZUFsbGhpZ2hsaWdodHMoKSB7XG4gIGlmIChfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnJlbW92ZSgpO1xuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZXN0cm95QWxsaGlnaGxpZ2h0cygpIHtcbiAgaGlkZUFsbGhpZ2hsaWdodHMoKTtcbiAgX2hpZ2hsaWdodHMuc3BsaWNlKDAsIF9oaWdobGlnaHRzLmxlbmd0aCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXN0cm95SGlnaGxpZ2h0KGlkKSB7XG4gIGxldCBpID0gLTE7XG4gIGxldCBfZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzLmZpbmQoKGgsIGopID0+IHtcbiAgICBpID0gajtcbiAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gIH0pO1xuICBpZiAoaGlnaGxpZ2h0ICYmIGkgPj0gMCAmJiBpIDwgX2hpZ2hsaWdodHMubGVuZ3RoKSB7XG4gICAgX2hpZ2hsaWdodHMuc3BsaWNlKGksIDEpO1xuICB9XG4gIGNvbnN0IGhpZ2hsaWdodENvbnRhaW5lciA9IF9kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gIGlmIChoaWdobGlnaHRDb250YWluZXIpIHtcbiAgICBoaWdobGlnaHRDb250YWluZXIucmVtb3ZlKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDZmlUZXh0Tm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KGVsZW1lbnQsIGNoaWxkKSB7XG4gIGxldCBmb3VuZCA9IC0xO1xuICBsZXQgdGV4dE5vZGVJbmRleCA9IC0xO1xuICBsZXQgcHJldmlvdXNXYXNFbGVtZW50ID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGROb2RlID0gZWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuICAgIGNvbnN0IGlzVGV4dCA9IGlzQ2ZpVGV4dE5vZGUoY2hpbGROb2RlKTtcbiAgICBpZiAoaXNUZXh0IHx8IHByZXZpb3VzV2FzRWxlbWVudCkge1xuICAgICAgdGV4dE5vZGVJbmRleCArPSAyO1xuICAgIH1cbiAgICBpZiAoaXNUZXh0KSB7XG4gICAgICBpZiAoY2hpbGROb2RlID09PSBjaGlsZCkge1xuICAgICAgICBmb3VuZCA9IHRleHROb2RlSW5kZXg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBwcmV2aW91c1dhc0VsZW1lbnQgPSBjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFO1xuICB9XG4gIHJldHVybiBmb3VuZDtcbn1cblxuZnVuY3Rpb24gZ2V0Q29tbW9uQW5jZXN0b3JFbGVtZW50KG5vZGUxLCBub2RlMikge1xuICBpZiAobm9kZTEubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIG5vZGUxID09PSBub2RlMikge1xuICAgIHJldHVybiBub2RlMTtcbiAgfVxuICBpZiAobm9kZTEubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIG5vZGUxLmNvbnRhaW5zKG5vZGUyKSkge1xuICAgIHJldHVybiBub2RlMTtcbiAgfVxuICBpZiAobm9kZTIubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIG5vZGUyLmNvbnRhaW5zKG5vZGUxKSkge1xuICAgIHJldHVybiBub2RlMjtcbiAgfVxuICBjb25zdCBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluID0gW107XG4gIGxldCBwYXJlbnQgPSBub2RlMS5wYXJlbnROb2RlO1xuICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluLnB1c2gocGFyZW50KTtcbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgfVxuICBjb25zdCBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluID0gW107XG4gIHBhcmVudCA9IG5vZGUyLnBhcmVudE5vZGU7XG4gIHdoaWxlIChwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIG5vZGUyRWxlbWVudEFuY2VzdG9yQ2hhaW4ucHVzaChwYXJlbnQpO1xuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xuICB9XG4gIGxldCBjb21tb25BbmNlc3RvciA9IG5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4uZmluZChcbiAgICAobm9kZTFFbGVtZW50QW5jZXN0b3IpID0+IHtcbiAgICAgIHJldHVybiBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluLmluZGV4T2Yobm9kZTFFbGVtZW50QW5jZXN0b3IpID49IDA7XG4gICAgfVxuICApO1xuICBpZiAoIWNvbW1vbkFuY2VzdG9yKSB7XG4gICAgY29tbW9uQW5jZXN0b3IgPSBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluLmZpbmQoKG5vZGUyRWxlbWVudEFuY2VzdG9yKSA9PiB7XG4gICAgICByZXR1cm4gbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbi5pbmRleE9mKG5vZGUyRWxlbWVudEFuY2VzdG9yKSA+PSAwO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBjb21tb25BbmNlc3Rvcjtcbn1cblxuZnVuY3Rpb24gZnVsbFF1YWxpZmllZFNlbGVjdG9yKG5vZGUpIHtcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgY29uc3QgbG93ZXJDYXNlTmFtZSA9XG4gICAgICAobm9kZS5sb2NhbE5hbWUgJiYgbm9kZS5sb2NhbE5hbWUudG9Mb3dlckNhc2UoKSkgfHxcbiAgICAgIG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICByZXR1cm4gbG93ZXJDYXNlTmFtZTtcbiAgfVxuICAvL3JldHVybiBjc3NQYXRoKG5vZGUsIGp1c3RTZWxlY3Rvcik7XG4gIHJldHVybiBjc3NQYXRoKG5vZGUsIHRydWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8oKSB7XG4gIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBTRUxFQ1RJT04gQ09MTEFQU0VELlwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJhd1RleHQgPSBzZWxlY3Rpb24udG9TdHJpbmcoKTtcbiAgY29uc3QgY2xlYW5UZXh0ID0gcmF3VGV4dC50cmltKCkucmVwbGFjZSgvXFxuL2csIFwiIFwiKS5yZXBsYWNlKC9cXHNcXHMrL2csIFwiIFwiKTtcbiAgaWYgKGNsZWFuVGV4dC5sZW5ndGggPT09IDApIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBTRUxFQ1RJT04gVEVYVCBFTVBUWS5cIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoIXNlbGVjdGlvbi5hbmNob3JOb2RlIHx8ICFzZWxlY3Rpb24uZm9jdXNOb2RlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYW5nZSA9XG4gICAgc2VsZWN0aW9uLnJhbmdlQ291bnQgPT09IDFcbiAgICAgID8gc2VsZWN0aW9uLmdldFJhbmdlQXQoMClcbiAgICAgIDogY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNPZmZzZXRcbiAgICAgICAgKTtcbiAgaWYgKCFyYW5nZSB8fCByYW5nZS5jb2xsYXBzZWQpIHtcbiAgICBjb25zb2xlLmxvZyhcIiQkJCQkJCQkJCQkJCQkJCQkIENBTk5PVCBHRVQgTk9OLUNPTExBUFNFRCBTRUxFQ1RJT04gUkFOR0U/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJhbmdlSW5mbyA9IGNvbnZlcnRSYW5nZShyYW5nZSwgZnVsbFF1YWxpZmllZFNlbGVjdG9yLCBjb21wdXRlQ0ZJKTtcbiAgaWYgKCFyYW5nZUluZm8pIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBTRUxFQ1RJT04gUkFOR0UgSU5GTyBGQUlMPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmIChJU19ERVYgJiYgREVCVUdfVklTVUFMUykge1xuICAgIGNvbnN0IHJlc3RvcmVkUmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKHdpbi5kb2N1bWVudCwgcmFuZ2VJbmZvKTtcbiAgICBpZiAocmVzdG9yZWRSYW5nZSkge1xuICAgICAgaWYgKFxuICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0T2Zmc2V0ID09PSByYW5nZS5zdGFydE9mZnNldCAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLmVuZE9mZnNldCA9PT0gcmFuZ2UuZW5kT2Zmc2V0ICYmXG4gICAgICAgIHJlc3RvcmVkUmFuZ2Uuc3RhcnRDb250YWluZXIgPT09IHJhbmdlLnN0YXJ0Q29udGFpbmVyICYmXG4gICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kQ29udGFpbmVyID09PSByYW5nZS5lbmRDb250YWluZXJcbiAgICAgICkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIlNFTEVDVElPTiBSQU5HRSBSRVNUT1JFRCBPS0FZIChkZXYgY2hlY2spLlwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiU0VMRUNUSU9OIFJBTkdFIFJFU1RPUkUgRkFJTCAoZGV2IGNoZWNrKS5cIik7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIlNFTEVDVElPTlwiLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNPZmZzZXQsXG4gICAgICAgICAgZ2V0Q3NzU2VsZWN0b3JcbiAgICAgICAgKTtcbiAgICAgICAgZHVtcERlYnVnKFxuICAgICAgICAgIFwiT1JERVJFRCBSQU5HRSBGUk9NIFNFTEVDVElPTlwiLFxuICAgICAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgICAgIHJhbmdlLmVuZENvbnRhaW5lcixcbiAgICAgICAgICByYW5nZS5lbmRPZmZzZXQsXG4gICAgICAgICAgZ2V0Q3NzU2VsZWN0b3JcbiAgICAgICAgKTtcbiAgICAgICAgZHVtcERlYnVnKFxuICAgICAgICAgIFwiUkVTVE9SRUQgUkFOR0VcIixcbiAgICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRDb250YWluZXIsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRPZmZzZXQsXG4gICAgICAgICAgZ2V0Q3NzU2VsZWN0b3JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5sb2coXCJDQU5OT1QgUkVTVE9SRSBTRUxFQ1RJT04gUkFOR0UgPz8hXCIpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbG9jYXRpb25zOiByYW5nZUluZm8yTG9jYXRpb24ocmFuZ2VJbmZvKSxcbiAgICB0ZXh0OiB7XG4gICAgICBoaWdobGlnaHQ6IHJhd1RleHQsXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2hlY2tCbGFja2xpc3RlZChlbCkge1xuICBsZXQgYmxhY2tsaXN0ZWRJZDtcbiAgY29uc3QgaWQgPSBlbC5nZXRBdHRyaWJ1dGUoXCJpZFwiKTtcbiAgaWYgKGlkICYmIF9ibGFja2xpc3RJZENsYXNzRm9yQ0ZJLmluZGV4T2YoaWQpID49IDApIHtcbiAgICBjb25zb2xlLmxvZyhcImNoZWNrQmxhY2tsaXN0ZWQgSUQ6IFwiICsgaWQpO1xuICAgIGJsYWNrbGlzdGVkSWQgPSBpZDtcbiAgfVxuICBsZXQgYmxhY2tsaXN0ZWRDbGFzcztcbiAgZm9yIChjb25zdCBpdGVtIG9mIF9ibGFja2xpc3RJZENsYXNzRm9yQ0ZJKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdC5jb250YWlucyhpdGVtKSkge1xuICAgICAgY29uc29sZS5sb2coXCJjaGVja0JsYWNrbGlzdGVkIENMQVNTOiBcIiArIGl0ZW0pO1xuICAgICAgYmxhY2tsaXN0ZWRDbGFzcyA9IGl0ZW07XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKGJsYWNrbGlzdGVkSWQgfHwgYmxhY2tsaXN0ZWRDbGFzcykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjc3NQYXRoKG5vZGUsIG9wdGltaXplZCkge1xuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gXCJcIjtcbiAgfVxuXG4gIGNvbnN0IHN0ZXBzID0gW107XG4gIGxldCBjb250ZXh0Tm9kZSA9IG5vZGU7XG4gIHdoaWxlIChjb250ZXh0Tm9kZSkge1xuICAgIGNvbnN0IHN0ZXAgPSBfY3NzUGF0aFN0ZXAoY29udGV4dE5vZGUsICEhb3B0aW1pemVkLCBjb250ZXh0Tm9kZSA9PT0gbm9kZSk7XG4gICAgaWYgKCFzdGVwKSB7XG4gICAgICBicmVhazsgLy8gRXJyb3IgLSBiYWlsIG91dCBlYXJseS5cbiAgICB9XG4gICAgc3RlcHMucHVzaChzdGVwLnZhbHVlKTtcbiAgICBpZiAoc3RlcC5vcHRpbWl6ZWQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb250ZXh0Tm9kZSA9IGNvbnRleHROb2RlLnBhcmVudE5vZGU7XG4gIH1cbiAgc3RlcHMucmV2ZXJzZSgpO1xuICByZXR1cm4gc3RlcHMuam9pbihcIiA+IFwiKTtcbn1cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbi8vIGh0dHBzOi8vY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9ibGluay8rL21hc3Rlci9Tb3VyY2UvZGV2dG9vbHMvZnJvbnRfZW5kL2NvbXBvbmVudHMvRE9NUHJlc2VudGF0aW9uVXRpbHMuanMjMzE2XG5mdW5jdGlvbiBfY3NzUGF0aFN0ZXAobm9kZSwgb3B0aW1pemVkLCBpc1RhcmdldE5vZGUpIHtcbiAgZnVuY3Rpb24gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhuZCkge1xuICAgIGNvbnN0IGNsYXNzQXR0cmlidXRlID0gbmQuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIik7XG4gICAgaWYgKCFjbGFzc0F0dHJpYnV0ZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBjbGFzc0F0dHJpYnV0ZVxuICAgICAgLnNwbGl0KC9cXHMrL2cpXG4gICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAubWFwKChubSkgPT4ge1xuICAgICAgICAvLyBUaGUgcHJlZml4IGlzIHJlcXVpcmVkIHRvIHN0b3JlIFwiX19wcm90b19fXCIgaW4gYSBvYmplY3QtYmFzZWQgbWFwLlxuICAgICAgICByZXR1cm4gXCIkXCIgKyBubTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaWRTZWxlY3RvcihpZGQpIHtcbiAgICByZXR1cm4gXCIjXCIgKyBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQoaWRkKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVzY2FwZUlkZW50aWZpZXJJZk5lZWRlZChpZGVudCkge1xuICAgIGlmIChpc0NTU0lkZW50aWZpZXIoaWRlbnQpKSB7XG4gICAgICByZXR1cm4gaWRlbnQ7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hvdWxkRXNjYXBlRmlyc3QgPSAvXig/OlswLTldfC1bMC05LV0/KS8udGVzdChpZGVudCk7XG4gICAgY29uc3QgbGFzdEluZGV4ID0gaWRlbnQubGVuZ3RoIC0gMTtcbiAgICByZXR1cm4gaWRlbnQucmVwbGFjZSgvLi9nLCBmdW5jdGlvbiAoYywgaWkpIHtcbiAgICAgIHJldHVybiAoc2hvdWxkRXNjYXBlRmlyc3QgJiYgaWkgPT09IDApIHx8ICFpc0NTU0lkZW50Q2hhcihjKVxuICAgICAgICA/IGVzY2FwZUFzY2lpQ2hhcihjLCBpaSA9PT0gbGFzdEluZGV4KVxuICAgICAgICA6IGM7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBlc2NhcGVBc2NpaUNoYXIoYywgaXNMYXN0KSB7XG4gICAgcmV0dXJuIFwiXFxcXFwiICsgdG9IZXhCeXRlKGMpICsgKGlzTGFzdCA/IFwiXCIgOiBcIiBcIik7XG4gIH1cblxuICBmdW5jdGlvbiB0b0hleEJ5dGUoYykge1xuICAgIGxldCBoZXhCeXRlID0gYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KTtcbiAgICBpZiAoaGV4Qnl0ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgIGhleEJ5dGUgPSBcIjBcIiArIGhleEJ5dGU7XG4gICAgfVxuICAgIHJldHVybiBoZXhCeXRlO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNDU1NJZGVudENoYXIoYykge1xuICAgIGlmICgvW2EtekEtWjAtOV8tXS8udGVzdChjKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBjLmNoYXJDb2RlQXQoMCkgPj0gMHhhMDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQ1NTSWRlbnRpZmllcih2YWx1ZSkge1xuICAgIHJldHVybiAvXi0/W2EtekEtWl9dW2EtekEtWjAtOV8tXSokLy50ZXN0KHZhbHVlKTtcbiAgfVxuXG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgbG93ZXJDYXNlTmFtZSA9XG4gICAgKG5vZGUubG9jYWxOYW1lICYmIG5vZGUubG9jYWxOYW1lLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gIGNvbnN0IGVsZW1lbnQgPSBub2RlO1xuXG4gIGNvbnN0IGlkID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJpZFwiKTtcblxuICBpZiAob3B0aW1pemVkKSB7XG4gICAgaWYgKGlkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICAgIHZhbHVlOiBpZFNlbGVjdG9yKGlkKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGxvd2VyQ2FzZU5hbWUgPT09IFwiYm9keVwiIHx8XG4gICAgICBsb3dlckNhc2VOYW1lID09PSBcImhlYWRcIiB8fFxuICAgICAgbG93ZXJDYXNlTmFtZSA9PT0gXCJodG1sXCJcbiAgICApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGxvd2VyQ2FzZU5hbWUsIC8vIG5vZGUubm9kZU5hbWVJbkNvcnJlY3RDYXNlKCksXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5vZGVOYW1lID0gbG93ZXJDYXNlTmFtZTsgLy8gbm9kZS5ub2RlTmFtZUluQ29ycmVjdENhc2UoKTtcbiAgaWYgKGlkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgIHZhbHVlOiBub2RlTmFtZSArIGlkU2VsZWN0b3IoaWQpLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XG5cbiAgaWYgKCFwYXJlbnQgfHwgcGFyZW50Lm5vZGVUeXBlID09PSBOb2RlLkRPQ1VNRU5UX05PREUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgb3B0aW1pemVkOiB0cnVlLFxuICAgICAgdmFsdWU6IG5vZGVOYW1lLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheV8gPSBwcmVmaXhlZEVsZW1lbnRDbGFzc05hbWVzKGVsZW1lbnQpO1xuXG4gIGNvbnN0IHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5ID0gW107IC8vIC5rZXlTZXQoKVxuICBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheV8uZm9yRWFjaCgoYXJySXRlbSkgPT4ge1xuICAgIGlmIChwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheS5pbmRleE9mKGFyckl0ZW0pIDwgMCkge1xuICAgICAgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkucHVzaChhcnJJdGVtKTtcbiAgICB9XG4gIH0pO1xuXG4gIGxldCBuZWVkc0NsYXNzTmFtZXMgPSBmYWxzZTtcbiAgbGV0IG5lZWRzTnRoQ2hpbGQgPSBmYWxzZTtcbiAgbGV0IG93bkluZGV4ID0gLTE7XG4gIGxldCBlbGVtZW50SW5kZXggPSAtMTtcbiAgY29uc3Qgc2libGluZ3MgPSBwYXJlbnQuY2hpbGRyZW47XG5cbiAgZm9yIChcbiAgICBsZXQgaSA9IDA7XG4gICAgKG93bkluZGV4ID09PSAtMSB8fCAhbmVlZHNOdGhDaGlsZCkgJiYgaSA8IHNpYmxpbmdzLmxlbmd0aDtcbiAgICArK2lcbiAgKSB7XG4gICAgY29uc3Qgc2libGluZyA9IHNpYmxpbmdzW2ldO1xuICAgIGlmIChzaWJsaW5nLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGVsZW1lbnRJbmRleCArPSAxO1xuICAgIGlmIChzaWJsaW5nID09PSBub2RlKSB7XG4gICAgICBvd25JbmRleCA9IGVsZW1lbnRJbmRleDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAobmVlZHNOdGhDaGlsZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gc2libGluZy5ub2RlTmFtZUluQ29ycmVjdENhc2UoKVxuICAgIGNvbnN0IHNpYmxpbmdOYW1lID1cbiAgICAgIChzaWJsaW5nLmxvY2FsTmFtZSAmJiBzaWJsaW5nLmxvY2FsTmFtZS50b0xvd2VyQ2FzZSgpKSB8fFxuICAgICAgc2libGluZy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChzaWJsaW5nTmFtZSAhPT0gbm9kZU5hbWUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBuZWVkc0NsYXNzTmFtZXMgPSB0cnVlO1xuXG4gICAgY29uc3Qgb3duQ2xhc3NOYW1lcyA9IFtdO1xuICAgIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5LmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICAgIG93bkNsYXNzTmFtZXMucHVzaChhcnJJdGVtKTtcbiAgICB9KTtcbiAgICBsZXQgb3duQ2xhc3NOYW1lQ291bnQgPSBvd25DbGFzc05hbWVzLmxlbmd0aDtcblxuICAgIGlmIChvd25DbGFzc05hbWVDb3VudCA9PT0gMCkge1xuICAgICAgbmVlZHNOdGhDaGlsZCA9IHRydWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3Qgc2libGluZ0NsYXNzTmFtZXNBcnJheV8gPSBwcmVmaXhlZEVsZW1lbnRDbGFzc05hbWVzKHNpYmxpbmcpO1xuICAgIGNvbnN0IHNpYmxpbmdDbGFzc05hbWVzQXJyYXkgPSBbXTsgLy8gLmtleVNldCgpXG4gICAgc2libGluZ0NsYXNzTmFtZXNBcnJheV8uZm9yRWFjaCgoYXJySXRlbSkgPT4ge1xuICAgICAgaWYgKHNpYmxpbmdDbGFzc05hbWVzQXJyYXkuaW5kZXhPZihhcnJJdGVtKSA8IDApIHtcbiAgICAgICAgc2libGluZ0NsYXNzTmFtZXNBcnJheS5wdXNoKGFyckl0ZW0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCBzaWJsaW5nQ2xhc3Mgb2Ygc2libGluZ0NsYXNzTmFtZXNBcnJheSkge1xuICAgICAgY29uc3QgaW5kID0gb3duQ2xhc3NOYW1lcy5pbmRleE9mKHNpYmxpbmdDbGFzcyk7XG4gICAgICBpZiAoaW5kIDwgMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgb3duQ2xhc3NOYW1lcy5zcGxpY2UoaW5kLCAxKTsgLy8gZGVsZXRlIG93bkNsYXNzTmFtZXNbc2libGluZ0NsYXNzXTtcblxuICAgICAgaWYgKCEtLW93bkNsYXNzTmFtZUNvdW50KSB7XG4gICAgICAgIG5lZWRzTnRoQ2hpbGQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgcmVzdWx0ID0gbm9kZU5hbWU7XG4gIGlmIChcbiAgICBpc1RhcmdldE5vZGUgJiZcbiAgICBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmXG4gICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpICYmXG4gICAgIWVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaWRcIikgJiZcbiAgICAhZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKVxuICApIHtcbiAgICByZXN1bHQgKz0gJ1t0eXBlPVwiJyArIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwidHlwZVwiKSArICdcIl0nO1xuICB9XG4gIGlmIChuZWVkc050aENoaWxkKSB7XG4gICAgcmVzdWx0ICs9IFwiOm50aC1jaGlsZChcIiArIChvd25JbmRleCArIDEpICsgXCIpXCI7XG4gIH0gZWxzZSBpZiAobmVlZHNDbGFzc05hbWVzKSB7XG4gICAgZm9yIChjb25zdCBwcmVmaXhlZE5hbWUgb2YgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkpIHtcbiAgICAgIHJlc3VsdCArPSBcIi5cIiArIGVzY2FwZUlkZW50aWZpZXJJZk5lZWRlZChwcmVmaXhlZE5hbWUuc3Vic3RyKDEpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG9wdGltaXplZDogZmFsc2UsXG4gICAgdmFsdWU6IHJlc3VsdCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZUNGSShub2RlKSB7XG4gIC8vIFRPRE86IGhhbmRsZSBjaGFyYWN0ZXIgcG9zaXRpb24gaW5zaWRlIHRleHQgbm9kZVxuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgbGV0IGNmaSA9IFwiXCI7XG5cbiAgbGV0IGN1cnJlbnRFbGVtZW50ID0gbm9kZTtcbiAgd2hpbGUgKFxuICAgIGN1cnJlbnRFbGVtZW50LnBhcmVudE5vZGUgJiZcbiAgICBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICApIHtcbiAgICBjb25zdCBibGFja2xpc3RlZCA9IGNoZWNrQmxhY2tsaXN0ZWQoY3VycmVudEVsZW1lbnQpO1xuICAgIGlmICghYmxhY2tsaXN0ZWQpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW4gPSBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlLmNoaWxkcmVuO1xuICAgICAgbGV0IGN1cnJlbnRFbGVtZW50SW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY3VycmVudEVsZW1lbnRQYXJlbnRDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoY3VycmVudEVsZW1lbnQgPT09IGN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW5baV0pIHtcbiAgICAgICAgICBjdXJyZW50RWxlbWVudEluZGV4ID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRFbGVtZW50SW5kZXggPj0gMCkge1xuICAgICAgICBjb25zdCBjZmlJbmRleCA9IChjdXJyZW50RWxlbWVudEluZGV4ICsgMSkgKiAyO1xuICAgICAgICBjZmkgPVxuICAgICAgICAgIGNmaUluZGV4ICtcbiAgICAgICAgICAoY3VycmVudEVsZW1lbnQuaWQgPyBcIltcIiArIGN1cnJlbnRFbGVtZW50LmlkICsgXCJdXCIgOiBcIlwiKSArXG4gICAgICAgICAgKGNmaS5sZW5ndGggPyBcIi9cIiArIGNmaSA6IFwiXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICBjdXJyZW50RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50LnBhcmVudE5vZGU7XG4gIH1cblxuICByZXR1cm4gXCIvXCIgKyBjZmk7XG59XG5cbmZ1bmN0aW9uIF9jcmVhdGVIaWdobGlnaHQobG9jYXRpb25zLCBjb2xvciwgcG9pbnRlckludGVyYWN0aW9uLCB0eXBlKSB7XG4gIGNvbnN0IHJhbmdlSW5mbyA9IGxvY2F0aW9uMlJhbmdlSW5mbyhsb2NhdGlvbnMpO1xuICBjb25zdCB1bmlxdWVTdHIgPSBgJHtyYW5nZUluZm8uY2ZpfSR7cmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yfSR7cmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4fSR7cmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0fSR7cmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcn0ke3JhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXh9JHtyYW5nZUluZm8uZW5kT2Zmc2V0fWA7XG5cbiAgY29uc3QgaGFzaCA9IHJlcXVpcmUoXCJoYXNoLmpzXCIpO1xuICBjb25zdCBzaGEyNTZIZXggPSBoYXNoLnNoYTI1NigpLnVwZGF0ZSh1bmlxdWVTdHIpLmRpZ2VzdChcImhleFwiKTtcblxuICB2YXIgaWQ7XG4gIGlmICh0eXBlID09IElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSKSB7XG4gICAgaWQgPSBcIlIyX0hJR0hMSUdIVF9cIiArIHNoYTI1NkhleDtcbiAgfSBlbHNlIHtcbiAgICBpZCA9IFwiUjJfQU5OT1RBVElPTl9cIiArIHNoYTI1NkhleDtcbiAgfVxuXG4gIGRlc3Ryb3lIaWdobGlnaHQoaWQpO1xuXG4gIGNvbnN0IGhpZ2hsaWdodCA9IHtcbiAgICBjb2xvcjogY29sb3IgPyBjb2xvciA6IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUixcbiAgICBpZCxcbiAgICBwb2ludGVySW50ZXJhY3Rpb24sXG4gICAgcmFuZ2VJbmZvLFxuICB9O1xuICBfaGlnaGxpZ2h0cy5wdXNoKGhpZ2hsaWdodCk7XG4gIGNyZWF0ZUhpZ2hsaWdodERvbShcbiAgICB3aW5kb3csXG4gICAgaGlnaGxpZ2h0LFxuICAgIHR5cGUgPT0gSURfQU5OT1RBVElPTl9DT05UQUlORVIgPyB0cnVlIDogZmFsc2VcbiAgKTtcblxuICByZXR1cm4gaGlnaGxpZ2h0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSGlnaGxpZ2h0KHNlbGVjdGlvbkluZm8sIGNvbG9yLCBwb2ludGVySW50ZXJhY3Rpb24pIHtcbiAgcmV0dXJuIF9jcmVhdGVIaWdobGlnaHQoXG4gICAgc2VsZWN0aW9uSW5mbyxcbiAgICBjb2xvcixcbiAgICBwb2ludGVySW50ZXJhY3Rpb24sXG4gICAgSURfSElHSExJR0hUU19DT05UQUlORVJcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFubm90YXRpb24oaWQpIHtcbiAgbGV0IGkgPSAtMTtcblxuICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoLCBqKSA9PiB7XG4gICAgaSA9IGo7XG4gICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICB9KTtcbiAgaWYgKGkgPT0gX2hpZ2hsaWdodHMubGVuZ3RoKSByZXR1cm47XG5cbiAgdmFyIGxvY2F0aW9ucyA9IHtcbiAgICBsb2NhdGlvbnM6IHJhbmdlSW5mbzJMb2NhdGlvbihoaWdobGlnaHQucmFuZ2VJbmZvKSxcbiAgfTtcblxuICByZXR1cm4gX2NyZWF0ZUhpZ2hsaWdodChcbiAgICBsb2NhdGlvbnMsXG4gICAgaGlnaGxpZ2h0LmNvbG9yLFxuICAgIHRydWUsXG4gICAgSURfQU5OT1RBVElPTl9DT05UQUlORVJcbiAgKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSGlnaGxpZ2h0RG9tKHdpbiwgaGlnaGxpZ2h0LCBhbm5vdGF0aW9uRmxhZykge1xuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBjb25zdCBzY2FsZSA9XG4gICAgMSAvXG4gICAgKHdpbi5SRUFESVVNMiAmJiB3aW4uUkVBRElVTTIuaXNGaXhlZExheW91dFxuICAgICAgPyB3aW4uUkVBRElVTTIuZnhsVmlld3BvcnRTY2FsZVxuICAgICAgOiAxKTtcblxuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG5cbiAgY29uc3QgcmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCBoaWdobGlnaHQucmFuZ2VJbmZvKTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBwYWdpbmF0ZWQgPSBpc1BhZ2luYXRlZChkb2N1bWVudCk7XG4gIGNvbnN0IGhpZ2hsaWdodHNDb250YWluZXIgPSBlbnN1cmVDb250YWluZXIod2luLCBhbm5vdGF0aW9uRmxhZyk7XG4gIGNvbnN0IGhpZ2hsaWdodFBhcmVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgaGlnaGxpZ2h0UGFyZW50LnNldEF0dHJpYnV0ZShcImlkXCIsIGhpZ2hsaWdodC5pZCk7XG4gIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSKTtcblxuICBkb2N1bWVudC5ib2R5LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuICBoaWdobGlnaHRQYXJlbnQuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gIGlmIChoaWdobGlnaHQucG9pbnRlckludGVyYWN0aW9uKSB7XG4gICAgaGlnaGxpZ2h0UGFyZW50LnNldEF0dHJpYnV0ZShcImRhdGEtY2xpY2tcIiwgXCIxXCIpO1xuICB9XG5cbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBjb25zdCB1c2VTVkcgPSAhREVCVUdfVklTVUFMUyAmJiBVU0VfU1ZHO1xuICAvL2NvbnN0IHVzZVNWRyA9IFVTRV9TVkc7XG4gIGNvbnN0IGRyYXdVbmRlcmxpbmUgPSBmYWxzZTtcbiAgY29uc3QgZHJhd1N0cmlrZVRocm91Z2ggPSBmYWxzZTtcbiAgY29uc3QgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cyA9IGRyYXdVbmRlcmxpbmUgfHwgZHJhd1N0cmlrZVRocm91Z2g7XG4gIC8vY29uc3QgY2xpZW50UmVjdHMgPSBERUJVR19WSVNVQUxTID8gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKSA6XG4gIGNvbnN0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgcmFuZ2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICBsZXQgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWc7XG4gIGNvbnN0IHJvdW5kZWRDb3JuZXIgPSAzO1xuICBjb25zdCB1bmRlcmxpbmVUaGlja25lc3MgPSAyO1xuICBjb25zdCBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyA9IDM7XG4gIGNvbnN0IG9wYWNpdHkgPSBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWTtcbiAgbGV0IGV4dHJhID0gXCJcIjtcbiAgY29uc3QgcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0ID1cbiAgICBmcmFtZUZvckhpZ2hsaWdodEFubm90YXRpb25NYXJrV2l0aElEKHdpbiwgaGlnaGxpZ2h0LmlkKTtcblxuICBsZXQgeE9mZnNldDtcbiAgbGV0IHlPZmZzZXQ7XG4gIGxldCBhbm5vdGF0aW9uT2Zmc2V0O1xuXG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBib2R5UmVjdC5sZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gICAgYW5ub3RhdGlvbk9mZnNldCA9XG4gICAgICBwYXJzZUludChcbiAgICAgICAgKHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5yaWdodCAtIHhPZmZzZXQpIC8gd2luZG93LmlubmVyV2lkdGhcbiAgICAgICkgKyAxO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiBib2R5UmVjdC50b3A7XG4gICAgYW5ub3RhdGlvbk9mZnNldCA9IHBhcnNlSW50KFxuICAgICAgcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnJpZ2h0IC8gd2luZG93LmlubmVyV2lkdGggKyAxXG4gICAgKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgY2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIGlmICh1c2VTVkcpIHtcbiAgICAgIGNvbnN0IGJvcmRlclRoaWNrbmVzcyA9IDA7XG4gICAgICBpZiAoIWhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgfVxuICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWR1JlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICBcInJlY3RcIlxuICAgICAgKTtcblxuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgIGBmaWxsOiByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSkgIWltcG9ydGFudDsgZmlsbC1vcGFjaXR5OiAke29wYWNpdHl9ICFpbXBvcnRhbnQ7IHN0cm9rZS13aWR0aDogMDtgXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2NhbGUgPSBzY2FsZTtcblxuICAgICAgLypcbiAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0ID0ge1xuICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICovXG5cbiAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QgPSB7XG4gICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJyeFwiLCBgJHtyb3VuZGVkQ29ybmVyICogc2NhbGV9YCk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJyeVwiLCBgJHtyb3VuZGVkQ29ybmVyICogc2NhbGV9YCk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwieFwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC5sZWZ0IC0gYm9yZGVyVGhpY2tuZXNzKSAqIHNjYWxlfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwieVwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC50b3AgLSBib3JkZXJUaGlja25lc3MpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJoZWlnaHRcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QuaGVpZ2h0ICsgYm9yZGVyVGhpY2tuZXNzICogMikgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcIndpZHRoXCIsXG4gICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0LndpZHRoICsgYm9yZGVyVGhpY2tuZXNzICogMikgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0QXJlYVNWR1JlY3QpO1xuICAgICAgaWYgKGRyYXdVbmRlcmxpbmUpIHtcbiAgICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWR0xpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgU1ZHX1hNTF9OQU1FU1BBQ0UsXG4gICAgICAgICAgXCJsaW5lXCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICAgIGBzdHJva2UtbGluZWNhcDogcm91bmQ7IHN0cm9rZS13aWR0aDogJHtcbiAgICAgICAgICAgIHVuZGVybGluZVRoaWNrbmVzcyAqIHNjYWxlXG4gICAgICAgICAgfTsgc3Ryb2tlOiByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke1xuICAgICAgICAgICAgaGlnaGxpZ2h0LmNvbG9yLmJsdWVcbiAgICAgICAgICB9KSAhaW1wb3J0YW50OyBzdHJva2Utb3BhY2l0eTogJHtvcGFjaXR5fSAhaW1wb3J0YW50YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zY2FsZSA9IHNjYWxlO1xuICAgICAgICAvKlxuICAgICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsaW5lT2Zmc2V0ID1cbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoID4gcm91bmRlZENvcm5lciA/IHJvdW5kZWRDb3JuZXIgOiAwO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ4MVwiLFxuICAgICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmxlZnQgKyBsaW5lT2Zmc2V0KSAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDJcIixcbiAgICAgICAgICBgJHtcbiAgICAgICAgICAgIChoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmxlZnQgK1xuICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoIC1cbiAgICAgICAgICAgICAgbGluZU9mZnNldCkgKlxuICAgICAgICAgICAgc2NhbGVcbiAgICAgICAgICB9YFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB5ID1cbiAgICAgICAgICAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC50b3AgK1xuICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgLVxuICAgICAgICAgICAgdW5kZXJsaW5lVGhpY2tuZXNzIC8gMikgKlxuICAgICAgICAgIHNjYWxlO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXCJ5MVwiLCBgJHt5fWApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXCJ5MlwiLCBgJHt5fWApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJoZWlnaHRcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmhlaWdodCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwid2lkdGhcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZy5hcHBlbmRDaGlsZChoaWdobGlnaHRBcmVhU1ZHTGluZSk7XG4gICAgICB9XG4gICAgICBpZiAoZHJhd1N0cmlrZVRocm91Z2gpIHtcbiAgICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWR0xpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgU1ZHX1hNTF9OQU1FU1BBQ0UsXG4gICAgICAgICAgXCJsaW5lXCJcbiAgICAgICAgKTtcblxuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgICAgYHN0cm9rZS1saW5lY2FwOiBidXR0OyBzdHJva2Utd2lkdGg6ICR7XG4gICAgICAgICAgICBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyAqIHNjYWxlXG4gICAgICAgICAgfTsgc3Ryb2tlOiByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke1xuICAgICAgICAgICAgaGlnaGxpZ2h0LmNvbG9yLmJsdWVcbiAgICAgICAgICB9KSAhaW1wb3J0YW50OyBzdHJva2Utb3BhY2l0eTogJHtvcGFjaXR5fSAhaW1wb3J0YW50YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zY2FsZSA9IHNjYWxlO1xuXG4gICAgICAgIC8qXG4gICAgICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgKi9cblxuICAgICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDFcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmxlZnQgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngyXCIsXG4gICAgICAgICAgYCR7XG4gICAgICAgICAgICAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICsgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCkgKlxuICAgICAgICAgICAgc2NhbGVcbiAgICAgICAgICB9YFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBsaW5lT2Zmc2V0ID0gaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgLyAyO1xuICAgICAgICBjb25zdCB5ID0gKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QudG9wICsgbGluZU9mZnNldCkgKiBzY2FsZTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTFcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTJcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIndpZHRoXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0QXJlYVNWR0xpbmUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoaWdobGlnaHRBcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuICAgICAgaGlnaGxpZ2h0QXJlYS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG5cbiAgICAgIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgICAgIGNvbnN0IHJnYiA9IE1hdGgucm91bmQoMHhmZmZmZmYgKiBNYXRoLnJhbmRvbSgpKTtcbiAgICAgICAgY29uc3QgciA9IHJnYiA+PiAxNjtcbiAgICAgICAgY29uc3QgZyA9IChyZ2IgPj4gOCkgJiAyNTU7XG4gICAgICAgIGNvbnN0IGIgPSByZ2IgJiAyNTU7XG4gICAgICAgIGV4dHJhID0gYG91dGxpbmUtY29sb3I6IHJnYigke3J9LCAke2d9LCAke2J9KTsgb3V0bGluZS1zdHlsZTogc29saWQ7IG91dGxpbmUtd2lkdGg6IDFweDsgb3V0bGluZS1vZmZzZXQ6IC0xcHg7YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChkcmF3VW5kZXJsaW5lKSB7XG4gICAgICAgICAgZXh0cmEgKz0gYGJvcmRlci1ib3R0b206ICR7dW5kZXJsaW5lVGhpY2tuZXNzICogc2NhbGV9cHggc29saWQgcmdiYSgke1xuICAgICAgICAgICAgaGlnaGxpZ2h0LmNvbG9yLnJlZFxuICAgICAgICAgIH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudGA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGhpZ2hsaWdodEFyZWEuc2V0QXR0cmlidXRlKFxuICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgIGBib3JkZXItcmFkaXVzOiAke3JvdW5kZWRDb3JuZXJ9cHggIWltcG9ydGFudDsgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KSAhaW1wb3J0YW50OyAke2V4dHJhfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc2NhbGUgPSBzY2FsZTtcbiAgICAgIC8qXG4gICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYS5yZWN0ID0ge1xuICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICovXG4gICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUud2lkdGggPSBgJHtoaWdobGlnaHRBcmVhLnJlY3Qud2lkdGggKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLmhlaWdodCA9IGAke2hpZ2hsaWdodEFyZWEucmVjdC5oZWlnaHQgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLmxlZnQgPSBgJHtoaWdobGlnaHRBcmVhLnJlY3QubGVmdCAqIHNjYWxlfXB4YDtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUudG9wID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LnRvcCAqIHNjYWxlfXB4YDtcbiAgICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYSk7XG4gICAgICBpZiAoIURFQlVHX1ZJU1VBTFMgJiYgZHJhd1N0cmlrZVRocm91Z2gpIHtcbiAgICAgICAgLy9pZiAoZHJhd1N0cmlrZVRocm91Z2gpIHtcbiAgICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYUxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgICBgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KSAhaW1wb3J0YW50O2BcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLnBvc2l0aW9uID0gcGFnaW5hdGVkID8gXCJmaXhlZFwiIDogXCJhYnNvbHV0ZVwiO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zY2FsZSA9IHNjYWxlO1xuICAgICAgICAvKlxuICAgICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLndpZHRoID0gYCR7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC53aWR0aCAqIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLmhlaWdodCA9IGAke1xuICAgICAgICAgIHN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzICogc2NhbGVcbiAgICAgICAgfXB4YDtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUubGVmdCA9IGAke1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QubGVmdCAqIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLnRvcCA9IGAke1xuICAgICAgICAgIChoaWdobGlnaHRBcmVhTGluZS5yZWN0LnRvcCArXG4gICAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0LmhlaWdodCAvIDIgLVxuICAgICAgICAgICAgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgLyAyKSAqXG4gICAgICAgICAgc2NhbGVcbiAgICAgICAgfXB4YDtcbiAgICAgICAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRBcmVhTGluZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAodXNlU1ZHICYmIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWRyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfWE1MX05BTUVTUEFDRSwgXCJzdmdcIik7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zZXRBdHRyaWJ1dGUoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLnN0eWxlLm92ZXJmbG93ID0gXCJ2aXNpYmxlXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS5sZWZ0ID0gXCIwXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS50b3AgPSBcIjBcIjtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLmFwcGVuZChoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZyk7XG4gICAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRBcmVhU1ZHKTtcbiAgfVxuXG4gIGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUEpO1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnNldEF0dHJpYnV0ZShcbiAgICAgIFwic3R5bGVcIixcbiAgICAgIGBib3JkZXItcmFkaXVzOiAke3JvdW5kZWRDb3JuZXJ9cHggIWltcG9ydGFudDsgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KSAhaW1wb3J0YW50OyAke2V4dHJhfWBcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBKTtcbiAgfVxuXG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc2NhbGUgPSBzY2FsZTtcblxuICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnNldEF0dHJpYnV0ZShcbiAgICAgIFwic3R5bGVcIixcbiAgICAgIGBvdXRsaW5lLWNvbG9yOiBtYWdlbnRhOyBvdXRsaW5lLXN0eWxlOiBzb2xpZDsgb3V0bGluZS13aWR0aDogMXB4OyBvdXRsaW5lLW9mZnNldDogLTFweDtgXG4gICAgKTtcbiAgfVxuXG4gIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnJlY3QgPSB7XG4gICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdCA9IHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnJlY3QgPSB7XG4gICAgICBoZWlnaHQ6IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCxcbiAgICAgIGxlZnQ6IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgdG9wOiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgd2lkdGg6IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0LndpZHRoLFxuICAgIH07XG4gIH1cblxuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS53aWR0aCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3Qud2lkdGggKiBzY2FsZX1weGA7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLmhlaWdodCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3QuaGVpZ2h0ICogc2NhbGV9cHhgO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5sZWZ0ID0gYCR7aGlnaGxpZ2h0Qm91bmRpbmcucmVjdC5sZWZ0ICogc2NhbGV9cHhgO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS50b3AgPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LnRvcCAqIHNjYWxlfXB4YDtcblxuICBoaWdobGlnaHRQYXJlbnQuYXBwZW5kKGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgaGlnaGxpZ2h0c0NvbnRhaW5lci5hcHBlbmQoaGlnaGxpZ2h0UGFyZW50KTtcblxuICByZXR1cm4gaGlnaGxpZ2h0UGFyZW50O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVPcmRlcmVkUmFuZ2Uoc3RhcnROb2RlLCBzdGFydE9mZnNldCwgZW5kTm9kZSwgZW5kT2Zmc2V0KSB7XG4gIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlLnNldFN0YXJ0KHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICByYW5nZS5zZXRFbmQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgaWYgKCFyYW5nZS5jb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgY29uc29sZS5sb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIENPTExBUFNFRCAuLi4gUkFOR0UgUkVWRVJTRT9cIik7XG4gIGNvbnN0IHJhbmdlUmV2ZXJzZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZVJldmVyc2Uuc2V0U3RhcnQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgcmFuZ2VSZXZlcnNlLnNldEVuZChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgaWYgKCFyYW5nZVJldmVyc2UuY29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgT0suXCIpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBjb25zb2xlLmxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgUkFOR0UgUkVWRVJTRSBBTFNPIENPTExBUFNFRD8hXCIpO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UmFuZ2UocmFuZ2UsIGdldENzc1NlbGVjdG9yLCBjb21wdXRlRWxlbWVudENGSSkge1xuICBjb25zdCBzdGFydElzRWxlbWVudCA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERTtcbiAgY29uc3Qgc3RhcnRDb250YWluZXJFbGVtZW50ID0gc3RhcnRJc0VsZW1lbnRcbiAgICA/IHJhbmdlLnN0YXJ0Q29udGFpbmVyXG4gICAgOiByYW5nZS5zdGFydENvbnRhaW5lci5wYXJlbnROb2RlICYmXG4gICAgICByYW5nZS5zdGFydENvbnRhaW5lci5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgID8gcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZVxuICAgIDogdW5kZWZpbmVkO1xuICBpZiAoIXN0YXJ0Q29udGFpbmVyRWxlbWVudCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPSBzdGFydElzRWxlbWVudFxuICAgID8gLTFcbiAgICA6IEFycmF5LmZyb20oc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMpLmluZGV4T2YoXG4gICAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyXG4gICAgICApO1xuICBpZiAoc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPCAtMSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IgPSBnZXRDc3NTZWxlY3RvcihcbiAgICBzdGFydENvbnRhaW5lckVsZW1lbnRcbiAgKTtcbiAgY29uc3QgZW5kSXNFbGVtZW50ID0gcmFuZ2UuZW5kQ29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERTtcbiAgY29uc3QgZW5kQ29udGFpbmVyRWxlbWVudCA9IGVuZElzRWxlbWVudFxuICAgID8gcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgOiByYW5nZS5lbmRDb250YWluZXIucGFyZW50Tm9kZSAmJlxuICAgICAgcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXG4gICAgPyByYW5nZS5lbmRDb250YWluZXIucGFyZW50Tm9kZVxuICAgIDogdW5kZWZpbmVkO1xuICBpZiAoIWVuZENvbnRhaW5lckVsZW1lbnQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA9IGVuZElzRWxlbWVudFxuICAgID8gLTFcbiAgICA6IEFycmF5LmZyb20oZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzKS5pbmRleE9mKHJhbmdlLmVuZENvbnRhaW5lcik7XG4gIGlmIChlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPCAtMSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yID0gZ2V0Q3NzU2VsZWN0b3IoZW5kQ29udGFpbmVyRWxlbWVudCk7XG4gIGNvbnN0IGNvbW1vbkVsZW1lbnRBbmNlc3RvciA9IGdldENvbW1vbkFuY2VzdG9yRWxlbWVudChcbiAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICByYW5nZS5lbmRDb250YWluZXJcbiAgKTtcbiAgaWYgKCFjb21tb25FbGVtZW50QW5jZXN0b3IpIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBOTyBSQU5HRSBDT01NT04gQU5DRVNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChyYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lcikge1xuICAgIGNvbnN0IHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50ID1cbiAgICAgIHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgICAgICA/IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyXG4gICAgICAgIDogcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIucGFyZW50Tm9kZTtcbiAgICBpZiAoXG4gICAgICByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCAmJlxuICAgICAgcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXG4gICAgKSB7XG4gICAgICBpZiAoY29tbW9uRWxlbWVudEFuY2VzdG9yICE9PSByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIj4+Pj4+PiBDT01NT04gQU5DRVNUT1IgQ09OVEFJTkVSIERJRkY/PyFcIik7XG4gICAgICAgIGNvbnNvbGUubG9nKGdldENzc1NlbGVjdG9yKGNvbW1vbkVsZW1lbnRBbmNlc3RvcikpO1xuICAgICAgICBjb25zb2xlLmxvZyhnZXRDc3NTZWxlY3RvcihyYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCByb290RWxlbWVudENmaSA9IGNvbXB1dGVFbGVtZW50Q0ZJKGNvbW1vbkVsZW1lbnRBbmNlc3Rvcik7XG4gIGNvbnN0IHN0YXJ0RWxlbWVudENmaSA9IGNvbXB1dGVFbGVtZW50Q0ZJKHN0YXJ0Q29udGFpbmVyRWxlbWVudCk7XG4gIGNvbnN0IGVuZEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShlbmRDb250YWluZXJFbGVtZW50KTtcbiAgbGV0IGNmaTtcbiAgaWYgKHJvb3RFbGVtZW50Q2ZpICYmIHN0YXJ0RWxlbWVudENmaSAmJiBlbmRFbGVtZW50Q2ZpKSB7XG4gICAgbGV0IHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9IHN0YXJ0RWxlbWVudENmaTtcbiAgICBpZiAoIXN0YXJ0SXNFbGVtZW50KSB7XG4gICAgICBjb25zdCBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSA9IGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChcbiAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LFxuICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lclxuICAgICAgKTtcbiAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgIHN0YXJ0RWxlbWVudENmaSArXG4gICAgICAgIFwiL1wiICtcbiAgICAgICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkgK1xuICAgICAgICBcIjpcIiArXG4gICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0ID49IDAgJiZcbiAgICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQgPCBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZS5zdGFydE9mZnNldF07XG4gICAgICAgIGlmIChjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgKHJhbmdlLnN0YXJ0T2Zmc2V0ICsgMSkgKiAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNmaVRleHROb2RlSW5kZXggPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQsXG4gICAgICAgICAgICBjaGlsZE5vZGVcbiAgICAgICAgICApO1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9IHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgY2ZpVGV4dE5vZGVJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY2ZpSW5kZXhPZkxhc3RFbGVtZW50ID1cbiAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQgKiAyO1xuICAgICAgICBjb25zdCBsYXN0Q2hpbGROb2RlID1cbiAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tcbiAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICBdO1xuICAgICAgICBpZiAobGFzdENoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgc3RhcnRFbGVtZW50Q2ZpICsgXCIvXCIgKyAoY2ZpSW5kZXhPZkxhc3RFbGVtZW50ICsgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGxldCBlbmRFbGVtZW50T3JUZXh0Q2ZpID0gZW5kRWxlbWVudENmaTtcbiAgICBpZiAoIWVuZElzRWxlbWVudCkge1xuICAgICAgY29uc3QgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LFxuICAgICAgICByYW5nZS5lbmRDb250YWluZXJcbiAgICAgICk7XG4gICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgZW5kRWxlbWVudENmaSArXG4gICAgICAgIFwiL1wiICtcbiAgICAgICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpICtcbiAgICAgICAgXCI6XCIgK1xuICAgICAgICByYW5nZS5lbmRPZmZzZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChcbiAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0ID49IDAgJiZcbiAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0IDwgZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkTm9kZSA9IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZS5lbmRPZmZzZXRdO1xuICAgICAgICBpZiAoY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPSBlbmRFbGVtZW50Q2ZpICsgXCIvXCIgKyAocmFuZ2UuZW5kT2Zmc2V0ICsgMSkgKiAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNmaVRleHROb2RlSW5kZXggPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LFxuICAgICAgICAgICAgY2hpbGROb2RlXG4gICAgICAgICAgKTtcbiAgICAgICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID0gZW5kRWxlbWVudENmaSArIFwiL1wiICsgY2ZpVGV4dE5vZGVJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY2ZpSW5kZXhPZkxhc3RFbGVtZW50ID0gZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudCAqIDI7XG4gICAgICAgIGNvbnN0IGxhc3RDaGlsZE5vZGUgPVxuICAgICAgICAgIGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tcbiAgICAgICAgICAgIGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggLSAxXG4gICAgICAgICAgXTtcbiAgICAgICAgaWYgKGxhc3RDaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBlbmRFbGVtZW50Q2ZpICsgXCIvXCIgKyAoY2ZpSW5kZXhPZkxhc3RFbGVtZW50ICsgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBlbmRFbGVtZW50Q2ZpICsgXCIvXCIgKyAoY2ZpSW5kZXhPZkxhc3RFbGVtZW50ICsgMik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgY2ZpID1cbiAgICAgIHJvb3RFbGVtZW50Q2ZpICtcbiAgICAgIFwiLFwiICtcbiAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaS5yZXBsYWNlKHJvb3RFbGVtZW50Q2ZpLCBcIlwiKSArXG4gICAgICBcIixcIiArXG4gICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpLnJlcGxhY2Uocm9vdEVsZW1lbnRDZmksIFwiXCIpO1xuICB9XG4gIHJldHVybiB7XG4gICAgY2ZpLFxuICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgZW5kT2Zmc2V0OiByYW5nZS5lbmRPZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgc3RhcnRPZmZzZXQ6IHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCByYW5nZUluZm8pIHtcbiAgY29uc3Qgc3RhcnRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFzdGFydEVsZW1lbnQpIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIFNUQVJUIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgc3RhcnRDb250YWluZXIgPSBzdGFydEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHN0YXJ0Q29udGFpbmVyID1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gc3RhcnRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIGNvbnN0IGVuZEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFlbmRFbGVtZW50KSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBFTkQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBlbmRDb250YWluZXIgPSBlbmRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IGVuZEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZW5kQ29udGFpbmVyID1cbiAgICAgIGVuZEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4XTtcbiAgICBpZiAoZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5zdGFydE9mZnNldCxcbiAgICBlbmRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLmVuZE9mZnNldFxuICApO1xufVxuXG5mdW5jdGlvbiBmcmFtZUZvckhpZ2hsaWdodEFubm90YXRpb25NYXJrV2l0aElEKHdpbiwgaWQpIHtcbiAgbGV0IGNsaWVudFJlY3RzID0gZnJhbWVGb3JIaWdobGlnaHRXaXRoSUQoaWQpO1xuICBpZiAoIWNsaWVudFJlY3RzKSByZXR1cm47XG5cbiAgdmFyIHRvcENsaWVudFJlY3QgPSBjbGllbnRSZWN0c1swXTtcbiAgdmFyIG1heEhlaWdodCA9IHRvcENsaWVudFJlY3QuaGVpZ2h0O1xuICBmb3IgKGNvbnN0IGNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBpZiAoY2xpZW50UmVjdC50b3AgPCB0b3BDbGllbnRSZWN0LnRvcCkgdG9wQ2xpZW50UmVjdCA9IGNsaWVudFJlY3Q7XG4gICAgaWYgKGNsaWVudFJlY3QuaGVpZ2h0ID4gbWF4SGVpZ2h0KSBtYXhIZWlnaHQgPSBjbGllbnRSZWN0LmhlaWdodDtcbiAgfVxuXG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuXG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBib2R5UmVjdCA9IGRvY3VtZW50LmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGxldCB5T2Zmc2V0O1xuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICB9XG4gIHZhciBuZXdUb3AgPSB0b3BDbGllbnRSZWN0LnRvcDtcblxuICBpZiAoX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICBkbyB7XG4gICAgICB2YXIgYm91bmRpbmdBcmVhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAgIENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQVxuICAgICAgKTtcbiAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgICAgLy9mb3IgKGxldCBpID0gMCwgbGVuZ3RoID0gYm91bmRpbmdBcmVhcy5zbmFwc2hvdExlbmd0aDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICBmb3IgKFxuICAgICAgICB2YXIgaSA9IDAsIGxlbiA9IGJvdW5kaW5nQXJlYXMubGVuZ3RoIHwgMDtcbiAgICAgICAgaSA8IGxlbjtcbiAgICAgICAgaSA9IChpICsgMSkgfCAwXG4gICAgICApIHtcbiAgICAgICAgdmFyIGJvdW5kaW5nQXJlYSA9IGJvdW5kaW5nQXJlYXNbaV07XG4gICAgICAgIGlmIChNYXRoLmFicyhib3VuZGluZ0FyZWEucmVjdC50b3AgLSAobmV3VG9wIC0geU9mZnNldCkpIDwgMykge1xuICAgICAgICAgIG5ld1RvcCArPSBib3VuZGluZ0FyZWEucmVjdC5oZWlnaHQ7XG4gICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAoZm91bmQpO1xuICB9XG5cbiAgdG9wQ2xpZW50UmVjdC50b3AgPSBuZXdUb3A7XG4gIHRvcENsaWVudFJlY3QuaGVpZ2h0ID0gbWF4SGVpZ2h0O1xuXG4gIHJldHVybiB0b3BDbGllbnRSZWN0O1xufVxuXG5mdW5jdGlvbiBoaWdobGlnaHRXaXRoSUQoaWQpIHtcbiAgbGV0IGkgPSAtMTtcbiAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCwgaikgPT4ge1xuICAgIGkgPSBqO1xuICAgIHJldHVybiBoLmlkID09PSBpZDtcbiAgfSk7XG4gIHJldHVybiBoaWdobGlnaHQ7XG59XG5cbmZ1bmN0aW9uIGZyYW1lRm9ySGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IGhpZ2hsaWdodFdpdGhJRChpZCk7XG4gIGlmICghaGlnaGxpZ2h0KSByZXR1cm47XG5cbiAgY29uc3QgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgcmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCBoaWdobGlnaHQucmFuZ2VJbmZvKTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcblxuICByZXR1cm4gY2xpZW50UmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJhbmdlSW5mbzJMb2NhdGlvbihyYW5nZUluZm8pIHtcbiAgcmV0dXJuIHtcbiAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIHBhcnRpYWxDZmk6IHJhbmdlSW5mby5jZmksXG4gICAgZG9tUmFuZ2U6IHtcbiAgICAgIHN0YXJ0OiB7XG4gICAgICAgIGNzc1NlbGVjdG9yOiByYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgICAgIHRleHROb2RlSW5kZXg6IHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICAgICAgb2Zmc2V0OiByYW5nZUluZm8uc3RhcnRPZmZzZXQsXG4gICAgICB9LFxuICAgICAgZW5kOiB7XG4gICAgICAgIGNzc1NlbGVjdG9yOiByYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgICAgICB0ZXh0Tm9kZUluZGV4OiByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4LFxuICAgICAgICBvZmZzZXQ6IHJhbmdlSW5mby5lbmRPZmZzZXQsXG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvY2F0aW9uMlJhbmdlSW5mbyhsb2NhdGlvbikge1xuICBjb25zdCBsb2NhdGlvbnMgPSBsb2NhdGlvbi5sb2NhdGlvbnM7XG4gIGNvbnN0IGRvbVJhbmdlID0gbG9jYXRpb25zLmRvbVJhbmdlO1xuICBjb25zdCBzdGFydCA9IGRvbVJhbmdlLnN0YXJ0O1xuICBjb25zdCBlbmQgPSBkb21SYW5nZS5lbmQ7XG5cbiAgcmV0dXJuIHtcbiAgICBjZmk6IGxvY2F0aW9uLnBhcnRpYWxDZmksXG4gICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBlbmQudGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IGVuZC5jc3NTZWxlY3RvcixcbiAgICBlbmRPZmZzZXQ6IGVuZC5vZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IHN0YXJ0LnRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IHN0YXJ0LmNzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiBzdGFydC5vZmZzZXQsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQoaWQpIHtcbiAgY29uc3QgaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0V2l0aElEKGlkKTtcbiAgaWYgKCFoaWdobGlnaHQpIHJldHVybjtcblxuICBjb25zdCBkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDtcbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuICBjb25zdCByYW5nZSA9IGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIGhpZ2hsaWdodC5yYW5nZUluZm8pO1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGRyYXdVbmRlcmxpbmUgPSBmYWxzZTtcbiAgY29uc3QgZHJhd1N0cmlrZVRocm91Z2ggPSBmYWxzZTtcbiAgY29uc3QgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cyA9IGRyYXdVbmRlcmxpbmUgfHwgZHJhd1N0cmlrZVRocm91Z2g7XG4gIC8vY29uc3QgY2xpZW50UmVjdHMgPSBERUJVR19WSVNVQUxTID8gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKSA6XG4gIGNvbnN0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgcmFuZ2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICB2YXIgc2l6ZSA9IHtcbiAgICBzY3JlZW5XaWR0aDogd2luZG93Lm91dGVyV2lkdGgsXG4gICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cub3V0ZXJIZWlnaHQsXG4gICAgbGVmdDogY2xpZW50UmVjdHNbMF0ubGVmdCxcbiAgICB3aWR0aDogY2xpZW50UmVjdHNbMF0ud2lkdGgsXG4gICAgdG9wOiBjbGllbnRSZWN0c1swXS50b3AsXG4gICAgaGVpZ2h0OiBjbGllbnRSZWN0c1swXS5oZWlnaHQsXG4gIH07XG5cbiAgcmV0dXJuIHNpemU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZWxlY3Rpb25SZWN0KCkge1xuICB0cnkge1xuICAgIHZhciBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCk7XG5cbiAgICBjb25zdCBjbGllbnRSZWN0ID0gcmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB2YXIgaGFuZGxlQm91bmRzID0ge1xuICAgICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cub3V0ZXJIZWlnaHQsXG4gICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQsXG4gICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgIHRvcDogY2xpZW50UmVjdC50b3AsXG4gICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgIH07XG4gICAgcmV0dXJuIGhhbmRsZUJvdW5kcztcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRTY3JvbGxNb2RlKGZsYWcpIHtcbiAgaWYgKCFmbGFnKSB7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfUEFHSU5BVEVEKTtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19QQUdJTkFURUQpO1xuICB9XG59XG5cbi8qXG4gaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsgLy8gSUUgPj0gOTsgb3RoZXIgYnJvd3NlcnNcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAvL2FsZXJ0KFwiWW91J3ZlIHRyaWVkIHRvIG9wZW4gY29udGV4dCBtZW51XCIpOyAvL2hlcmUgeW91IGRyYXcgeW91ciBvd24gbWVudVxuICAgICAgICAgICAgLy9lLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAvL2xldCBnZXRDc3NTZWxlY3RvciA9IGZ1bGxRdWFsaWZpZWRTZWxlY3RvcjtcbiAgICAgICAgICAgIFxuXHRcdFx0bGV0IHN0ciA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcblx0XHRcdGxldCBzZWxlY3Rpb25JbmZvID0gZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8oKTtcblx0XHRcdGxldCBwb3MgPSBjcmVhdGVIaWdobGlnaHQoc2VsZWN0aW9uSW5mbyx7cmVkOjEwLGdyZWVuOjUwLGJsdWU6MjMwfSx0cnVlKTtcblx0XHRcdGxldCByZXQyID0gY3JlYXRlQW5ub3RhdGlvbihwb3MuaWQpO1xuXHRcdFx0XG4gIH0sIGZhbHNlKTtcbiAgICB9IGVsc2UgeyAvLyBJRSA8IDlcbiAgICAgICAgZG9jdW1lbnQuYXR0YWNoRXZlbnQoJ29uY29udGV4dG1lbnUnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGFsZXJ0KFwiWW91J3ZlIHRyaWVkIHRvIG9wZW4gY29udGV4dCBtZW51XCIpO1xuICAgICAgICAgICAgd2luZG93LmV2ZW50LnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbiovXG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBsb2cgYXMgbG9nTmF0aXZlLCBsb2dFcnJvciwgc25hcEN1cnJlbnRPZmZzZXQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgdG9OYXRpdmVSZWN0IH0gZnJvbSBcIi4vcmVjdFwiO1xuaW1wb3J0IHsgVGV4dFJhbmdlIH0gZnJvbSBcIi4vdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3RleHQtcmFuZ2VcIjtcblxuLy8gUG9seWZpbGwgZm9yIEFuZHJvaWQgQVBJIDI2XG5pbXBvcnQgbWF0Y2hBbGwgZnJvbSBcInN0cmluZy5wcm90b3R5cGUubWF0Y2hhbGxcIjtcbm1hdGNoQWxsLnNoaW0oKTtcblxuY29uc3QgZGVidWcgPSB0cnVlO1xuXG4vLyBOb3RpZnkgbmF0aXZlIGNvZGUgdGhhdCB0aGUgc2VsZWN0aW9uIGNoYW5nZXMuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2VsZWN0aW9uY2hhbmdlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbGxhcHNlZCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5pc0NvbGxhcHNlZDtcblxuICAgICAgaWYgKGNvbGxhcHNlZCAmJiBpc1NlbGVjdGluZykge1xuICAgICAgICBpc1NlbGVjdGluZyA9IGZhbHNlO1xuICAgICAgICBBbmRyb2lkLm9uU2VsZWN0aW9uRW5kKCk7XG4gICAgICAgIC8vIFNuYXBzIHRoZSBjdXJyZW50IGNvbHVtbiBpbiBjYXNlIHRoZSB1c2VyIHNoaWZ0ZWQgdGhlIHNjcm9sbCBieSBkcmFnZ2luZyB0aGUgdGV4dCBzZWxlY3Rpb24uXG4gICAgICAgIHNuYXBDdXJyZW50T2Zmc2V0KCk7XG4gICAgICB9IGVsc2UgaWYgKCFjb2xsYXBzZWQgJiYgIWlzU2VsZWN0aW5nKSB7XG4gICAgICAgIGlzU2VsZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgQW5kcm9pZC5vblNlbGVjdGlvblN0YXJ0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvbigpIHtcbiAgY29uc3QgdGV4dCA9IGdldEN1cnJlbnRTZWxlY3Rpb25UZXh0KCk7XG4gIGlmICghdGV4dCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IHJlY3QgPSBnZXRTZWxlY3Rpb25SZWN0KCk7XG4gIHJldHVybiB7IHRleHQsIHJlY3QgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uUmVjdCgpIHtcbiAgdHJ5IHtcbiAgICBsZXQgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCByYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuXG4gICAgcmV0dXJuIHRvTmF0aXZlUmVjdChyYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dFcnJvcihlKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCgpIHtcbiAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICBpZiAoIXNlbGVjdGlvbikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHNlbGVjdGlvbi5pc0NvbGxhcHNlZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgaGlnaGxpZ2h0ID0gc2VsZWN0aW9uLnRvU3RyaW5nKCk7XG4gIGNvbnN0IGNsZWFuSGlnaGxpZ2h0ID0gaGlnaGxpZ2h0XG4gICAgLnRyaW0oKVxuICAgIC5yZXBsYWNlKC9cXG4vZywgXCIgXCIpXG4gICAgLnJlcGxhY2UoL1xcc1xccysvZywgXCIgXCIpO1xuICBpZiAoY2xlYW5IaWdobGlnaHQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoIXNlbGVjdGlvbi5hbmNob3JOb2RlIHx8ICFzZWxlY3Rpb24uZm9jdXNOb2RlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYW5nZSA9XG4gICAgc2VsZWN0aW9uLnJhbmdlQ291bnQgPT09IDFcbiAgICAgID8gc2VsZWN0aW9uLmdldFJhbmdlQXQoMClcbiAgICAgIDogY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNPZmZzZXRcbiAgICAgICAgKTtcbiAgaWYgKCFyYW5nZSB8fCByYW5nZS5jb2xsYXBzZWQpIHtcbiAgICBsb2coXCIkJCQkJCQkJCQkJCQkJCQkJCBDQU5OT1QgR0VUIE5PTi1DT0xMQVBTRUQgU0VMRUNUSU9OIFJBTkdFPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHRleHQgPSBkb2N1bWVudC5ib2R5LnRleHRDb250ZW50O1xuICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKGRvY3VtZW50LmJvZHkpO1xuICBjb25zdCBzdGFydCA9IHRleHRSYW5nZS5zdGFydC5vZmZzZXQ7XG4gIGNvbnN0IGVuZCA9IHRleHRSYW5nZS5lbmQub2Zmc2V0O1xuXG4gIGNvbnN0IHNuaXBwZXRMZW5ndGggPSAyMDA7XG5cbiAgLy8gQ29tcHV0ZSB0aGUgdGV4dCBiZWZvcmUgdGhlIGhpZ2hsaWdodCwgaWdub3JpbmcgdGhlIGZpcnN0IFwid29yZFwiLCB3aGljaCBtaWdodCBiZSBjdXQuXG4gIGxldCBiZWZvcmUgPSB0ZXh0LnNsaWNlKE1hdGgubWF4KDAsIHN0YXJ0IC0gc25pcHBldExlbmd0aCksIHN0YXJ0KTtcbiAgbGV0IGZpcnN0V29yZFN0YXJ0ID0gYmVmb3JlLnNlYXJjaCgvXFxQe0x9XFxwe0x9L2d1KTtcbiAgaWYgKGZpcnN0V29yZFN0YXJ0ICE9PSAtMSkge1xuICAgIGJlZm9yZSA9IGJlZm9yZS5zbGljZShmaXJzdFdvcmRTdGFydCArIDEpO1xuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUgdGV4dCBhZnRlciB0aGUgaGlnaGxpZ2h0LCBpZ25vcmluZyB0aGUgbGFzdCBcIndvcmRcIiwgd2hpY2ggbWlnaHQgYmUgY3V0LlxuICBsZXQgYWZ0ZXIgPSB0ZXh0LnNsaWNlKGVuZCwgTWF0aC5taW4odGV4dC5sZW5ndGgsIGVuZCArIHNuaXBwZXRMZW5ndGgpKTtcbiAgbGV0IGxhc3RXb3JkRW5kID0gQXJyYXkuZnJvbShhZnRlci5tYXRjaEFsbCgvXFxwe0x9XFxQe0x9L2d1KSkucG9wKCk7XG4gIGlmIChsYXN0V29yZEVuZCAhPT0gdW5kZWZpbmVkICYmIGxhc3RXb3JkRW5kLmluZGV4ID4gMSkge1xuICAgIGFmdGVyID0gYWZ0ZXIuc2xpY2UoMCwgbGFzdFdvcmRFbmQuaW5kZXggKyAxKTtcbiAgfVxuXG4gIHJldHVybiB7IGhpZ2hsaWdodCwgYmVmb3JlLCBhZnRlciB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVPcmRlcmVkUmFuZ2Uoc3RhcnROb2RlLCBzdGFydE9mZnNldCwgZW5kTm9kZSwgZW5kT2Zmc2V0KSB7XG4gIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlLnNldFN0YXJ0KHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICByYW5nZS5zZXRFbmQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgaWYgKCFyYW5nZS5jb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgbG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBDT0xMQVBTRUQgLi4uIFJBTkdFIFJFVkVSU0U/XCIpO1xuICBjb25zdCByYW5nZVJldmVyc2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2VSZXZlcnNlLnNldFN0YXJ0KGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRFbmQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIGlmICghcmFuZ2VSZXZlcnNlLmNvbGxhcHNlZCkge1xuICAgIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgUkFOR0UgUkVWRVJTRSBPSy5cIik7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgUkFOR0UgUkVWRVJTRSBBTFNPIENPTExBUFNFRD8hXCIpO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgcmFuZ2VJbmZvKSB7XG4gIGNvbnN0IHN0YXJ0RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghc3RhcnRFbGVtZW50KSB7XG4gICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gU1RBUlQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBzdGFydENvbnRhaW5lciA9IHN0YXJ0RWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICApIHtcbiAgICAgIGxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHN0YXJ0Q29udGFpbmVyID1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gc3RhcnRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFPyFcIik7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICBjb25zdCBlbmRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghZW5kRWxlbWVudCkge1xuICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIEVORCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IGVuZENvbnRhaW5lciA9IGVuZEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IGVuZEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICApIHtcbiAgICAgIGxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IGVuZEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZW5kQ29udGFpbmVyID1cbiAgICAgIGVuZEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4XTtcbiAgICBpZiAoZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCIpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICBzdGFydENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uc3RhcnRPZmZzZXQsXG4gICAgZW5kQ29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5lbmRPZmZzZXRcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvY2F0aW9uMlJhbmdlSW5mbyhsb2NhdGlvbikge1xuICBjb25zdCBsb2NhdGlvbnMgPSBsb2NhdGlvbi5sb2NhdGlvbnM7XG4gIGNvbnN0IGRvbVJhbmdlID0gbG9jYXRpb25zLmRvbVJhbmdlO1xuICBjb25zdCBzdGFydCA9IGRvbVJhbmdlLnN0YXJ0O1xuICBjb25zdCBlbmQgPSBkb21SYW5nZS5lbmQ7XG5cbiAgcmV0dXJuIHtcbiAgICBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IGVuZC50ZXh0Tm9kZUluZGV4LFxuICAgIGVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcjogZW5kLmNzc1NlbGVjdG9yLFxuICAgIGVuZE9mZnNldDogZW5kLm9mZnNldCxcbiAgICBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogc3RhcnQudGV4dE5vZGVJbmRleCxcbiAgICBzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcjogc3RhcnQuY3NzU2VsZWN0b3IsXG4gICAgc3RhcnRPZmZzZXQ6IHN0YXJ0Lm9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9nKCkge1xuICBpZiAoZGVidWcpIHtcbiAgICBsb2dOYXRpdmUuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuLy8gQmFzZSBzY3JpcHQgdXNlZCBieSBib3RoIHJlZmxvd2FibGUgYW5kIGZpeGVkIGxheW91dCByZXNvdXJjZXMuXG5cbmltcG9ydCBcIi4vZ2VzdHVyZXNcIjtcbmltcG9ydCBcIi4va2V5Ym9hcmRcIjtcbmltcG9ydCB7XG4gIHJlbW92ZVByb3BlcnR5LFxuICBzY3JvbGxMZWZ0LFxuICBzY3JvbGxSaWdodCxcbiAgc2Nyb2xsVG9FbmQsXG4gIHNjcm9sbFRvSWQsXG4gIHNjcm9sbFRvUG9zaXRpb24sXG4gIHNjcm9sbFRvU3RhcnQsXG4gIHNjcm9sbFRvVGV4dCxcbiAgc2V0UHJvcGVydHksXG4gIHNldENTU1Byb3BlcnRpZXMsXG59IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQge1xuICBjcmVhdGVBbm5vdGF0aW9uLFxuICBjcmVhdGVIaWdobGlnaHQsXG4gIGRlc3Ryb3lIaWdobGlnaHQsXG4gIGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvLFxuICBnZXRTZWxlY3Rpb25SZWN0LFxuICByZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQsXG4gIHNldFNjcm9sbE1vZGUsXG59IGZyb20gXCIuL2hpZ2hsaWdodFwiO1xuaW1wb3J0IHsgZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IgfSBmcm9tIFwiLi9kb21cIjtcbmltcG9ydCB7IGdldEN1cnJlbnRTZWxlY3Rpb24gfSBmcm9tIFwiLi9zZWxlY3Rpb25cIjtcbmltcG9ydCB7IGdldERlY29yYXRpb25zLCByZWdpc3RlclRlbXBsYXRlcyB9IGZyb20gXCIuL2RlY29yYXRvclwiO1xuXG4vLyBQdWJsaWMgQVBJIHVzZWQgYnkgdGhlIG5hdmlnYXRvci5cbndpbmRvdy5yZWFkaXVtID0ge1xuICAvLyB1dGlsc1xuICBzY3JvbGxUb0lkOiBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1Bvc2l0aW9uOiBzY3JvbGxUb1Bvc2l0aW9uLFxuICBzY3JvbGxUb1RleHQ6IHNjcm9sbFRvVGV4dCxcbiAgc2Nyb2xsTGVmdDogc2Nyb2xsTGVmdCxcbiAgc2Nyb2xsUmlnaHQ6IHNjcm9sbFJpZ2h0LFxuICBzY3JvbGxUb1N0YXJ0OiBzY3JvbGxUb1N0YXJ0LFxuICBzY3JvbGxUb0VuZDogc2Nyb2xsVG9FbmQsXG4gIHNldENTU1Byb3BlcnRpZXM6IHNldENTU1Byb3BlcnRpZXMsXG4gIHNldFByb3BlcnR5OiBzZXRQcm9wZXJ0eSxcbiAgcmVtb3ZlUHJvcGVydHk6IHJlbW92ZVByb3BlcnR5LFxuXG4gIC8vIHNlbGVjdGlvblxuICBnZXRDdXJyZW50U2VsZWN0aW9uOiBnZXRDdXJyZW50U2VsZWN0aW9uLFxuXG4gIC8vIGRlY29yYXRpb25cbiAgcmVnaXN0ZXJEZWNvcmF0aW9uVGVtcGxhdGVzOiByZWdpc3RlclRlbXBsYXRlcyxcbiAgZ2V0RGVjb3JhdGlvbnM6IGdldERlY29yYXRpb25zLFxuXG4gIC8vIERPTVxuICBmaW5kRmlyc3RWaXNpYmxlTG9jYXRvcjogZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IsXG59O1xuXG4vLyBMZWdhY3kgaGlnaGxpZ2h0cyBBUEkuXG53aW5kb3cuY3JlYXRlQW5ub3RhdGlvbiA9IGNyZWF0ZUFubm90YXRpb247XG53aW5kb3cuY3JlYXRlSGlnaGxpZ2h0ID0gY3JlYXRlSGlnaGxpZ2h0O1xud2luZG93LmRlc3Ryb3lIaWdobGlnaHQgPSBkZXN0cm95SGlnaGxpZ2h0O1xud2luZG93LmdldEN1cnJlbnRTZWxlY3Rpb25JbmZvID0gZ2V0Q3VycmVudFNlbGVjdGlvbkluZm87XG53aW5kb3cuZ2V0U2VsZWN0aW9uUmVjdCA9IGdldFNlbGVjdGlvblJlY3Q7XG53aW5kb3cucmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEID0gcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEO1xud2luZG93LnNldFNjcm9sbE1vZGUgPSBzZXRTY3JvbGxNb2RlO1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuLy8gU2NyaXB0IHVzZWQgZm9yIHJlZmxvd2FibGUgcmVzb3VyY2VzLlxuXG5pbXBvcnQgXCIuL2luZGV4XCI7XG5cbndpbmRvdy5yZWFkaXVtLmlzUmVmbG93YWJsZSA9IHRydWU7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbiAgLy8gU2V0dXBzIHRoZSBgdmlld3BvcnRgIG1ldGEgdGFnIHRvIGRpc2FibGUgem9vbWluZy5cbiAgbGV0IG1ldGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibWV0YVwiKTtcbiAgbWV0YS5zZXRBdHRyaWJ1dGUoXCJuYW1lXCIsIFwidmlld3BvcnRcIik7XG4gIG1ldGEuc2V0QXR0cmlidXRlKFxuICAgIFwiY29udGVudFwiLFxuICAgIFwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWF4aW11bS1zY2FsZT0xLjAsIHVzZXItc2NhbGFibGU9bm8sIHNocmluay10by1maXQ9bm9cIlxuICApO1xuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGEpO1xufSk7XG4iXSwibmFtZXMiOlsiYXBwcm94U2VhcmNoIiwic2VhcmNoIiwidGV4dCIsInN0ciIsIm1heEVycm9ycyIsIm1hdGNoUG9zIiwiZXhhY3RNYXRjaGVzIiwiaW5kZXhPZiIsInB1c2giLCJzdGFydCIsImVuZCIsImxlbmd0aCIsImVycm9ycyIsInRleHRNYXRjaFNjb3JlIiwibWF0Y2hlcyIsIm1hdGNoUXVvdGUiLCJxdW90ZSIsImNvbnRleHQiLCJNYXRoIiwibWluIiwic2NvcmVNYXRjaCIsIm1hdGNoIiwicXVvdGVXZWlnaHQiLCJwcmVmaXhXZWlnaHQiLCJzdWZmaXhXZWlnaHQiLCJwb3NXZWlnaHQiLCJxdW90ZVNjb3JlIiwicHJlZml4U2NvcmUiLCJwcmVmaXgiLCJzbGljZSIsIm1heCIsInN1ZmZpeFNjb3JlIiwic3VmZml4IiwicG9zU2NvcmUiLCJoaW50Iiwib2Zmc2V0IiwiYWJzIiwicmF3U2NvcmUiLCJtYXhTY29yZSIsIm5vcm1hbGl6ZWRTY29yZSIsInNjb3JlZE1hdGNoZXMiLCJtYXAiLCJtIiwic2NvcmUiLCJzb3J0IiwiYSIsImIiLCJub2RlVGV4dExlbmd0aCIsIm5vZGUiLCJub2RlVHlwZSIsIk5vZGUiLCJFTEVNRU5UX05PREUiLCJURVhUX05PREUiLCJ0ZXh0Q29udGVudCIsInByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoIiwic2libGluZyIsInByZXZpb3VzU2libGluZyIsInJlc29sdmVPZmZzZXRzIiwiZWxlbWVudCIsIm9mZnNldHMiLCJuZXh0T2Zmc2V0Iiwic2hpZnQiLCJub2RlSXRlciIsIm93bmVyRG9jdW1lbnQiLCJjcmVhdGVOb2RlSXRlcmF0b3IiLCJOb2RlRmlsdGVyIiwiU0hPV19URVhUIiwicmVzdWx0cyIsImN1cnJlbnROb2RlIiwibmV4dE5vZGUiLCJ0ZXh0Tm9kZSIsInVuZGVmaW5lZCIsImRhdGEiLCJSYW5nZUVycm9yIiwiUkVTT0xWRV9GT1JXQVJEUyIsIlJFU09MVkVfQkFDS1dBUkRTIiwiVGV4dFBvc2l0aW9uIiwiRXJyb3IiLCJwYXJlbnQiLCJjb250YWlucyIsImVsIiwicGFyZW50RWxlbWVudCIsIm9wdGlvbnMiLCJlcnIiLCJkaXJlY3Rpb24iLCJ0dyIsImRvY3VtZW50IiwiY3JlYXRlVHJlZVdhbGtlciIsImdldFJvb3ROb2RlIiwiZm9yd2FyZHMiLCJwcmV2aW91c05vZGUiLCJmcm9tUG9pbnQiLCJ0ZXh0T2Zmc2V0IiwiY2hpbGROb2RlcyIsImkiLCJUZXh0UmFuZ2UiLCJyZWxhdGl2ZVRvIiwicmVzb2x2ZSIsInJhbmdlIiwiUmFuZ2UiLCJzZXRTdGFydCIsInNldEVuZCIsInN0YXJ0Q29udGFpbmVyIiwic3RhcnRPZmZzZXQiLCJlbmRDb250YWluZXIiLCJlbmRPZmZzZXQiLCJyb290Iiwibm9kZUZyb21YUGF0aCIsInhwYXRoRnJvbU5vZGUiLCJSYW5nZUFuY2hvciIsIm5vcm1hbGl6ZWRSYW5nZSIsImZyb21SYW5nZSIsInRvUmFuZ2UiLCJ0ZXh0UmFuZ2UiLCJ0eXBlIiwic2VsZWN0b3IiLCJzdGFydFBvcyIsImZyb21DaGFyT2Zmc2V0IiwiZW5kUG9zIiwiVGV4dFBvc2l0aW9uQW5jaG9yIiwiZnJvbU9mZnNldHMiLCJUZXh0UXVvdGVBbmNob3IiLCJleGFjdCIsInRvUG9zaXRpb25BbmNob3IiLCJjb250ZXh0TGVuIiwid2luZG93IiwiYWRkRXZlbnRMaXN0ZW5lciIsImV2ZW50IiwiQW5kcm9pZCIsImxvZ0Vycm9yIiwibWVzc2FnZSIsImZpbGVuYW1lIiwibGluZW5vIiwib2JzZXJ2ZXIiLCJSZXNpemVPYnNlcnZlciIsIm9uVmlld3BvcnRXaWR0aENoYW5nZWQiLCJzbmFwQ3VycmVudE9mZnNldCIsIm9ic2VydmUiLCJib2R5IiwiYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkIiwiaWQiLCJ2aXJ0dWFsQ29sIiwiZ2V0RWxlbWVudEJ5SWQiLCJpc1Njcm9sbE1vZGVFbmFibGVkIiwiZ2V0Q29sdW1uQ291bnRQZXJTY3JlZW4iLCJyZW1vdmUiLCJkb2N1bWVudFdpZHRoIiwic2Nyb2xsaW5nRWxlbWVudCIsInNjcm9sbFdpZHRoIiwiY29sQ291bnQiLCJwYWdlV2lkdGgiLCJoYXNPZGRDb2xDb3VudCIsInJvdW5kIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsInN0eWxlIiwiYnJlYWtCZWZvcmUiLCJpbm5lckhUTUwiLCJhcHBlbmRDaGlsZCIsIndpZHRoIiwiZ2V0Vmlld3BvcnRXaWR0aCIsImRldmljZVBpeGVsUmF0aW8iLCJzZXRQcm9wZXJ0eSIsInBhcnNlSW50IiwiZ2V0Q29tcHV0ZWRTdHlsZSIsImRvY3VtZW50RWxlbWVudCIsImdldFByb3BlcnR5VmFsdWUiLCJ0cmltIiwiaXNSVEwiLCJkaXIiLCJ0b0xvd2VyQ2FzZSIsInNjcm9sbFRvSWQiLCJzY3JvbGxUb1JlY3QiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJzY3JvbGxUb1Bvc2l0aW9uIiwicG9zaXRpb24iLCJzY3JvbGxIZWlnaHQiLCJzY3JvbGxUb3AiLCJmYWN0b3IiLCJzY3JvbGxMZWZ0Iiwic25hcE9mZnNldCIsInNjcm9sbFRvVGV4dCIsInJhbmdlRnJvbUxvY2F0b3IiLCJzY3JvbGxUb1JhbmdlIiwicmVjdCIsInRvcCIsInNjcm9sbFkiLCJpbm5lckhlaWdodCIsImxlZnQiLCJzY3JvbGxYIiwic2Nyb2xsVG9TdGFydCIsInNjcm9sbFRvIiwic2Nyb2xsVG9FbmQiLCJtaW5PZmZzZXQiLCJzY3JvbGxUb09mZnNldCIsInNjcm9sbFJpZ2h0IiwibWF4T2Zmc2V0IiwiY3VycmVudE9mZnNldCIsImRpZmYiLCJ2YWx1ZSIsImRlbHRhIiwibG9jYXRvciIsImxvY2F0aW9ucyIsImhpZ2hsaWdodCIsImNzc1NlbGVjdG9yIiwicXVlcnlTZWxlY3RvciIsImFuY2hvciIsImJlZm9yZSIsImFmdGVyIiwiZnJhZ21lbnRzIiwiaHRtbElkIiwiY3JlYXRlUmFuZ2UiLCJzZXRTdGFydEJlZm9yZSIsInNldEVuZEFmdGVyIiwiZSIsInNldENTU1Byb3BlcnRpZXMiLCJwcm9wZXJ0aWVzIiwibmFtZSIsImtleSIsInJlbW92ZVByb3BlcnR5IiwibG9nIiwiQXJyYXkiLCJwcm90b3R5cGUiLCJjYWxsIiwiYXJndW1lbnRzIiwiam9pbiIsImxvZ05hdGl2ZSIsImRlYnVnIiwidG9OYXRpdmVSZWN0IiwicGl4ZWxSYXRpbyIsImhlaWdodCIsInJpZ2h0IiwiYm90dG9tIiwiZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAiLCJkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzIiwiY2xpZW50UmVjdHMiLCJnZXRDbGllbnRSZWN0cyIsInRvbGVyYW5jZSIsIm9yaWdpbmFsUmVjdHMiLCJyYW5nZUNsaWVudFJlY3QiLCJtZXJnZWRSZWN0cyIsIm1lcmdlVG91Y2hpbmdSZWN0cyIsIm5vQ29udGFpbmVkUmVjdHMiLCJyZW1vdmVDb250YWluZWRSZWN0cyIsIm5ld1JlY3RzIiwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyIsIm1pbkFyZWEiLCJqIiwiYmlnRW5vdWdoIiwic3BsaWNlIiwicmVjdHMiLCJyZWN0MSIsInJlY3QyIiwicmVjdHNMaW5lVXBWZXJ0aWNhbGx5IiwiYWxtb3N0RXF1YWwiLCJyZWN0c0xpbmVVcEhvcml6b250YWxseSIsImhvcml6b250YWxBbGxvd2VkIiwiYWxpZ25lZCIsImNhbk1lcmdlIiwicmVjdHNUb3VjaE9yT3ZlcmxhcCIsImZpbHRlciIsInJlcGxhY2VtZW50Q2xpZW50UmVjdCIsImdldEJvdW5kaW5nUmVjdCIsInJlY3RzVG9LZWVwIiwiU2V0IiwiZGVsZXRlIiwicG9zc2libHlDb250YWluaW5nUmVjdCIsImhhcyIsInJlY3RDb250YWlucyIsImZyb20iLCJyZWN0Q29udGFpbnNQb2ludCIsIngiLCJ5IiwidG9BZGQiLCJ0b1JlbW92ZSIsInN1YnRyYWN0UmVjdHMxIiwicmVjdFN1YnRyYWN0Iiwic3VidHJhY3RSZWN0czIiLCJhcHBseSIsInJlY3RJbnRlcnNlY3RlZCIsInJlY3RJbnRlcnNlY3QiLCJyZWN0QSIsInJlY3RCIiwicmVjdEMiLCJyZWN0RCIsIm1heExlZnQiLCJtaW5SaWdodCIsIm1heFRvcCIsIm1pbkJvdHRvbSIsInN0eWxlcyIsIk1hcCIsImdyb3VwcyIsImxhc3RHcm91cElkIiwicmVnaXN0ZXJUZW1wbGF0ZXMiLCJuZXdTdHlsZXMiLCJzdHlsZXNoZWV0IiwiT2JqZWN0IiwiZW50cmllcyIsInNldCIsInN0eWxlRWxlbWVudCIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwiZ2V0RGVjb3JhdGlvbnMiLCJncm91cE5hbWUiLCJncm91cCIsImdldCIsIkRlY29yYXRpb25Hcm91cCIsImhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50IiwiY2xpY2tFdmVudCIsInNpemUiLCJmaW5kVGFyZ2V0IiwiZ3JvdXBDb250ZW50IiwiaXRlbXMiLCJyZXZlcnNlIiwiaXRlbSIsImNsaWNrYWJsZUVsZW1lbnRzIiwidG9KU09OIiwiY2xpZW50WCIsImNsaWVudFkiLCJ0YXJnZXQiLCJvbkRlY29yYXRpb25BY3RpdmF0ZWQiLCJKU09OIiwic3RyaW5naWZ5IiwiZGVjb3JhdGlvbiIsImNsaWNrIiwiZ3JvdXBJZCIsImxhc3RJdGVtSWQiLCJjb250YWluZXIiLCJhZGQiLCJsYXlvdXQiLCJkZWNvcmF0aW9uSWQiLCJpbmRleCIsImZpbmRJbmRleCIsInVwZGF0ZSIsImNsZWFyIiwiY2xlYXJDb250YWluZXIiLCJyZXF1ZXN0TGF5b3V0IiwiZm9yRWFjaCIsImdyb3VwQ29udGFpbmVyIiwicmVxdWlyZUNvbnRhaW5lciIsIml0ZW1Db250YWluZXIiLCJ2aWV3cG9ydFdpZHRoIiwiaW5uZXJXaWR0aCIsImNvbHVtbkNvdW50IiwieE9mZnNldCIsInlPZmZzZXQiLCJwb3NpdGlvbkVsZW1lbnQiLCJib3VuZGluZ1JlY3QiLCJmbG9vciIsImVsZW1lbnRUZW1wbGF0ZSIsInRlbXBsYXRlIiwiY29udGVudCIsImZpcnN0RWxlbWVudENoaWxkIiwiZXJyb3IiLCJyMSIsInIyIiwiY2xpZW50UmVjdCIsImxpbmUiLCJjbG9uZU5vZGUiLCJhcHBlbmQiLCJib3VuZHMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiY2hpbGRyZW4iLCJsYXN0U2l6ZSIsImNsaWVudFdpZHRoIiwiY2xpZW50SGVpZ2h0IiwiZ2V0Q3NzU2VsZWN0b3IiLCJuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50IiwiaW50ZXJhY3RpdmVUYWdzIiwibm9kZU5hbWUiLCJvdXRlckhUTUwiLCJoYXNBdHRyaWJ1dGUiLCJnZXRBdHRyaWJ1dGUiLCJmaW5kRmlyc3RWaXNpYmxlTG9jYXRvciIsImZpbmRFbGVtZW50IiwiaHJlZiIsInJvb3RFbGVtZW50IiwiY2hpbGQiLCJzaG91bGRJZ25vcmVFbGVtZW50IiwiaXNFbGVtZW50VmlzaWJsZSIsInJlYWRpdW0iLCJpc0ZpeGVkTGF5b3V0IiwiZWxTdHlsZSIsImRpc3BsYXkiLCJvcGFjaXR5Iiwib25DbGljayIsImJpbmREcmFnR2VzdHVyZSIsImdldFNlbGVjdGlvbiIsImlzQ29sbGFwc2VkIiwiZGVmYXVsdFByZXZlbnRlZCIsInRhcmdldEVsZW1lbnQiLCJpbnRlcmFjdGl2ZUVsZW1lbnQiLCJzaG91bGRQcmV2ZW50RGVmYXVsdCIsIm9uVGFwIiwic3RvcFByb3BhZ2F0aW9uIiwicHJldmVudERlZmF1bHQiLCJvblN0YXJ0IiwicGFzc2l2ZSIsIm9uRW5kIiwib25Nb3ZlIiwic3RhdGUiLCJpc1N0YXJ0aW5nRHJhZyIsInN0YXJ0WCIsInRvdWNoZXMiLCJzdGFydFkiLCJjdXJyZW50WCIsImN1cnJlbnRZIiwib2Zmc2V0WCIsIm9mZnNldFkiLCJvbkRyYWdTdGFydCIsIm9uRHJhZ01vdmUiLCJvbkRyYWdFbmQiLCJzaG91bGRJZ25vcmVFdmVudCIsInNlbmRQcmVzc0tleU1lc3NhZ2UiLCJhY3RpdmVFbGVtZW50IiwicmVwZWF0Iiwia2V5RXZlbnQiLCJjb2RlIiwiY2hhcmFjdGVycyIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsImtleUNvZGUiLCJhbHQiLCJhbHRLZXkiLCJjb250cm9sIiwiY3RybEtleSIsInNoaWZ0S2V5IiwibWV0YSIsIm1ldGFLZXkiLCJvbktleSIsIlJPT1RfQ0xBU1NfUkVEVUNFX01PVElPTiIsIlJPT1RfQ0xBU1NfTk9fRk9PVE5PVEVTIiwiUE9QVVBfRElBTE9HX0NMQVNTIiwiRk9PVE5PVEVTX0NPTlRBSU5FUl9DTEFTUyIsIkZPT1ROT1RFU19DTE9TRV9CVVRUT05fQ0xBU1MiLCJGT09UTk9URV9GT1JDRV9TSE9XIiwiVFRTX0lEX1BSRVZJT1VTIiwiVFRTX0lEX05FWFQiLCJUVFNfSURfU0xJREVSIiwiVFRTX0lEX0FDVElWRV9XT1JEIiwiVFRTX0lEX0NPTlRBSU5FUiIsIlRUU19JRF9JTkZPIiwiVFRTX05BVl9CVVRUT05fQ0xBU1MiLCJUVFNfSURfU1BFQUtJTkdfRE9DX0VMRU1FTlQiLCJUVFNfQ0xBU1NfSU5KRUNURURfU1BBTiIsIlRUU19DTEFTU19JTkpFQ1RFRF9TVUJTUEFOIiwiVFRTX0lEX0lOSkVDVEVEX1BBUkVOVCIsIklEX0hJR0hMSUdIVFNfQ09OVEFJTkVSIiwiSURfQU5OT1RBVElPTl9DT05UQUlORVIiLCJDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSIiwiQ0xBU1NfQU5OT1RBVElPTl9DT05UQUlORVIiLCJDTEFTU19ISUdITElHSFRfQVJFQSIsIkNMQVNTX0FOTk9UQVRJT05fQVJFQSIsIkNMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBIiwiQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBIiwiX2JsYWNrbGlzdElkQ2xhc3NGb3JDRkkiLCJDTEFTU19QQUdJTkFURUQiLCJJU19ERVYiLCJfaGlnaGxpZ2h0cyIsIl9oaWdobGlnaHRzQ29udGFpbmVyIiwiX2Fubm90YXRpb25Db250YWluZXIiLCJsYXN0TW91c2VEb3duWCIsImxhc3RNb3VzZURvd25ZIiwiYm9keUV2ZW50TGlzdGVuZXJzU2V0IiwiVVNFX1NWRyIsIkRFRkFVTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZIiwiQUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWSIsIkRFQlVHX1ZJU1VBTFMiLCJERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IiLCJibHVlIiwiZ3JlZW4iLCJyZWQiLCJBTk5PVEFUSU9OX1dJRFRIIiwicmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlIiwiX3dpbiIsImhpZ2hsaWdodEJvdW5kaW5nIiwib3V0bGluZSIsInNldEhpZ2hsaWdodEFyZWFTdHlsZSIsIndpbiIsImhpZ2hsaWdodEFyZWFzIiwidXNlU1ZHIiwiaGlnaGxpZ2h0QXJlYSIsImlzU1ZHIiwibmFtZXNwYWNlVVJJIiwiU1ZHX1hNTF9OQU1FU1BBQ0UiLCJjb2xvciIsInJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlIiwicGFyZW50Tm9kZSIsImZpbmQiLCJoIiwicHJvY2Vzc1RvdWNoRXZlbnQiLCJldiIsInNjcm9sbEVsZW1lbnQiLCJnZXRTY3JvbGxpbmdFbGVtZW50IiwiY2hhbmdlZFRvdWNoZXMiLCJwYWdpbmF0ZWQiLCJpc1BhZ2luYXRlZCIsImJvZHlSZWN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiZm91bmRIaWdobGlnaHQiLCJmb3VuZEVsZW1lbnQiLCJmb3VuZFJlY3QiLCJoaWdobGlnaHRQYXJlbnQiLCJoaXQiLCJoaWdobGlnaHRGcmFnbWVudHMiLCJoaWdobGlnaHRGcmFnbWVudCIsIndpdGhSZWN0IiwiaGlnaGxpZ2h0Qm91bmRpbmdzIiwiYWxsSGlnaGxpZ2h0QXJlYXMiLCJmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyIsImZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIiwiYWxsSGlnaGxpZ2h0Qm91bmRpbmdzIiwic2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSIsInNjcmVlbldpZHRoIiwib3V0ZXJXaWR0aCIsInNjcmVlbkhlaWdodCIsIm91dGVySGVpZ2h0IiwicGF5bG9hZCIsInByb2Nlc3MiLCJlbGVjdHJvbl8xIiwiaXBjUmVuZGVyZXIiLCJzZW5kVG9Ib3N0IiwiUjJfRVZFTlRfSElHSExJR0hUX0NMSUNLIiwid2Via2l0VVJMIiwiY29uc29sZSIsImluY2x1ZGVzIiwiaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQiLCJ3ZWJraXQiLCJtZXNzYWdlSGFuZGxlcnMiLCJwb3N0TWVzc2FnZSIsImhpZ2hsaWdodEFjdGl2YXRlZCIsInByb2Nlc3NNb3VzZUV2ZW50IiwidG91Y2hlZFBvc2l0aW9uIiwidG9QcmVzZXJ2ZSIsInRvQ2hlY2siLCJjaGVja092ZXJsYXBzIiwic3RpbGxPdmVybGFwaW5nUmVjdHMiLCJoYXMxIiwiaGFzMiIsInhPdmVybGFwIiwiZ2V0UmVjdE92ZXJsYXBYIiwieU92ZXJsYXAiLCJnZXRSZWN0T3ZlcmxhcFkiLCJyYW5nZUNsaWVudFJlY3RzIiwiZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXBfIiwiY2xhc3NMaXN0IiwiZW5zdXJlQ29udGFpbmVyIiwiYW5ub3RhdGlvbkZsYWciLCJ0b3VjaEVuZCIsImhpZGVBbGxoaWdobGlnaHRzIiwiZGVzdHJveUFsbGhpZ2hsaWdodHMiLCJkZXN0cm95SGlnaGxpZ2h0IiwiX2RvY3VtZW50IiwiaGlnaGxpZ2h0Q29udGFpbmVyIiwiaXNDZmlUZXh0Tm9kZSIsImdldENoaWxkVGV4dE5vZGVDZmlJbmRleCIsImZvdW5kIiwidGV4dE5vZGVJbmRleCIsInByZXZpb3VzV2FzRWxlbWVudCIsImNoaWxkTm9kZSIsImlzVGV4dCIsImdldENvbW1vbkFuY2VzdG9yRWxlbWVudCIsIm5vZGUxIiwibm9kZTIiLCJub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluIiwibm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbiIsImNvbW1vbkFuY2VzdG9yIiwibm9kZTFFbGVtZW50QW5jZXN0b3IiLCJub2RlMkVsZW1lbnRBbmNlc3RvciIsImZ1bGxRdWFsaWZpZWRTZWxlY3RvciIsImxvd2VyQ2FzZU5hbWUiLCJsb2NhbE5hbWUiLCJjc3NQYXRoIiwiZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8iLCJzZWxlY3Rpb24iLCJyYXdUZXh0IiwidG9TdHJpbmciLCJjbGVhblRleHQiLCJyZXBsYWNlIiwiYW5jaG9yTm9kZSIsImZvY3VzTm9kZSIsInJhbmdlQ291bnQiLCJnZXRSYW5nZUF0IiwiY3JlYXRlT3JkZXJlZFJhbmdlIiwiYW5jaG9yT2Zmc2V0IiwiZm9jdXNPZmZzZXQiLCJjb2xsYXBzZWQiLCJyYW5nZUluZm8iLCJjb252ZXJ0UmFuZ2UiLCJjb21wdXRlQ0ZJIiwicmVzdG9yZWRSYW5nZSIsImNvbnZlcnRSYW5nZUluZm8iLCJkdW1wRGVidWciLCJyYW5nZUluZm8yTG9jYXRpb24iLCJjaGVja0JsYWNrbGlzdGVkIiwiYmxhY2tsaXN0ZWRJZCIsImJsYWNrbGlzdGVkQ2xhc3MiLCJvcHRpbWl6ZWQiLCJzdGVwcyIsImNvbnRleHROb2RlIiwic3RlcCIsIl9jc3NQYXRoU3RlcCIsImlzVGFyZ2V0Tm9kZSIsInByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMiLCJuZCIsImNsYXNzQXR0cmlidXRlIiwic3BsaXQiLCJCb29sZWFuIiwibm0iLCJpZFNlbGVjdG9yIiwiaWRkIiwiZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkIiwiaWRlbnQiLCJpc0NTU0lkZW50aWZpZXIiLCJzaG91bGRFc2NhcGVGaXJzdCIsInRlc3QiLCJsYXN0SW5kZXgiLCJjIiwiaWkiLCJpc0NTU0lkZW50Q2hhciIsImVzY2FwZUFzY2lpQ2hhciIsImlzTGFzdCIsInRvSGV4Qnl0ZSIsImhleEJ5dGUiLCJjaGFyQ29kZUF0IiwiRE9DVU1FTlRfTk9ERSIsInByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5XyIsInByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5IiwiYXJySXRlbSIsIm5lZWRzQ2xhc3NOYW1lcyIsIm5lZWRzTnRoQ2hpbGQiLCJvd25JbmRleCIsImVsZW1lbnRJbmRleCIsInNpYmxpbmdzIiwic2libGluZ05hbWUiLCJvd25DbGFzc05hbWVzIiwib3duQ2xhc3NOYW1lQ291bnQiLCJzaWJsaW5nQ2xhc3NOYW1lc0FycmF5XyIsInNpYmxpbmdDbGFzc05hbWVzQXJyYXkiLCJzaWJsaW5nQ2xhc3MiLCJpbmQiLCJyZXN1bHQiLCJwcmVmaXhlZE5hbWUiLCJzdWJzdHIiLCJjZmkiLCJjdXJyZW50RWxlbWVudCIsImJsYWNrbGlzdGVkIiwiY3VycmVudEVsZW1lbnRQYXJlbnRDaGlsZHJlbiIsImN1cnJlbnRFbGVtZW50SW5kZXgiLCJjZmlJbmRleCIsIl9jcmVhdGVIaWdobGlnaHQiLCJwb2ludGVySW50ZXJhY3Rpb24iLCJsb2NhdGlvbjJSYW5nZUluZm8iLCJ1bmlxdWVTdHIiLCJzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciIsInN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IiwiZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yIiwiZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IiwiaGFzaCIsInJlcXVpcmUiLCJzaGEyNTZIZXgiLCJzaGEyNTYiLCJkaWdlc3QiLCJjcmVhdGVIaWdobGlnaHREb20iLCJjcmVhdGVIaWdobGlnaHQiLCJzZWxlY3Rpb25JbmZvIiwiY3JlYXRlQW5ub3RhdGlvbiIsInNjYWxlIiwiUkVBRElVTTIiLCJmeGxWaWV3cG9ydFNjYWxlIiwiaGlnaGxpZ2h0c0NvbnRhaW5lciIsImRyYXdVbmRlcmxpbmUiLCJkcmF3U3RyaWtlVGhyb3VnaCIsImhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnIiwicm91bmRlZENvcm5lciIsInVuZGVybGluZVRoaWNrbmVzcyIsInN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzIiwiZXh0cmEiLCJyYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QiLCJmcmFtZUZvckhpZ2hsaWdodEFubm90YXRpb25NYXJrV2l0aElEIiwiYW5ub3RhdGlvbk9mZnNldCIsImJvcmRlclRoaWNrbmVzcyIsImNyZWF0ZURvY3VtZW50RnJhZ21lbnQiLCJoaWdobGlnaHRBcmVhU1ZHUmVjdCIsImNyZWF0ZUVsZW1lbnROUyIsImhpZ2hsaWdodEFyZWFTVkdMaW5lIiwibGluZU9mZnNldCIsInJnYiIsInJhbmRvbSIsInIiLCJnIiwiaGlnaGxpZ2h0QXJlYUxpbmUiLCJoaWdobGlnaHRBcmVhU1ZHIiwib3ZlcmZsb3ciLCJyYW5nZUJvdW5kaW5nQ2xpZW50UmVjdCIsInN0YXJ0Tm9kZSIsImVuZE5vZGUiLCJyYW5nZVJldmVyc2UiLCJjb21wdXRlRWxlbWVudENGSSIsInN0YXJ0SXNFbGVtZW50Iiwic3RhcnRDb250YWluZXJFbGVtZW50IiwiZW5kSXNFbGVtZW50IiwiZW5kQ29udGFpbmVyRWxlbWVudCIsImNvbW1vbkVsZW1lbnRBbmNlc3RvciIsImNvbW1vbkFuY2VzdG9yQ29udGFpbmVyIiwicmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQiLCJyb290RWxlbWVudENmaSIsInN0YXJ0RWxlbWVudENmaSIsImVuZEVsZW1lbnRDZmkiLCJzdGFydEVsZW1lbnRPclRleHRDZmkiLCJzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSIsImNmaVRleHROb2RlSW5kZXgiLCJjZmlJbmRleE9mTGFzdEVsZW1lbnQiLCJjaGlsZEVsZW1lbnRDb3VudCIsImxhc3RDaGlsZE5vZGUiLCJlbmRFbGVtZW50T3JUZXh0Q2ZpIiwiZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpIiwic3RhcnRFbGVtZW50IiwiZW5kRWxlbWVudCIsImZyYW1lRm9ySGlnaGxpZ2h0V2l0aElEIiwidG9wQ2xpZW50UmVjdCIsIm1heEhlaWdodCIsIm5ld1RvcCIsImJvdW5kaW5nQXJlYXMiLCJnZXRFbGVtZW50c0J5Q2xhc3NOYW1lIiwibGVuIiwiYm91bmRpbmdBcmVhIiwiaGlnaGxpZ2h0V2l0aElEIiwicGFydGlhbENmaSIsImRvbVJhbmdlIiwibG9jYXRpb24iLCJyZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQiLCJnZXRTZWxlY3Rpb25SZWN0Iiwic2VsIiwiaGFuZGxlQm91bmRzIiwic2V0U2Nyb2xsTW9kZSIsImZsYWciLCJtYXRjaEFsbCIsInNoaW0iLCJpc1NlbGVjdGluZyIsIm9uU2VsZWN0aW9uRW5kIiwib25TZWxlY3Rpb25TdGFydCIsImdldEN1cnJlbnRTZWxlY3Rpb24iLCJnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCIsImNsZWFuSGlnaGxpZ2h0Iiwic25pcHBldExlbmd0aCIsImZpcnN0V29yZFN0YXJ0IiwibGFzdFdvcmRFbmQiLCJwb3AiLCJyZWdpc3RlckRlY29yYXRpb25UZW1wbGF0ZXMiLCJpc1JlZmxvd2FibGUiLCJoZWFkIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6960\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},3715:function(__unused_webpack_module,exports,__webpack_require__){eval("var hash = exports;\n\nhash.utils = __webpack_require__(6436);\nhash.common = __webpack_require__(5772);\nhash.sha = __webpack_require__(9041);\nhash.ripemd = __webpack_require__(2949);\nhash.hmac = __webpack_require__(2344);\n\n// Proxy hash functions to the main object\nhash.sha1 = hash.sha.sha1;\nhash.sha256 = hash.sha.sha256;\nhash.sha224 = hash.sha.sha224;\nhash.sha384 = hash.sha.sha384;\nhash.sha512 = hash.sha.sha512;\nhash.ripemd160 = hash.ripemd.ripemd160;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcxNS5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQSxhQUFhLG1CQUFPLENBQUMsSUFBYztBQUNuQyxjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBWTtBQUMvQixjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsSUFBYTs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanM/N2Q5MiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3715\n")},5772:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction BlockHash() {\n this.pending = null;\n this.pendingTotal = 0;\n this.blockSize = this.constructor.blockSize;\n this.outSize = this.constructor.outSize;\n this.hmacStrength = this.constructor.hmacStrength;\n this.padLength = this.constructor.padLength / 8;\n this.endian = 'big';\n\n this._delta8 = this.blockSize / 8;\n this._delta32 = this.blockSize / 32;\n}\nexports.BlockHash = BlockHash;\n\nBlockHash.prototype.update = function update(msg, enc) {\n // Convert message to array, pad it, and join into 32bit blocks\n msg = utils.toArray(msg, enc);\n if (!this.pending)\n this.pending = msg;\n else\n this.pending = this.pending.concat(msg);\n this.pendingTotal += msg.length;\n\n // Enough data, try updating\n if (this.pending.length >= this._delta8) {\n msg = this.pending;\n\n // Process pending data in blocks\n var r = msg.length % this._delta8;\n this.pending = msg.slice(msg.length - r, msg.length);\n if (this.pending.length === 0)\n this.pending = null;\n\n msg = utils.join32(msg, 0, msg.length - r, this.endian);\n for (var i = 0; i < msg.length; i += this._delta32)\n this._update(msg, i, i + this._delta32);\n }\n\n return this;\n};\n\nBlockHash.prototype.digest = function digest(enc) {\n this.update(this._pad());\n assert(this.pending === null);\n\n return this._digest(enc);\n};\n\nBlockHash.prototype._pad = function pad() {\n var len = this.pendingTotal;\n var bytes = this._delta8;\n var k = bytes - ((len + this.padLength) % bytes);\n var res = new Array(k + this.padLength);\n res[0] = 0x80;\n for (var i = 1; i < k; i++)\n res[i] = 0;\n\n // Append length\n len <<= 3;\n if (this.endian === 'big') {\n for (var t = 8; t < this.padLength; t++)\n res[i++] = 0;\n\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = len & 0xff;\n } else {\n res[i++] = len & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n\n for (t = 8; t < this.padLength; t++)\n res[i++] = 0;\n }\n\n return res;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTc3Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLE9BQU87QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzP2VkYzkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5772\n")},2344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction Hmac(hash, key, enc) {\n if (!(this instanceof Hmac))\n return new Hmac(hash, key, enc);\n this.Hash = hash;\n this.blockSize = hash.blockSize / 8;\n this.outSize = hash.outSize / 8;\n this.inner = null;\n this.outer = null;\n\n this._init(utils.toArray(key, enc));\n}\nmodule.exports = Hmac;\n\nHmac.prototype._init = function init(key) {\n // Shorten key, if needed\n if (key.length > this.blockSize)\n key = new this.Hash().update(key).digest();\n assert(key.length <= this.blockSize);\n\n // Add padding to key\n for (var i = key.length; i < this.blockSize; i++)\n key.push(0);\n\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x36;\n this.inner = new this.Hash().update(key);\n\n // 0x36 ^ 0x5c = 0x6a\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x6a;\n this.outer = new this.Hash().update(key);\n};\n\nHmac.prototype.update = function update(msg, enc) {\n this.inner.update(msg, enc);\n return this;\n};\n\nHmac.prototype.digest = function digest(enc) {\n this.outer.update(this.inner.digest());\n return this.outer.digest(enc);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsb0JBQW9CO0FBQy9DOztBQUVBLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvaG1hYy5qcz8yMTM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gSG1hYyhoYXNoLCBrZXksIGVuYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hYykpXG4gICAgcmV0dXJuIG5ldyBIbWFjKGhhc2gsIGtleSwgZW5jKTtcbiAgdGhpcy5IYXNoID0gaGFzaDtcbiAgdGhpcy5ibG9ja1NpemUgPSBoYXNoLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMub3V0U2l6ZSA9IGhhc2gub3V0U2l6ZSAvIDg7XG4gIHRoaXMuaW5uZXIgPSBudWxsO1xuICB0aGlzLm91dGVyID0gbnVsbDtcblxuICB0aGlzLl9pbml0KHV0aWxzLnRvQXJyYXkoa2V5LCBlbmMpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hYztcblxuSG1hYy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGtleSkge1xuICAvLyBTaG9ydGVuIGtleSwgaWYgbmVlZGVkXG4gIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpXG4gICAga2V5ID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xuICBhc3NlcnQoa2V5Lmxlbmd0aCA8PSB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gQWRkIHBhZGRpbmcgdG8ga2V5XG4gIGZvciAodmFyIGkgPSBrZXkubGVuZ3RoOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKylcbiAgICBrZXkucHVzaCgwKTtcblxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDM2O1xuICB0aGlzLmlubmVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xuXG4gIC8vIDB4MzYgXiAweDVjID0gMHg2YVxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2344\n")},2949:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_3 = utils.sum32_3;\nvar sum32_4 = utils.sum32_4;\nvar BlockHash = common.BlockHash;\n\nfunction RIPEMD160() {\n if (!(this instanceof RIPEMD160))\n return new RIPEMD160();\n\n BlockHash.call(this);\n\n this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];\n this.endian = 'little';\n}\nutils.inherits(RIPEMD160, BlockHash);\nexports.ripemd160 = RIPEMD160;\n\nRIPEMD160.blockSize = 512;\nRIPEMD160.outSize = 160;\nRIPEMD160.hmacStrength = 192;\nRIPEMD160.padLength = 64;\n\nRIPEMD160.prototype._update = function update(msg, start) {\n var A = this.h[0];\n var B = this.h[1];\n var C = this.h[2];\n var D = this.h[3];\n var E = this.h[4];\n var Ah = A;\n var Bh = B;\n var Ch = C;\n var Dh = D;\n var Eh = E;\n for (var j = 0; j < 80; j++) {\n var T = sum32(\n rotl32(\n sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),\n s[j]),\n E);\n A = E;\n E = D;\n D = rotl32(C, 10);\n C = B;\n B = T;\n T = sum32(\n rotl32(\n sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),\n sh[j]),\n Eh);\n Ah = Eh;\n Eh = Dh;\n Dh = rotl32(Ch, 10);\n Ch = Bh;\n Bh = T;\n }\n T = sum32_3(this.h[1], C, Dh);\n this.h[1] = sum32_3(this.h[2], D, Eh);\n this.h[2] = sum32_3(this.h[3], E, Ah);\n this.h[3] = sum32_3(this.h[4], A, Bh);\n this.h[4] = sum32_3(this.h[0], B, Ch);\n this.h[0] = T;\n};\n\nRIPEMD160.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'little');\n else\n return utils.split32(this.h, 'little');\n};\n\nfunction f(j, x, y, z) {\n if (j <= 15)\n return x ^ y ^ z;\n else if (j <= 31)\n return (x & y) | ((~x) & z);\n else if (j <= 47)\n return (x | (~y)) ^ z;\n else if (j <= 63)\n return (x & z) | (y & (~z));\n else\n return x ^ (y | (~z));\n}\n\nfunction K(j) {\n if (j <= 15)\n return 0x00000000;\n else if (j <= 31)\n return 0x5a827999;\n else if (j <= 47)\n return 0x6ed9eba1;\n else if (j <= 63)\n return 0x8f1bbcdc;\n else\n return 0xa953fd4e;\n}\n\nfunction Kh(j) {\n if (j <= 15)\n return 0x50a28be6;\n else if (j <= 31)\n return 0x5c4dd124;\n else if (j <= 47)\n return 0x6d703ef3;\n else if (j <= 63)\n return 0x7a6d76e9;\n else\n return 0x00000000;\n}\n\nvar r = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,\n 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,\n 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13\n];\n\nvar rh = [\n 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,\n 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,\n 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,\n 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,\n 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11\n];\n\nvar s = [\n 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,\n 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,\n 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,\n 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,\n 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6\n];\n\nvar sh = [\n 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,\n 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,\n 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,\n 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,\n 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11\n];\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBVTs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzP2JiNDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2949\n")},9041:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nexports.sha1 = __webpack_require__(4761);\nexports.sha224 = __webpack_require__(799);\nexports.sha256 = __webpack_require__(9344);\nexports.sha384 = __webpack_require__(772);\nexports.sha512 = __webpack_require__(5900);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA0MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix3Q0FBaUM7QUFDakMseUNBQXFDO0FBQ3JDLDBDQUFxQztBQUNyQyx5Q0FBcUM7QUFDckMsMENBQXFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcz81OTE5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGEvMScpO1xuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYS8yMjQnKTtcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEvMjU2Jyk7XG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhLzM4NCcpO1xuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYS81MTInKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9041\n")},4761:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_5 = utils.sum32_5;\nvar ft_1 = shaCommon.ft_1;\nvar BlockHash = common.BlockHash;\n\nvar sha1_K = [\n 0x5A827999, 0x6ED9EBA1,\n 0x8F1BBCDC, 0xCA62C1D6\n];\n\nfunction SHA1() {\n if (!(this instanceof SHA1))\n return new SHA1();\n\n BlockHash.call(this);\n this.h = [\n 0x67452301, 0xefcdab89, 0x98badcfe,\n 0x10325476, 0xc3d2e1f0 ];\n this.W = new Array(80);\n}\n\nutils.inherits(SHA1, BlockHash);\nmodule.exports = SHA1;\n\nSHA1.blockSize = 512;\nSHA1.outSize = 160;\nSHA1.hmacStrength = 80;\nSHA1.padLength = 64;\n\nSHA1.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n\n for(; i < W.length; i++)\n W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n\n for (i = 0; i < W.length; i++) {\n var s = ~~(i / 20);\n var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);\n e = d;\n d = c;\n c = rotl32(b, 30);\n b = a;\n a = t;\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n};\n\nSHA1.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc2MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVOztBQUVsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixRQUFRO0FBQzFCOztBQUVBLFFBQVEsY0FBYztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzEuanM/MTNlMiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGZ0XzEgPSBzaGFDb21tb24uZnRfMTtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMTtcblxuU0hBMS5ibG9ja1NpemUgPSA1MTI7XG5TSEExLm91dFNpemUgPSAxNjA7XG5TSEExLmhtYWNTdHJlbmd0aCA9IDgwO1xuU0hBMS5wYWRMZW5ndGggPSA2NDtcblxuU0hBMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuXG4gIGZvcig7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSByb3RsMzIoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSwgMSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4761\n")},799:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar SHA256 = __webpack_require__(9344);\n\nfunction SHA224() {\n if (!(this instanceof SHA224))\n return new SHA224();\n\n SHA256.call(this);\n this.h = [\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];\n}\nutils.inherits(SHA224, SHA256);\nmodule.exports = SHA224;\n\nSHA224.blockSize = 512;\nSHA224.outSize = 224;\nSHA224.hmacStrength = 192;\nSHA224.padLength = 64;\n\nSHA224.prototype._digest = function digest(enc) {\n // Just truncate output\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 7), 'big');\n else\n return utils.split32(this.h.slice(0, 7), 'big');\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVO0FBQzlCLGFBQWEsbUJBQU8sQ0FBQyxJQUFPOztBQUU1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzIyNC5qcz8wN2YyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBTSEEyNTYgPSByZXF1aXJlKCcuLzI1NicpO1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///799\n")},9344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\nvar assert = __webpack_require__(9746);\n\nvar sum32 = utils.sum32;\nvar sum32_4 = utils.sum32_4;\nvar sum32_5 = utils.sum32_5;\nvar ch32 = shaCommon.ch32;\nvar maj32 = shaCommon.maj32;\nvar s0_256 = shaCommon.s0_256;\nvar s1_256 = shaCommon.s1_256;\nvar g0_256 = shaCommon.g0_256;\nvar g1_256 = shaCommon.g1_256;\n\nvar BlockHash = common.BlockHash;\n\nvar sha256_K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\nfunction SHA256() {\n if (!(this instanceof SHA256))\n return new SHA256();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n ];\n this.k = sha256_K;\n this.W = new Array(64);\n}\nutils.inherits(SHA256, BlockHash);\nmodule.exports = SHA256;\n\nSHA256.blockSize = 512;\nSHA256.outSize = 256;\nSHA256.hmacStrength = 192;\nSHA256.padLength = 64;\n\nSHA256.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i++)\n W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n var f = this.h[5];\n var g = this.h[6];\n var h = this.h[7];\n\n assert(this.k.length === W.length);\n for (i = 0; i < W.length; i++) {\n var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);\n var T2 = sum32(s0_256(a), maj32(a, b, c));\n h = g;\n g = f;\n f = e;\n e = sum32(d, T1);\n d = c;\n c = b;\n b = a;\n a = sum32(T1, T2);\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n this.h[5] = sum32(this.h[5], f);\n this.h[6] = sum32(this.h[6], g);\n this.h[7] = sum32(this.h[7], h);\n};\n\nSHA256.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBLFNBQVMsY0FBYztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMjU2LmpzPzZlZWQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIHNoYUNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciBjaDMyID0gc2hhQ29tbW9uLmNoMzI7XG52YXIgbWFqMzIgPSBzaGFDb21tb24ubWFqMzI7XG52YXIgczBfMjU2ID0gc2hhQ29tbW9uLnMwXzI1NjtcbnZhciBzMV8yNTYgPSBzaGFDb21tb24uczFfMjU2O1xudmFyIGcwXzI1NiA9IHNoYUNvbW1vbi5nMF8yNTY7XG52YXIgZzFfMjU2ID0gc2hhQ29tbW9uLmcxXzI1NjtcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG4gIF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBUMSA9IHN1bTMyXzUoaCwgczFfMjU2KGUpLCBjaDMyKGUsIGYsIGcpLCB0aGlzLmtbaV0sIFdbaV0pO1xuICAgIHZhciBUMiA9IHN1bTMyKHMwXzI1NihhKSwgbWFqMzIoYSwgYiwgYykpO1xuICAgIGggPSBnO1xuICAgIGcgPSBmO1xuICAgIGYgPSBlO1xuICAgIGUgPSBzdW0zMihkLCBUMSk7XG4gICAgZCA9IGM7XG4gICAgYyA9IGI7XG4gICAgYiA9IGE7XG4gICAgYSA9IHN1bTMyKFQxLCBUMik7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xuICB0aGlzLmhbNV0gPSBzdW0zMih0aGlzLmhbNV0sIGYpO1xuICB0aGlzLmhbNl0gPSBzdW0zMih0aGlzLmhbNl0sIGcpO1xuICB0aGlzLmhbN10gPSBzdW0zMih0aGlzLmhbN10sIGgpO1xufTtcblxuU0hBMjU2LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9344\n")},772:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\n\nvar SHA512 = __webpack_require__(5900);\n\nfunction SHA384() {\n if (!(this instanceof SHA384))\n return new SHA384();\n\n SHA512.call(this);\n this.h = [\n 0xcbbb9d5d, 0xc1059ed8,\n 0x629a292a, 0x367cd507,\n 0x9159015a, 0x3070dd17,\n 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31,\n 0x8eb44a87, 0x68581511,\n 0xdb0c2e0d, 0x64f98fa7,\n 0x47b5481d, 0xbefa4fa4 ];\n}\nutils.inherits(SHA384, SHA512);\nmodule.exports = SHA384;\n\nSHA384.blockSize = 1024;\nSHA384.outSize = 384;\nSHA384.hmacStrength = 192;\nSHA384.padLength = 128;\n\nSHA384.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 12), 'big');\n else\n return utils.split32(this.h.slice(0, 12), 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcyLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVOztBQUU5QixhQUFhLG1CQUFPLENBQUMsSUFBTzs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMzg0LmpzPzhiOTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi81MTInKTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///772\n")},5900:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar assert = __webpack_require__(9746);\n\nvar rotr64_hi = utils.rotr64_hi;\nvar rotr64_lo = utils.rotr64_lo;\nvar shr64_hi = utils.shr64_hi;\nvar shr64_lo = utils.shr64_lo;\nvar sum64 = utils.sum64;\nvar sum64_hi = utils.sum64_hi;\nvar sum64_lo = utils.sum64_lo;\nvar sum64_4_hi = utils.sum64_4_hi;\nvar sum64_4_lo = utils.sum64_4_lo;\nvar sum64_5_hi = utils.sum64_5_hi;\nvar sum64_5_lo = utils.sum64_5_lo;\n\nvar BlockHash = common.BlockHash;\n\nvar sha512_K = [\n 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,\n 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,\n 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,\n 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,\n 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,\n 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,\n 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,\n 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,\n 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,\n 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,\n 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,\n 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,\n 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,\n 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,\n 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,\n 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,\n 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,\n 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,\n 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,\n 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,\n 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,\n 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,\n 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,\n 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,\n 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,\n 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,\n 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,\n 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,\n 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,\n 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,\n 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,\n 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,\n 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,\n 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,\n 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,\n 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,\n 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,\n 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,\n 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,\n 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817\n];\n\nfunction SHA512() {\n if (!(this instanceof SHA512))\n return new SHA512();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xf3bcc908,\n 0xbb67ae85, 0x84caa73b,\n 0x3c6ef372, 0xfe94f82b,\n 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1,\n 0x9b05688c, 0x2b3e6c1f,\n 0x1f83d9ab, 0xfb41bd6b,\n 0x5be0cd19, 0x137e2179 ];\n this.k = sha512_K;\n this.W = new Array(160);\n}\nutils.inherits(SHA512, BlockHash);\nmodule.exports = SHA512;\n\nSHA512.blockSize = 1024;\nSHA512.outSize = 512;\nSHA512.hmacStrength = 192;\nSHA512.padLength = 128;\n\nSHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {\n var W = this.W;\n\n // 32 x 32bit words\n for (var i = 0; i < 32; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i += 2) {\n var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2\n var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);\n var c1_hi = W[i - 14]; // i - 7\n var c1_lo = W[i - 13];\n var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15\n var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);\n var c3_hi = W[i - 32]; // i - 16\n var c3_lo = W[i - 31];\n\n W[i] = sum64_4_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n W[i + 1] = sum64_4_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n }\n};\n\nSHA512.prototype._update = function _update(msg, start) {\n this._prepareBlock(msg, start);\n\n var W = this.W;\n\n var ah = this.h[0];\n var al = this.h[1];\n var bh = this.h[2];\n var bl = this.h[3];\n var ch = this.h[4];\n var cl = this.h[5];\n var dh = this.h[6];\n var dl = this.h[7];\n var eh = this.h[8];\n var el = this.h[9];\n var fh = this.h[10];\n var fl = this.h[11];\n var gh = this.h[12];\n var gl = this.h[13];\n var hh = this.h[14];\n var hl = this.h[15];\n\n assert(this.k.length === W.length);\n for (var i = 0; i < W.length; i += 2) {\n var c0_hi = hh;\n var c0_lo = hl;\n var c1_hi = s1_512_hi(eh, el);\n var c1_lo = s1_512_lo(eh, el);\n var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);\n var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);\n var c3_hi = this.k[i];\n var c3_lo = this.k[i + 1];\n var c4_hi = W[i];\n var c4_lo = W[i + 1];\n\n var T1_hi = sum64_5_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n var T1_lo = sum64_5_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n\n c0_hi = s0_512_hi(ah, al);\n c0_lo = s0_512_lo(ah, al);\n c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);\n c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);\n\n var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);\n var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);\n\n hh = gh;\n hl = gl;\n\n gh = fh;\n gl = fl;\n\n fh = eh;\n fl = el;\n\n eh = sum64_hi(dh, dl, T1_hi, T1_lo);\n el = sum64_lo(dl, dl, T1_hi, T1_lo);\n\n dh = ch;\n dl = cl;\n\n ch = bh;\n cl = bl;\n\n bh = ah;\n bl = al;\n\n ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);\n al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);\n }\n\n sum64(this.h, 0, ah, al);\n sum64(this.h, 2, bh, bl);\n sum64(this.h, 4, ch, cl);\n sum64(this.h, 6, dh, dl);\n sum64(this.h, 8, eh, el);\n sum64(this.h, 10, fh, fl);\n sum64(this.h, 12, gh, gl);\n sum64(this.h, 14, hh, hl);\n};\n\nSHA512.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n\nfunction ch64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ ((~xh) & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction ch64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ ((~xl) & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 28);\n var c1_hi = rotr64_hi(xl, xh, 2); // 34\n var c2_hi = rotr64_hi(xl, xh, 7); // 39\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 28);\n var c1_lo = rotr64_lo(xl, xh, 2); // 34\n var c2_lo = rotr64_lo(xl, xh, 7); // 39\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 14);\n var c1_hi = rotr64_hi(xh, xl, 18);\n var c2_hi = rotr64_hi(xl, xh, 9); // 41\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 14);\n var c1_lo = rotr64_lo(xh, xl, 18);\n var c2_lo = rotr64_lo(xl, xh, 9); // 41\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 1);\n var c1_hi = rotr64_hi(xh, xl, 8);\n var c2_hi = shr64_hi(xh, xl, 7);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 1);\n var c1_lo = rotr64_lo(xh, xl, 8);\n var c2_lo = shr64_lo(xh, xl, 7);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 19);\n var c1_hi = rotr64_hi(xl, xh, 29); // 61\n var c2_hi = shr64_hi(xh, xl, 6);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 19);\n var c1_lo = rotr64_lo(xl, xh, 29); // 61\n var c2_lo = shr64_lo(xh, xl, 6);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTkwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixRQUFRO0FBQzFCO0FBQ0EsU0FBUyxjQUFjO0FBQ3ZCLGdEQUFnRDtBQUNoRDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzUxMi5qcz9iNTI1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbnZhciByb3RyNjRfaGkgPSB1dGlscy5yb3RyNjRfaGk7XG52YXIgcm90cjY0X2xvID0gdXRpbHMucm90cjY0X2xvO1xudmFyIHNocjY0X2hpID0gdXRpbHMuc2hyNjRfaGk7XG52YXIgc2hyNjRfbG8gPSB1dGlscy5zaHI2NF9sbztcbnZhciBzdW02NCA9IHV0aWxzLnN1bTY0O1xudmFyIHN1bTY0X2hpID0gdXRpbHMuc3VtNjRfaGk7XG52YXIgc3VtNjRfbG8gPSB1dGlscy5zdW02NF9sbztcbnZhciBzdW02NF80X2hpID0gdXRpbHMuc3VtNjRfNF9oaTtcbnZhciBzdW02NF80X2xvID0gdXRpbHMuc3VtNjRfNF9sbztcbnZhciBzdW02NF81X2hpID0gdXRpbHMuc3VtNjRfNV9oaTtcbnZhciBzdW02NF81X2xvID0gdXRpbHMuc3VtNjRfNV9sbztcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCxcbiAgICAweGJiNjdhZTg1LCAweDg0Y2FhNzNiLFxuICAgIDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIsXG4gICAgMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSxcbiAgICAweDUxMGU1MjdmLCAweGFkZTY4MmQxLFxuICAgIDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYsXG4gICAgMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YixcbiAgICAweDViZTBjZDE5LCAweDEzN2UyMTc5IF07XG4gIHRoaXMuayA9IHNoYTUxMl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoMTYwKTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTUxMiwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBNTEyO1xuXG5TSEE1MTIuYmxvY2tTaXplID0gMTAyNDtcblNIQTUxMi5vdXRTaXplID0gNTEyO1xuU0hBNTEyLmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTUxMi5wYWRMZW5ndGggPSAxMjg7XG5cblNIQTUxMi5wcm90b3R5cGUuX3ByZXBhcmVCbG9jayA9IGZ1bmN0aW9uIF9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICAvLyAzMiB4IDMyYml0IHdvcmRzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGcxXzUxMl9oaShXW2kgLSA0XSwgV1tpIC0gM10pOyAgLy8gaSAtIDJcbiAgICB2YXIgYzBfbG8gPSBnMV81MTJfbG8oV1tpIC0gNF0sIFdbaSAtIDNdKTtcbiAgICB2YXIgYzFfaGkgPSBXW2kgLSAxNF07ICAvLyBpIC0gN1xuICAgIHZhciBjMV9sbyA9IFdbaSAtIDEzXTtcbiAgICB2YXIgYzJfaGkgPSBnMF81MTJfaGkoV1tpIC0gMzBdLCBXW2kgLSAyOV0pOyAgLy8gaSAtIDE1XG4gICAgdmFyIGMyX2xvID0gZzBfNTEyX2xvKFdbaSAtIDMwXSwgV1tpIC0gMjldKTtcbiAgICB2YXIgYzNfaGkgPSBXW2kgLSAzMl07ICAvLyBpIC0gMTZcbiAgICB2YXIgYzNfbG8gPSBXW2kgLSAzMV07XG5cbiAgICBXW2ldID0gc3VtNjRfNF9oaShcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyk7XG4gICAgV1tpICsgMV0gPSBzdW02NF80X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcbiAgICB2YXIgVDFfbG8gPSBzdW02NF81X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcblxuICAgIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgYzBfbG8gPSBzMF81MTJfbG8oYWgsIGFsKTtcbiAgICBjMV9oaSA9IG1hajY0X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wpO1xuICAgIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gY2g2NF9oaSh4aCwgeGwsIHloLCB5bCwgemgpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICh4aCAmIHpoKSBeICh5aCAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKHhsICYgemwpIF4gKHlsICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDEpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDEpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5900\n")},7038:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar rotr32 = utils.rotr32;\n\nfunction ft_1(s, x, y, z) {\n if (s === 0)\n return ch32(x, y, z);\n if (s === 1 || s === 3)\n return p32(x, y, z);\n if (s === 2)\n return maj32(x, y, z);\n}\nexports.ft_1 = ft_1;\n\nfunction ch32(x, y, z) {\n return (x & y) ^ ((~x) & z);\n}\nexports.ch32 = ch32;\n\nfunction maj32(x, y, z) {\n return (x & y) ^ (x & z) ^ (y & z);\n}\nexports.maj32 = maj32;\n\nfunction p32(x, y, z) {\n return x ^ y ^ z;\n}\nexports.p32 = p32;\n\nfunction s0_256(x) {\n return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);\n}\nexports.s0_256 = s0_256;\n\nfunction s1_256(x) {\n return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);\n}\nexports.s1_256 = s1_256;\n\nfunction g0_256(x) {\n return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);\n}\nexports.g0_256 = g0_256;\n\nfunction g1_256(x) {\n return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);\n}\nexports.g1_256 = g1_256;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAzOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0EsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxjQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS9jb21tb24uanM/YWE1NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgcm90cjMyID0gdXRpbHMucm90cjMyO1xuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuZXhwb3J0cy5mdF8xID0gZnRfMTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cbmV4cG9ydHMuY2gzMiA9IGNoMzI7XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cbmV4cG9ydHMubWFqMzIgPSBtYWozMjtcblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cbmV4cG9ydHMucDMyID0gcDMyO1xuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5leHBvcnRzLnMwXzI1NiA9IHMwXzI1NjtcblxuZnVuY3Rpb24gczFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA2KSBeIHJvdHIzMih4LCAxMSkgXiByb3RyMzIoeCwgMjUpO1xufVxuZXhwb3J0cy5zMV8yNTYgPSBzMV8yNTY7XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuZXhwb3J0cy5nMF8yNTYgPSBnMF8yNTY7XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5leHBvcnRzLmcxXzI1NiA9IGcxXzI1NjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7038\n")},6436:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar assert = __webpack_require__(9746);\nvar inherits = __webpack_require__(5717);\n\nexports.inherits = inherits;\n\nfunction isSurrogatePair(msg, i) {\n if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {\n return false;\n }\n if (i < 0 || i + 1 >= msg.length) {\n return false;\n }\n return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;\n}\n\nfunction toArray(msg, enc) {\n if (Array.isArray(msg))\n return msg.slice();\n if (!msg)\n return [];\n var res = [];\n if (typeof msg === 'string') {\n if (!enc) {\n // Inspired by stringToUtf8ByteArray() in closure-library by Google\n // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143\n // Apache License 2.0\n // https://github.com/google/closure-library/blob/master/LICENSE\n var p = 0;\n for (var i = 0; i < msg.length; i++) {\n var c = msg.charCodeAt(i);\n if (c < 128) {\n res[p++] = c;\n } else if (c < 2048) {\n res[p++] = (c >> 6) | 192;\n res[p++] = (c & 63) | 128;\n } else if (isSurrogatePair(msg, i)) {\n c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);\n res[p++] = (c >> 18) | 240;\n res[p++] = ((c >> 12) & 63) | 128;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n } else {\n res[p++] = (c >> 12) | 224;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n }\n }\n } else if (enc === 'hex') {\n msg = msg.replace(/[^a-z0-9]+/ig, '');\n if (msg.length % 2 !== 0)\n msg = '0' + msg;\n for (i = 0; i < msg.length; i += 2)\n res.push(parseInt(msg[i] + msg[i + 1], 16));\n }\n } else {\n for (i = 0; i < msg.length; i++)\n res[i] = msg[i] | 0;\n }\n return res;\n}\nexports.toArray = toArray;\n\nfunction toHex(msg) {\n var res = '';\n for (var i = 0; i < msg.length; i++)\n res += zero2(msg[i].toString(16));\n return res;\n}\nexports.toHex = toHex;\n\nfunction htonl(w) {\n var res = (w >>> 24) |\n ((w >>> 8) & 0xff00) |\n ((w << 8) & 0xff0000) |\n ((w & 0xff) << 24);\n return res >>> 0;\n}\nexports.htonl = htonl;\n\nfunction toHex32(msg, endian) {\n var res = '';\n for (var i = 0; i < msg.length; i++) {\n var w = msg[i];\n if (endian === 'little')\n w = htonl(w);\n res += zero8(w.toString(16));\n }\n return res;\n}\nexports.toHex32 = toHex32;\n\nfunction zero2(word) {\n if (word.length === 1)\n return '0' + word;\n else\n return word;\n}\nexports.zero2 = zero2;\n\nfunction zero8(word) {\n if (word.length === 7)\n return '0' + word;\n else if (word.length === 6)\n return '00' + word;\n else if (word.length === 5)\n return '000' + word;\n else if (word.length === 4)\n return '0000' + word;\n else if (word.length === 3)\n return '00000' + word;\n else if (word.length === 2)\n return '000000' + word;\n else if (word.length === 1)\n return '0000000' + word;\n else\n return word;\n}\nexports.zero8 = zero8;\n\nfunction join32(msg, start, end, endian) {\n var len = end - start;\n assert(len % 4 === 0);\n var res = new Array(len / 4);\n for (var i = 0, k = start; i < res.length; i++, k += 4) {\n var w;\n if (endian === 'big')\n w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];\n else\n w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];\n res[i] = w >>> 0;\n }\n return res;\n}\nexports.join32 = join32;\n\nfunction split32(msg, endian) {\n var res = new Array(msg.length * 4);\n for (var i = 0, k = 0; i < msg.length; i++, k += 4) {\n var m = msg[i];\n if (endian === 'big') {\n res[k] = m >>> 24;\n res[k + 1] = (m >>> 16) & 0xff;\n res[k + 2] = (m >>> 8) & 0xff;\n res[k + 3] = m & 0xff;\n } else {\n res[k + 3] = m >>> 24;\n res[k + 2] = (m >>> 16) & 0xff;\n res[k + 1] = (m >>> 8) & 0xff;\n res[k] = m & 0xff;\n }\n }\n return res;\n}\nexports.split32 = split32;\n\nfunction rotr32(w, b) {\n return (w >>> b) | (w << (32 - b));\n}\nexports.rotr32 = rotr32;\n\nfunction rotl32(w, b) {\n return (w << b) | (w >>> (32 - b));\n}\nexports.rotl32 = rotl32;\n\nfunction sum32(a, b) {\n return (a + b) >>> 0;\n}\nexports.sum32 = sum32;\n\nfunction sum32_3(a, b, c) {\n return (a + b + c) >>> 0;\n}\nexports.sum32_3 = sum32_3;\n\nfunction sum32_4(a, b, c, d) {\n return (a + b + c + d) >>> 0;\n}\nexports.sum32_4 = sum32_4;\n\nfunction sum32_5(a, b, c, d, e) {\n return (a + b + c + d + e) >>> 0;\n}\nexports.sum32_5 = sum32_5;\n\nfunction sum64(buf, pos, ah, al) {\n var bh = buf[pos];\n var bl = buf[pos + 1];\n\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n buf[pos] = hi >>> 0;\n buf[pos + 1] = lo;\n}\nexports.sum64 = sum64;\n\nfunction sum64_hi(ah, al, bh, bl) {\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n return hi >>> 0;\n}\nexports.sum64_hi = sum64_hi;\n\nfunction sum64_lo(ah, al, bh, bl) {\n var lo = al + bl;\n return lo >>> 0;\n}\nexports.sum64_lo = sum64_lo;\n\nfunction sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n\n var hi = ah + bh + ch + dh + carry;\n return hi >>> 0;\n}\nexports.sum64_4_hi = sum64_4_hi;\n\nfunction sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {\n var lo = al + bl + cl + dl;\n return lo >>> 0;\n}\nexports.sum64_4_lo = sum64_4_lo;\n\nfunction sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n lo = (lo + el) >>> 0;\n carry += lo < el ? 1 : 0;\n\n var hi = ah + bh + ch + dh + eh + carry;\n return hi >>> 0;\n}\nexports.sum64_5_hi = sum64_5_hi;\n\nfunction sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var lo = al + bl + cl + dl + el;\n\n return lo >>> 0;\n}\nexports.sum64_5_lo = sum64_5_lo;\n\nfunction rotr64_hi(ah, al, num) {\n var r = (al << (32 - num)) | (ah >>> num);\n return r >>> 0;\n}\nexports.rotr64_hi = rotr64_hi;\n\nfunction rotr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.rotr64_lo = rotr64_lo;\n\nfunction shr64_hi(ah, al, num) {\n return ah >>> num;\n}\nexports.shr64_hi = shr64_hi;\n\nfunction shr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.shr64_lo = shr64_lo;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBcUI7QUFDMUMsZUFBZSxtQkFBTyxDQUFDLElBQVU7O0FBRWpDLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGdCQUFnQjtBQUN0QztBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0EsSUFBSTtBQUNKLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsZ0JBQWdCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcz9jM2MwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuaW5oZXJpdHMgPSBpbmhlcml0cztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkge1xuICBpZiAoKG1zZy5jaGFyQ29kZUF0KGkpICYgMHhGQzAwKSAhPT0gMHhEODAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpIDwgMCB8fCBpICsgMSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAobXNnLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwO1xufVxuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIC8vIEluc3BpcmVkIGJ5IHN0cmluZ1RvVXRmOEJ5dGVBcnJheSgpIGluIGNsb3N1cmUtbGlicmFyeSBieSBHb29nbGVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvODU5OGQ4NzI0MmFmNTlhYWMyMzMyNzA3NDJjODk4NGUyYjJiZGJlMC9jbG9zdXJlL2dvb2cvY3J5cHQvY3J5cHQuanMjTDExNy1MMTQzXG4gICAgICAvLyBBcGFjaGUgTGljZW5zZSAyLjBcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAgICAgIHZhciBwID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSBjO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPCAyMDQ4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyA+PiA2KSB8IDE5MjtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3Vycm9nYXRlUGFpcihtc2csIGkpKSB7XG4gICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgJiAweDAzRkYpIDw8IDEwKSArIChtc2cuY2hhckNvZGVBdCgrK2kpICYgMHgwM0ZGKTtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDE4KSB8IDI0MDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiAxMikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoKGMgPj4gNikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyAmIDYzKSB8IDEyODtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDEyKSB8IDIyNDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleCA9IHRvSGV4O1xuXG5mdW5jdGlvbiBodG9ubCh3KSB7XG4gIHZhciByZXMgPSAodyA+Pj4gMjQpIHxcbiAgICAgICAgICAgICgodyA+Pj4gOCkgJiAweGZmMDApIHxcbiAgICAgICAgICAgICgodyA8PCA4KSAmIDB4ZmYwMDAwKSB8XG4gICAgICAgICAgICAoKHcgJiAweGZmKSA8PCAyNCk7XG4gIHJldHVybiByZXMgPj4+IDA7XG59XG5leHBvcnRzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHplcm84KHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSA3KVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNilcbiAgICByZXR1cm4gJzAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA1KVxuICAgIHJldHVybiAnMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA0KVxuICAgIHJldHVybiAnMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMylcbiAgICByZXR1cm4gJzAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAyKVxuICAgIHJldHVybiAnMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMDAwMDAwMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5zcGxpdDMyID0gc3BsaXQzMjtcblxuZnVuY3Rpb24gcm90cjMyKHcsIGIpIHtcbiAgcmV0dXJuICh3ID4+PiBiKSB8ICh3IDw8ICgzMiAtIGIpKTtcbn1cbmV4cG9ydHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyID0gc3VtMzI7XG5cbmZ1bmN0aW9uIHN1bTMyXzMoYSwgYiwgYykge1xuICByZXR1cm4gKGEgKyBiICsgYykgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNSA9IHN1bTMyXzU7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0X2hpID0gc3VtNjRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0X2xvKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IGFsICsgYmw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNF9sbyA9IHN1bTY0XzRfbG87XG5cbmZ1bmN0aW9uIHN1bTY0XzVfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZWwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGVsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBlaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMucm90cjY0X2hpID0gcm90cjY0X2hpO1xuXG5mdW5jdGlvbiByb3RyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufVxuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnNocjY0X2xvID0gc2hyNjRfbG87XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6436\n")},5717:function(module){eval("if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTcxNy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzPzNmYjUiXSwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5717\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},9746:function(module){eval("module.exports = assert;\n\nfunction assert(val, msg) {\n if (!val)\n throw new Error(msg || 'Assertion failed');\n}\n\nassert.equal = function assertEqual(l, r, msg) {\n if (l != r)\n throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvbWluaW1hbGlzdGljLWFzc2VydC9pbmRleC5qcz9kYTNlIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXNzZXJ0O1xuXG5mdW5jdGlvbiBhc3NlcnQodmFsLCBtc2cpIHtcbiAgaWYgKCF2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBhc3NlcnRFcXVhbChsLCByLCBtc2cpIHtcbiAgaWYgKGwgIT0gcilcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICgnQXNzZXJ0aW9uIGZhaWxlZDogJyArIGwgKyAnICE9ICcgKyByKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9746\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz81OWY4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz8zNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/MWJmMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzP2I4OGUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NmRiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/ZmI1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz9mMGYzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/YjMwZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz82OTY3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzP2E4ZjciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz83NzYwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/Yjg2MiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzc0OWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz9hYTJiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82ZGMxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz83ZmY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZDJhYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzPzYwOGYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzPzY5NDciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz83YTkyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz80NTY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YjY2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzP2FhYTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz9lZDA1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz9mMTM2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZWVlNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz84MTA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzPzdmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz8zNTA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz9iYTg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz9jZGZlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz8zNGI3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzkxOWUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9jZjY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz8wZjA5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/ZTQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz8zMmFlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzJjNTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/ZThjZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/M2Q3NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9jNmVmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/MGFlMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/MmI4ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/NzczNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzPzViNGEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzPzY4MWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz81NmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzPzUxYTAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/M2JkYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz9iN2UzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzPzA5YmMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZThlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/MDY5OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/ZjhkMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz9lNGZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzPzJhMmYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/MTNkNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9jNjA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(Q){var t=__webpack_module_cache__[Q];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[Q]={exports:{}};return __webpack_modules__[Q](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=function(Q){var t=Q&&Q.__esModule?function(){return Q.default}:function(){return Q};return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=function(Q,t){for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(Q,n)&&Object.defineProperty(Q,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=function(Q,t){return Object.prototype.hasOwnProperty.call(Q,t)};var __webpack_exports__=__webpack_require__(6960)})(); \ No newline at end of file diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt index 9bb6b2032e..3e0c93b107 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt @@ -7,10 +7,12 @@ package org.readium.r2.navigator import android.graphics.PointF +import android.view.View import kotlin.time.Duration import kotlin.time.ExperimentalTime import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow +import org.readium.r2.navigator.input.InputListener import org.readium.r2.navigator.media.MediaPlayback import org.readium.r2.navigator.preferences.Axis import org.readium.r2.navigator.preferences.ReadingProgression @@ -105,17 +107,15 @@ interface NavigatorDelegate { interface VisualNavigator : Navigator { /** - * Current presentation rendered by the navigator. + * View displaying the publication. */ - @ExperimentalReadiumApi - val presentation: StateFlow + val publicationView: View /** - * Returns the [Locator] to the first content element that begins on the current screen. + * Current presentation rendered by the navigator. */ @ExperimentalReadiumApi - suspend fun firstVisibleElementLocator(): Locator? = - currentLocator.value + val presentation: StateFlow @ExperimentalReadiumApi interface Presentation { @@ -135,43 +135,36 @@ interface VisualNavigator : Navigator { val axis: Axis } + /** + * Returns the [Locator] to the first content element that begins on the current screen. + */ + @ExperimentalReadiumApi + suspend fun firstVisibleElementLocator(): Locator? = + currentLocator.value + + /** + * Adds a new [InputListener] to receive touch, mouse or keyboard events. + * + * Registration order is critical, as listeners may consume the events and prevent others from + * receiving them. + */ + @ExperimentalReadiumApi + fun addInputListener(listener: InputListener) + + /** + * Removes a previously registered [InputListener]. + */ + @ExperimentalReadiumApi + fun removeInputListener(listener: InputListener) + interface Listener : Navigator.Listener { - /** - * Called when the user tapped the content, but nothing handled the event internally (eg. - * by following an internal link). - * - * Can be used in the reading app to toggle the navigation bars, or switch to the - * previous/next page if the tapped occurred on the edges. - * - * The [point] is relative to the navigator's view. - */ + @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) fun onTap(point: PointF): Boolean = false - - /** - * Called when the user starts dragging the content, but nothing handled the event - * internally. - * - * The points are relative to the navigator's view. - */ - @ExperimentalDragGesture + @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) fun onDragStart(startPoint: PointF, offset: PointF): Boolean = false - - /** - * Called when the user continues dragging the content, but nothing handled the event - * internally. - * - * The points are relative to the navigator's view. - */ - @ExperimentalDragGesture + @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) fun onDragMove(startPoint: PointF, offset: PointF): Boolean = false - - /** - * Called when the user stops dragging the content, but nothing handled the event - * internally. - * - * The points are relative to the navigator's view. - */ - @ExperimentalDragGesture + @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) fun onDragEnd(startPoint: PointF, offset: PointF): Boolean = false } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt index 58cfd18d27..5d9a189711 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt @@ -35,6 +35,9 @@ import org.json.JSONObject import org.jsoup.Jsoup import org.jsoup.safety.Safelist import org.readium.r2.navigator.extensions.optRectF +import org.readium.r2.navigator.input.InputModifier +import org.readium.r2.navigator.input.Key +import org.readium.r2.navigator.input.KeyEvent import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.extensions.optNullableString import org.readium.r2.shared.extensions.tryOrLog @@ -61,6 +64,7 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte fun onDragStart(event: DragEvent): Boolean fun onDragMove(event: DragEvent): Boolean fun onDragEnd(event: DragEvent): Boolean + fun onKey(event: KeyEvent): Boolean = false fun onDecorationActivated(id: DecorationId, group: String, rect: RectF, point: PointF): Boolean = false fun onProgressionChanged() fun onHighlightActivated(id: String) @@ -439,6 +443,23 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte return runBlocking(uiScope.coroutineContext) { listener?.onDragEnd(event) ?: false } } + @android.webkit.JavascriptInterface + fun onKey(eventJson: String): Boolean { + val jsonObject = JSONObject(eventJson) + val event = KeyEvent( + type = when (jsonObject.optString("type")) { + "down" -> KeyEvent.Type.Down + "up" -> KeyEvent.Type.Up + else -> return false + }, + key = Key(jsonObject.optString("code")), + modifiers = inputModifiers(jsonObject), + characters = jsonObject.optNullableString("characters")?.takeUnless { it.isBlank() } + ) + + return listener?.onKey(event) ?: false + } + @android.webkit.JavascriptInterface fun onSelectionStart() { isSelecting = true @@ -668,3 +689,19 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte ?: super.onGetContentRect(mode, view, outRect) } } + +private fun inputModifiers(json: JSONObject): Set = + buildSet { + if (json.optBoolean("alt")) { + add(InputModifier.Alt) + } + if (json.optBoolean("control")) { + add(InputModifier.Control) + } + if (json.optBoolean("shift")) { + add(InputModifier.Shift) + } + if (json.optBoolean("meta")) { + add(InputModifier.Meta) + } + } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt index d1822037d0..0434afe439 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt @@ -11,6 +11,7 @@ package org.readium.r2.navigator import android.content.Context import android.graphics.Rect +import android.os.Build import android.util.AttributeSet import android.view.* import android.view.animation.Interpolator @@ -189,7 +190,13 @@ class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView(context, private fun initWebPager() { setWillNotDraw(false) descendantFocusability = ViewGroup.FOCUS_AFTER_DESCENDANTS - isFocusable = true + + // Disable the focus overlay appearing when interacting with the keyboard. + // https://developer.android.com/about/versions/oreo/android-8.0-changes#ian + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + defaultFocusHighlightEnabled = false + } + val context = context mScroller = Scroller(context, sInterpolator) val configuration = ViewConfiguration.get(context) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2AudiobookActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2AudiobookActivity.kt index d0aa2c25ec..617aadf557 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2AudiobookActivity.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2AudiobookActivity.kt @@ -19,17 +19,19 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.readium.r2.navigator.BuildConfig.DEBUG import org.readium.r2.navigator.IR2Activity +import org.readium.r2.navigator.Navigator import org.readium.r2.navigator.NavigatorDelegate import org.readium.r2.navigator.R -import org.readium.r2.navigator.VisualNavigator import org.readium.r2.navigator.databinding.ActivityR2AudiobookBinding -import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.extensions.getPublication -import org.readium.r2.shared.publication.* +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.indexOfFirstWithHref import org.readium.r2.shared.publication.services.isRestricted import timber.log.Timber -open class R2AudiobookActivity : AppCompatActivity(), CoroutineScope, IR2Activity, MediaPlayerCallback, VisualNavigator { +open class R2AudiobookActivity : AppCompatActivity(), CoroutineScope, IR2Activity, MediaPlayerCallback, Navigator { override val currentLocator: StateFlow get() = _currentLocator private val _currentLocator = MutableStateFlow(Locator(href = "#", type = "")) @@ -101,14 +103,6 @@ open class R2AudiobookActivity : AppCompatActivity(), CoroutineScope, IR2Activit return true } - @Deprecated("Use `presentation.value.readingProgression` instead", replaceWith = ReplaceWith("presentation.value.readingProgression")) - override val readingProgression: ReadingProgression - get() = TODO("not implemented") // To change initializer of created properties use File | Settings | File Templates. - - @ExperimentalReadiumApi - override val presentation: StateFlow - get() = TODO("Not yet implemented") - /** * Context of this scope. */ diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt index 1ef8a4b0c8..8a3abda440 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt @@ -31,6 +31,7 @@ import org.readium.r2.navigator.NavigatorDelegate import org.readium.r2.navigator.R import org.readium.r2.navigator.VisualNavigator import org.readium.r2.navigator.image.ImageNavigatorFragment +import org.readium.r2.navigator.input.InputListener import org.readium.r2.navigator.pager.R2PagerAdapter import org.readium.r2.navigator.pager.R2ViewPager import org.readium.r2.navigator.util.CompositeFragmentFactory @@ -55,10 +56,23 @@ open class R2CbzActivity : AppCompatActivity(), CoroutineScope, IR2Activity, Vis override val currentLocator: StateFlow get() = navigatorFragment.currentLocator + override val publicationView: View + get() = navigatorFragment.publicationView + @ExperimentalReadiumApi override val presentation: StateFlow get() = navigatorFragment.presentation + @ExperimentalReadiumApi + override fun addInputListener(listener: InputListener) { + navigatorFragment.addInputListener(listener) + } + + @ExperimentalReadiumApi + override fun removeInputListener(listener: InputListener) { + navigatorFragment.removeInputListener(listener) + } + override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { return navigatorFragment.go(locator, animated, completion) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt index ffb45d513a..03bb6e9ecd 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt @@ -51,6 +51,12 @@ import org.readium.r2.navigator.epub.css.buildFontFamilyDeclaration import org.readium.r2.navigator.extensions.optRectF import org.readium.r2.navigator.extensions.positionsByResource import org.readium.r2.navigator.html.HtmlDecorationTemplates +import org.readium.r2.navigator.input.CompositeInputListener +import org.readium.r2.navigator.input.DragEvent +import org.readium.r2.navigator.input.InputListener +import org.readium.r2.navigator.input.KeyEvent +import org.readium.r2.navigator.input.KeyInterceptorView +import org.readium.r2.navigator.input.TapEvent import org.readium.r2.navigator.pager.R2EpubPageFragment import org.readium.r2.navigator.pager.R2PagerAdapter import org.readium.r2.navigator.pager.R2PagerAdapter.PageResource @@ -242,8 +248,6 @@ class EpubNavigatorFragment internal constructor( require(!publication.isRestricted) { "The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection." } } - override val presentation: StateFlow get() = viewModel.presentation - // Configurable override val settings: StateFlow get() = viewModel.settings @@ -304,7 +308,7 @@ class EpubNavigatorFragment internal constructor( ): View { currentActivity = requireActivity() _binding = ActivityR2ViewpagerBinding.inflate(inflater, container, false) - val view = binding.root + var view: View = binding.root positionsByReadingOrder = runBlocking { publication.positionsByReadingOrder() } positions = positionsByReadingOrder.flatten() @@ -403,6 +407,11 @@ class EpubNavigatorFragment internal constructor( } }) + // Fixed layout publications cannot intercept JS events yet. + if (publication.metadata.presentation.layout == EpubLayout.FIXED) { + view = KeyInterceptorView(view, this, inputListener) + } + return view } @@ -421,6 +430,8 @@ class EpubNavigatorFragment internal constructor( EpubLayout.FIXED -> Publication.TYPE.FXL } resourcePager.setBackgroundColor(viewModel.settings.value.effectiveBackgroundColor) + // Let the page views handle the keyboard events. + resourcePager.isFocusable = false parent.addView(resourcePager) @@ -619,6 +630,26 @@ class EpubNavigatorFragment internal constructor( } } + // VisualNavigator + + override val publicationView: View + get() = requireView() + + override val presentation: StateFlow get() = viewModel.presentation + + override val readingProgression: PublicationReadingProgression + get() = viewModel.readingProgression + + private val inputListener = CompositeInputListener() + + override fun addInputListener(listener: InputListener) { + inputListener.add(listener) + } + + override fun removeInputListener(listener: InputListener) { + inputListener.remove(listener) + } + // SelectableNavigator override suspend fun currentSelection(): Selection? { @@ -718,25 +749,29 @@ class EpubNavigatorFragment internal constructor( } override fun onTap(point: PointF): Boolean = - listener?.onTap(point.adjustedToViewport()) ?: false + inputListener.onTap(this@EpubNavigatorFragment, TapEvent(point)) override fun onDragStart(event: R2BasicWebView.DragEvent): Boolean = - listener?.onDragStart( - startPoint = event.startPoint.adjustedToViewport(), - offset = event.offset - ) ?: false + onDrag(DragEvent.Type.Start, event) override fun onDragMove(event: R2BasicWebView.DragEvent): Boolean = - listener?.onDragMove( - startPoint = event.startPoint.adjustedToViewport(), - offset = event.offset - ) ?: false + onDrag(DragEvent.Type.Move, event) override fun onDragEnd(event: R2BasicWebView.DragEvent): Boolean = - listener?.onDragEnd( - startPoint = event.startPoint.adjustedToViewport(), - offset = event.offset - ) ?: false + onDrag(DragEvent.Type.End, event) + + private fun onDrag(type: DragEvent.Type, event: R2BasicWebView.DragEvent): Boolean = + inputListener.onDrag( + this@EpubNavigatorFragment, + DragEvent( + type = type, + start = event.startPoint.adjustedToViewport(), + offset = event.offset + ) + ) + + override fun onKey(event: KeyEvent): Boolean = + inputListener.onKey(this@EpubNavigatorFragment, event) override fun onDecorationActivated( id: DecorationId, @@ -913,9 +948,6 @@ class EpubNavigatorFragment internal constructor( return null } - override val readingProgression: PublicationReadingProgression - get() = viewModel.readingProgression - override val currentLocator: StateFlow get() = _currentLocator private val _currentLocator = MutableStateFlow( initialLocator diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/R2EpubActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/R2EpubActivity.kt index fb0e46b428..0805aa64c6 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/R2EpubActivity.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/R2EpubActivity.kt @@ -11,7 +11,6 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.graphics.Color -import android.graphics.PointF import android.graphics.Rect import android.os.Bundle import android.util.DisplayMetrics @@ -26,6 +25,7 @@ import kotlinx.coroutines.flow.StateFlow import org.json.JSONException import org.json.JSONObject import org.readium.r2.navigator.* +import org.readium.r2.navigator.input.InputListener import org.readium.r2.navigator.pager.R2EpubPageFragment import org.readium.r2.navigator.pager.R2PagerAdapter import org.readium.r2.navigator.pager.R2ViewPager @@ -154,6 +154,9 @@ open class R2EpubActivity : AppCompatActivity(), IR2Activity, IR2Selectable, IR2 } } + override val publicationView: View + get() = navigatorFragment().publicationView + @Deprecated("Use `presentation.value.readingProgression` instead", replaceWith = ReplaceWith("presentation.value.readingProgression")) override val readingProgression: ReadingProgression get() = navigatorFragment().readingProgression @@ -162,6 +165,16 @@ open class R2EpubActivity : AppCompatActivity(), IR2Activity, IR2Selectable, IR2 override val presentation: StateFlow get() = navigatorFragment().presentation + @ExperimentalReadiumApi + override fun addInputListener(listener: InputListener) { + navigatorFragment().addInputListener(listener) + } + + @ExperimentalReadiumApi + override fun removeInputListener(listener: InputListener) { + navigatorFragment().removeInputListener(listener) + } + @Suppress("DEPRECATION") override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { navigatorFragment().go(locator, animated, completion) @@ -192,11 +205,6 @@ open class R2EpubActivity : AppCompatActivity(), IR2Activity, IR2Selectable, IR2 return navigatorFragment().goBackward(animated, completion) } - override fun onTap(point: PointF): Boolean { - toggleActionBar() - return super.onTap(point) - } - override fun currentSelection(callback: (Locator?) -> Unit) { currentFragment?.webView?.getCurrentSelectionInfo { val selection = JSONObject(it) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt index a09dc468e8..0eb3d48fd8 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt @@ -27,6 +27,10 @@ import org.readium.r2.navigator.SimplePresentation import org.readium.r2.navigator.VisualNavigator import org.readium.r2.navigator.databinding.ActivityR2ViewpagerBinding import org.readium.r2.navigator.extensions.layoutDirectionIsRTL +import org.readium.r2.navigator.input.CompositeInputListener +import org.readium.r2.navigator.input.InputListener +import org.readium.r2.navigator.input.KeyInterceptorView +import org.readium.r2.navigator.input.TapEvent import org.readium.r2.navigator.pager.R2CbzPageFragment import org.readium.r2.navigator.pager.R2PagerAdapter import org.readium.r2.navigator.pager.R2ViewPager @@ -78,25 +82,9 @@ class ImageNavigatorFragment private constructor( private var _binding: ActivityR2ViewpagerBinding? = null private val binding get() = _binding!! - override val readingProgression: PublicationReadingProgression = - publication.metadata.effectiveReadingProgression - - @ExperimentalReadiumApi - override val presentation: StateFlow = - MutableStateFlow( - SimplePresentation( - readingProgression = when (readingProgression) { - PublicationReadingProgression.RTL -> ReadingProgression.RTL - else -> ReadingProgression.LTR - }, - scroll = false, - axis = Axis.HORIZONTAL - ) - ).asStateFlow() - override fun onCreate(savedInstanceState: Bundle?) { childFragmentManager.fragmentFactory = createFragmentFactory { - R2CbzPageFragment(publication) { x, y -> this.listener?.onTap(PointF(x, y)) } + R2CbzPageFragment(publication) { x, y -> inputListener.onTap(this, TapEvent(PointF(x, y))) } } super.onCreate(savedInstanceState) } @@ -144,7 +132,7 @@ class ImageNavigatorFragment private constructor( go(initialLocator) } - return view + return KeyInterceptorView(view, this, inputListener) } override fun onStart() { @@ -224,6 +212,37 @@ class ImageNavigatorFragment private constructor( return current != resourcePager.currentItem } + // VisualNavigator + + override val publicationView: View + get() = requireView() + + override val readingProgression: PublicationReadingProgression = + publication.metadata.effectiveReadingProgression + + @ExperimentalReadiumApi + override val presentation: StateFlow = + MutableStateFlow( + SimplePresentation( + readingProgression = when (readingProgression) { + PublicationReadingProgression.RTL -> ReadingProgression.RTL + else -> ReadingProgression.LTR + }, + scroll = false, + axis = Axis.HORIZONTAL + ) + ).asStateFlow() + + private val inputListener = CompositeInputListener() + + override fun addInputListener(listener: InputListener) { + inputListener.add(listener) + } + + override fun removeInputListener(listener: InputListener) { + inputListener.remove(listener) + } + companion object { /** diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/input/DragEvent.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/input/DragEvent.kt new file mode 100644 index 0000000000..ed2daff2d2 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/input/DragEvent.kt @@ -0,0 +1,16 @@ +package org.readium.r2.navigator.input + +import android.graphics.PointF + +/** + * Represents a drag event emitted by a navigator from a [start] point moved by an [offset]. + * + * All the points are relative to the navigator view. + */ +data class DragEvent( + val type: Type, + val start: PointF, + val offset: PointF +) { + enum class Type { Start, Move, End } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/input/InputListener.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/input/InputListener.kt new file mode 100644 index 0000000000..79b8e24bad --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/input/InputListener.kt @@ -0,0 +1,45 @@ +package org.readium.r2.navigator.input + +import org.readium.r2.navigator.VisualNavigator +import org.readium.r2.shared.ExperimentalReadiumApi + +@ExperimentalReadiumApi +interface InputListener { + /** + * Called when the user tapped the content, but nothing handled the event internally (eg. + * by following an internal link). + */ + fun onTap(navigator: VisualNavigator, event: TapEvent): Boolean = false + + /** + * Called when the user dragged the content, but nothing handled the event internally. + */ + fun onDrag(navigator: VisualNavigator, event: DragEvent): Boolean = false + + /** + * Called when the user pressed or released a key, but nothing handled the event internally. + */ + fun onKey(navigator: VisualNavigator, event: KeyEvent): Boolean = false +} + +@OptIn(ExperimentalReadiumApi::class) +internal class CompositeInputListener : InputListener { + private val listeners = mutableListOf() + + fun add(listener: InputListener) { + listeners.add(listener) + } + + fun remove(listener: InputListener) { + listeners.remove(listener) + } + + override fun onTap(navigator: VisualNavigator, event: TapEvent): Boolean = + listeners.any { it.onTap(navigator, event) } + + override fun onDrag(navigator: VisualNavigator, event: DragEvent): Boolean = + listeners.any { it.onDrag(navigator, event) } + + override fun onKey(navigator: VisualNavigator, event: KeyEvent): Boolean = + listeners.any { it.onKey(navigator, event) } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/input/InputModifier.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/input/InputModifier.kt new file mode 100644 index 0000000000..c70008d0c3 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/input/InputModifier.kt @@ -0,0 +1,8 @@ +package org.readium.r2.navigator.input + +/** + * Represents a key modifier for an input event. + */ +enum class InputModifier { + Alt, Control, Meta, Shift +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyEvent.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyEvent.kt new file mode 100644 index 0000000000..aa6644b675 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyEvent.kt @@ -0,0 +1,366 @@ +package org.readium.r2.navigator.input + +import android.view.KeyEvent as AndroidKeyEvent + +/** + * Represents a keyboard event emitted by a navigator. + * + * @param type Nature of the event. + * @param key Key the user pressed or released. + * @param modifiers Additional input modifiers for keyboard shortcuts. + * @param characters Characters generated by the keypress, if any. + */ +data class KeyEvent( + val type: Type, + val key: Key, + val modifiers: Set, + val characters: String? +) { + + enum class Type { + Down, Up + } + + companion object { + operator fun invoke(type: Type, event: AndroidKeyEvent): KeyEvent? { + return KeyEvent( + type = type, + key = Key(event) ?: return null, + modifiers = inputModifiers(event), + characters = event.unicodeChar.toChar().toString() + ) + } + } +} + +/** + * Represents a physical key on a keyboard. + * + * See https://w3c.github.io/uievents-code/ + */ +@JvmInline +value class Key(val code: String) { + + companion object { + + // Alphanumeric section + + val Backquote = Key("Backquote") + val Backslash = Key("Backslash") + val BracketLeft = Key("BracketLeft") + val BracketRight = Key("BracketRight") + val Comma = Key("Comma") + val Digit0 = Key("Digit0") + val Digit1 = Key("Digit1") + val Digit2 = Key("Digit2") + val Digit3 = Key("Digit3") + val Digit4 = Key("Digit4") + val Digit5 = Key("Digit5") + val Digit6 = Key("Digit6") + val Digit7 = Key("Digit7") + val Digit8 = Key("Digit8") + val Digit9 = Key("Digit9") + val Equal = Key("Equal") + val IntlBackslash = Key("IntlBackslash") + val IntlRo = Key("IntlRo") + val IntlYen = Key("IntlYen") + val KeyA = Key("KeyA") + val KeyB = Key("KeyB") + val KeyC = Key("KeyC") + val KeyD = Key("KeyD") + val KeyE = Key("KeyE") + val KeyF = Key("KeyF") + val KeyG = Key("KeyG") + val KeyH = Key("KeyH") + val KeyI = Key("KeyI") + val KeyJ = Key("KeyJ") + val KeyK = Key("KeyK") + val KeyL = Key("KeyL") + val KeyM = Key("KeyM") + val KeyN = Key("KeyN") + val KeyO = Key("KeyO") + val KeyP = Key("KeyP") + val KeyQ = Key("KeyQ") + val KeyR = Key("KeyR") + val KeyS = Key("KeyS") + val KeyT = Key("KeyT") + val KeyU = Key("KeyU") + val KeyV = Key("KeyV") + val KeyW = Key("KeyW") + val KeyX = Key("KeyX") + val KeyY = Key("KeyY") + val KeyZ = Key("KeyZ") + val Minus = Key("Minus") + val Period = Key("Period") + val Quote = Key("Quote") + val Semicolon = Key("Semicolon") + val Slash = Key("Slash") + + // Function keys + + val AltLeft = Key("AltLeft") + val AltRight = Key("AltRight") + val Backspace = Key("Backspace") + val CapsLock = Key("CapsLock") + val ContextMenu = Key("ContextMenu") + val ControlLeft = Key("ControlLeft") + val ControlRight = Key("ControlRight") + val Enter = Key("Enter") + val MetaLeft = Key("MetaLeft") + val MetaRight = Key("MetaRight") + val ShiftLeft = Key("ShiftLeft") + val ShiftRight = Key("ShiftRight") + val Space = Key("Space") + val Tab = Key("Tab") + + // Function keys (Japanese and Korean keyboards) + + val Convert = Key("Convert") + val KanaMode = Key("KanaMode") + val Lang1 = Key("Lang1") + val Lang2 = Key("Lang2") + val Lang3 = Key("Lang3") + val Lang4 = Key("Lang4") + val Lang5 = Key("Lang5") + val NonConvert = Key("NonConvert") + + // Control pad section + + val Delete = Key("Delete") + val End = Key("End") + val Help = Key("Help") + val Home = Key("Home") + val Insert = Key("Insert") + val PageDown = Key("PageDown") + val PageUp = Key("PageUp") + + // Arrow pad section + + val ArrowDown = Key("ArrowDown") + val ArrowLeft = Key("ArrowLeft") + val ArrowRight = Key("ArrowRight") + val ArrowUp = Key("ArrowUp") + + // Numpad section + + val NumLock = Key("NumLock") + val Numpad0 = Key("Numpad0") + val Numpad1 = Key("Numpad1") + val Numpad2 = Key("Numpad2") + val Numpad3 = Key("Numpad3") + val Numpad4 = Key("Numpad4") + val Numpad5 = Key("Numpad5") + val Numpad6 = Key("Numpad6") + val Numpad7 = Key("Numpad7") + val Numpad8 = Key("Numpad8") + val Numpad9 = Key("Numpad9") + val NumpadAdd = Key("NumpadAdd") + val NumpadBackspace = Key("NumpadBackspace") + val NumpadClear = Key("NumpadClear") + val NumpadClearEntry = Key("NumpadClearEntry") + val NumpadComma = Key("NumpadComma") + val NumpadDecimal = Key("NumpadDecimal") + val NumpadDivide = Key("NumpadDivide") + val NumpadEnter = Key("NumpadEnter") + val NumpadEqual = Key("NumpadEqual") + val NumpadHash = Key("NumpadHash") + val NumpadMemoryAdd = Key("NumpadMemoryAdd") + val NumpadMemoryClear = Key("NumpadMemoryClear") + val NumpadMemoryRecall = Key("NumpadMemoryRecall") + val NumpadMemoryStore = Key("NumpadMemoryStore") + val NumpadMemorySubtract = Key("NumpadMemorySubtract") + val NumpadMultiply = Key("NumpadMultiply") + val NumpadParenLeft = Key("NumpadParenLeft") + val NumpadParenRight = Key("NumpadParenRight") + val NumpadStar = Key("NumpadStar") + val NumpadSubtract = Key("NumpadSubtract") + + // Function section + + val Escape = Key("Escape") + val F1 = Key("F1") + val F2 = Key("F2") + val F3 = Key("F3") + val F4 = Key("F4") + val F5 = Key("F5") + val F6 = Key("F6") + val F7 = Key("F7") + val F8 = Key("F8") + val F9 = Key("F9") + val F10 = Key("F10") + val F11 = Key("F11") + val F12 = Key("F12") + val Fn = Key("Fn") + val FnLock = Key("FnLock") + val PrintScreen = Key("PrintScreen") + val ScrollLock = Key("ScrollLock") + val Pause = Key("Pause") + + // Media keys + + val BrowserBack = Key("BrowserBack") + val BrowserFavorites = Key("BrowserFavorites") + val BrowserForward = Key("BrowserForward") + val BrowserHome = Key("BrowserHome") + val BrowserRefresh = Key("BrowserRefresh") + val BrowserSearch = Key("BrowserSearch") + val BrowserStop = Key("BrowserStop") + val Eject = Key("Eject") + val LaunchApp1 = Key("LaunchApp1") + val LaunchApp2 = Key("LaunchApp2") + val LaunchMail = Key("LaunchMail") + val MediaPlayPause = Key("MediaPlayPause") + val MediaSelect = Key("MediaSelect") + val MediaStop = Key("MediaStop") + val MediaTrackNext = Key("MediaTrackNext") + val MediaTrackPrevious = Key("MediaTrackPrevious") + val Power = Key("Power") + val Sleep = Key("Sleep") + val AudioVolumeDown = Key("AudioVolumeDown") + val AudioVolumeMute = Key("AudioVolumeMute") + val AudioVolumeUp = Key("AudioVolumeUp") + val WakeUp = Key("WakeUp") + + operator fun invoke(event: AndroidKeyEvent): Key? = + when (event.keyCode) { + AndroidKeyEvent.KEYCODE_DEL -> Backspace + AndroidKeyEvent.KEYCODE_ENTER -> Enter + AndroidKeyEvent.KEYCODE_FORWARD_DEL -> Delete + AndroidKeyEvent.KEYCODE_SPACE -> Space + AndroidKeyEvent.KEYCODE_TAB -> Tab + + AndroidKeyEvent.KEYCODE_0 -> Digit0 + AndroidKeyEvent.KEYCODE_1 -> Digit1 + AndroidKeyEvent.KEYCODE_2 -> Digit2 + AndroidKeyEvent.KEYCODE_3 -> Digit3 + AndroidKeyEvent.KEYCODE_4 -> Digit4 + AndroidKeyEvent.KEYCODE_5 -> Digit5 + AndroidKeyEvent.KEYCODE_6 -> Digit6 + AndroidKeyEvent.KEYCODE_7 -> Digit7 + AndroidKeyEvent.KEYCODE_8 -> Digit8 + AndroidKeyEvent.KEYCODE_9 -> Digit9 + + AndroidKeyEvent.KEYCODE_A -> KeyA + AndroidKeyEvent.KEYCODE_B -> KeyB + AndroidKeyEvent.KEYCODE_C -> KeyC + AndroidKeyEvent.KEYCODE_D -> KeyD + AndroidKeyEvent.KEYCODE_E -> KeyE + AndroidKeyEvent.KEYCODE_F -> KeyF + AndroidKeyEvent.KEYCODE_G -> KeyG + AndroidKeyEvent.KEYCODE_H -> KeyH + AndroidKeyEvent.KEYCODE_I -> KeyI + AndroidKeyEvent.KEYCODE_J -> KeyJ + AndroidKeyEvent.KEYCODE_K -> KeyK + AndroidKeyEvent.KEYCODE_L -> KeyL + AndroidKeyEvent.KEYCODE_M -> KeyM + AndroidKeyEvent.KEYCODE_N -> KeyN + AndroidKeyEvent.KEYCODE_O -> KeyO + AndroidKeyEvent.KEYCODE_P -> KeyP + AndroidKeyEvent.KEYCODE_Q -> KeyQ + AndroidKeyEvent.KEYCODE_R -> KeyR + AndroidKeyEvent.KEYCODE_S -> KeyS + AndroidKeyEvent.KEYCODE_T -> KeyT + AndroidKeyEvent.KEYCODE_U -> KeyU + AndroidKeyEvent.KEYCODE_V -> KeyV + AndroidKeyEvent.KEYCODE_W -> KeyW + AndroidKeyEvent.KEYCODE_X -> KeyX + AndroidKeyEvent.KEYCODE_Y -> KeyY + AndroidKeyEvent.KEYCODE_Z -> KeyZ + + AndroidKeyEvent.KEYCODE_APOSTROPHE -> Quote + AndroidKeyEvent.KEYCODE_BACKSLASH -> Backslash + AndroidKeyEvent.KEYCODE_GRAVE -> Backquote + AndroidKeyEvent.KEYCODE_COMMA -> Comma + AndroidKeyEvent.KEYCODE_EQUALS -> Equal + AndroidKeyEvent.KEYCODE_LEFT_BRACKET -> BracketLeft + AndroidKeyEvent.KEYCODE_MINUS -> Minus + AndroidKeyEvent.KEYCODE_PERIOD -> Period + AndroidKeyEvent.KEYCODE_RIGHT_BRACKET -> BracketRight + AndroidKeyEvent.KEYCODE_SEMICOLON -> Semicolon + AndroidKeyEvent.KEYCODE_SLASH -> Slash + + AndroidKeyEvent.KEYCODE_NUM_LOCK -> NumLock + AndroidKeyEvent.KEYCODE_NUMPAD_0 -> Numpad0 + AndroidKeyEvent.KEYCODE_NUMPAD_1 -> Numpad1 + AndroidKeyEvent.KEYCODE_NUMPAD_2 -> Numpad2 + AndroidKeyEvent.KEYCODE_NUMPAD_3 -> Numpad3 + AndroidKeyEvent.KEYCODE_NUMPAD_4 -> Numpad4 + AndroidKeyEvent.KEYCODE_NUMPAD_5 -> Numpad5 + AndroidKeyEvent.KEYCODE_NUMPAD_6 -> Numpad6 + AndroidKeyEvent.KEYCODE_NUMPAD_7 -> Numpad7 + AndroidKeyEvent.KEYCODE_NUMPAD_8 -> Numpad8 + AndroidKeyEvent.KEYCODE_NUMPAD_9 -> Numpad9 + AndroidKeyEvent.KEYCODE_NUMPAD_ADD -> NumpadAdd + AndroidKeyEvent.KEYCODE_NUMPAD_COMMA -> NumpadComma + AndroidKeyEvent.KEYCODE_NUMPAD_DIVIDE -> NumpadDivide + AndroidKeyEvent.KEYCODE_NUMPAD_DOT -> NumpadDecimal + AndroidKeyEvent.KEYCODE_NUMPAD_ENTER -> NumpadEnter + AndroidKeyEvent.KEYCODE_NUMPAD_EQUALS -> NumpadEqual + AndroidKeyEvent.KEYCODE_NUMPAD_LEFT_PAREN -> NumpadParenLeft + AndroidKeyEvent.KEYCODE_NUMPAD_MULTIPLY -> NumpadMultiply + AndroidKeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN -> NumpadParenRight + AndroidKeyEvent.KEYCODE_NUMPAD_SUBTRACT -> NumpadSubtract + + AndroidKeyEvent.KEYCODE_CAPS_LOCK -> CapsLock + AndroidKeyEvent.KEYCODE_ESCAPE -> Escape + AndroidKeyEvent.KEYCODE_FUNCTION -> Fn + AndroidKeyEvent.KEYCODE_INSERT -> Insert + + AndroidKeyEvent.KEYCODE_DPAD_DOWN -> ArrowDown + AndroidKeyEvent.KEYCODE_DPAD_LEFT -> ArrowLeft + AndroidKeyEvent.KEYCODE_DPAD_RIGHT -> ArrowRight + AndroidKeyEvent.KEYCODE_DPAD_UP -> ArrowUp + AndroidKeyEvent.KEYCODE_HOME -> Home + AndroidKeyEvent.KEYCODE_PAGE_DOWN -> PageDown + AndroidKeyEvent.KEYCODE_PAGE_UP -> PageUp + + AndroidKeyEvent.KEYCODE_F1 -> F1 + AndroidKeyEvent.KEYCODE_F2 -> F2 + AndroidKeyEvent.KEYCODE_F3 -> F3 + AndroidKeyEvent.KEYCODE_F4 -> F4 + AndroidKeyEvent.KEYCODE_F5 -> F5 + AndroidKeyEvent.KEYCODE_F6 -> F6 + AndroidKeyEvent.KEYCODE_F7 -> F7 + AndroidKeyEvent.KEYCODE_F8 -> F8 + AndroidKeyEvent.KEYCODE_F9 -> F9 + AndroidKeyEvent.KEYCODE_F10 -> F10 + AndroidKeyEvent.KEYCODE_F11 -> F11 + AndroidKeyEvent.KEYCODE_F12 -> F12 + + AndroidKeyEvent.KEYCODE_MEDIA_NEXT -> MediaTrackNext + AndroidKeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> MediaPlayPause + AndroidKeyEvent.KEYCODE_MEDIA_PREVIOUS -> MediaTrackPrevious + AndroidKeyEvent.KEYCODE_MEDIA_STOP -> MediaStop + AndroidKeyEvent.KEYCODE_VOLUME_DOWN -> AudioVolumeDown + AndroidKeyEvent.KEYCODE_VOLUME_MUTE -> AudioVolumeMute + AndroidKeyEvent.KEYCODE_VOLUME_UP -> AudioVolumeUp + + AndroidKeyEvent.KEYCODE_ALT_LEFT -> AltLeft + AndroidKeyEvent.KEYCODE_ALT_RIGHT -> AltRight + AndroidKeyEvent.KEYCODE_CTRL_LEFT -> ControlLeft + AndroidKeyEvent.KEYCODE_CTRL_RIGHT -> ControlRight + AndroidKeyEvent.KEYCODE_META_LEFT -> MetaLeft + AndroidKeyEvent.KEYCODE_META_RIGHT -> MetaRight + AndroidKeyEvent.KEYCODE_SHIFT_LEFT -> ShiftLeft + AndroidKeyEvent.KEYCODE_SHIFT_RIGHT -> ShiftRight + + else -> null + } + } +} + +private fun inputModifiers(event: android.view.KeyEvent): Set = + buildSet { + if (event.isAltPressed) { + add(InputModifier.Alt) + } + if (event.isCtrlPressed) { + add(InputModifier.Control) + } + if (event.isMetaPressed) { + add(InputModifier.Meta) + } + if (event.isShiftPressed) { + add(InputModifier.Shift) + } + } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyInterceptorView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyInterceptorView.kt new file mode 100644 index 0000000000..de413a8dc3 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/input/KeyInterceptorView.kt @@ -0,0 +1,43 @@ +package org.readium.r2.navigator.input + +import android.annotation.SuppressLint +import android.os.Build +import android.view.View +import android.widget.FrameLayout +import org.readium.r2.navigator.VisualNavigator +import org.readium.r2.shared.ExperimentalReadiumApi + +/** + * Utility view to intercept keyboard events and forward them to a [VisualNavigator.Listener]. + */ +@SuppressLint("ViewConstructor") +@OptIn(ExperimentalReadiumApi::class) +internal class KeyInterceptorView( + view: View, + private val navigator: VisualNavigator, + private val listener: InputListener? +) : FrameLayout(view.context) { + + init { + addView(view) + + isFocusable = true + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + defaultFocusHighlightEnabled = false + } + } + + override fun onKeyUp(keyCode: Int, event: android.view.KeyEvent?): Boolean { + event + ?.let { KeyEvent(KeyEvent.Type.Up, it) } + ?.let { listener?.onKey(navigator, it) } + return super.onKeyUp(keyCode, event) + } + + override fun onKeyDown(keyCode: Int, event: android.view.KeyEvent?): Boolean { + event + ?.let { KeyEvent(KeyEvent.Type.Down, it) } + ?.let { listener?.onKey(navigator, it) } + return super.onKeyDown(keyCode, event) + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/input/TapEvent.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/input/TapEvent.kt new file mode 100644 index 0000000000..b3d4c94792 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/input/TapEvent.kt @@ -0,0 +1,12 @@ +package org.readium.r2.navigator.input + +import android.graphics.PointF + +/** + * Represents a tap event emitted by a navigator at the given [point]. + * + * All the points are relative to the navigator view. + */ +data class TapEvent( + val point: PointF +) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt index 26747f1500..46f2b6dfa8 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt @@ -339,8 +339,8 @@ class AndroidTtsEngine private constructor( engine: TextToSpeech, request: Request ): Boolean { - return engine.setupVoice(settings.value, request.id, request.language, voices) - && (engine.speak(request.text, QUEUE_ADD, null, request.id.value) == SUCCESS) + return engine.setupVoice(settings.value, request.id, request.language, voices) && + (engine.speak(request.text, QUEUE_ADD, null, request.id.value) == SUCCESS) } private fun setupListener(engine: TextToSpeech) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt index 7ef1bdd98e..ad1b78cf81 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt @@ -20,6 +20,10 @@ import kotlinx.coroutines.launch import org.readium.r2.navigator.R import org.readium.r2.navigator.VisualNavigator import org.readium.r2.navigator.extensions.page +import org.readium.r2.navigator.input.CompositeInputListener +import org.readium.r2.navigator.input.InputListener +import org.readium.r2.navigator.input.KeyInterceptorView +import org.readium.r2.navigator.input.TapEvent import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.navigator.preferences.PreferencesEditor import org.readium.r2.navigator.preferences.ReadingProgression @@ -98,15 +102,6 @@ class PdfNavigatorFragment get() = viewModel.settings as StateFlow - - override fun submitPreferences(preferences: P) { - viewModel.submitPreferences(preferences) - } - private val viewModel: PdfNavigatorViewModel by viewModels { PdfNavigatorViewModel.createFactory( requireActivity().application, @@ -132,7 +127,7 @@ class PdfNavigatorFragment - get() = settings.mapStateIn(lifecycleScope) { settings -> - pdfEngineProvider.computePresentation(settings) - } + // Configurable - override val readingProgression: PublicationReadingProgression - get() = when (presentation.value.readingProgression) { - ReadingProgression.LTR -> PublicationReadingProgression.LTR - ReadingProgression.RTL -> PublicationReadingProgression.RTL - } + @Suppress("Unchecked_cast") + override val settings: StateFlow get() = viewModel.settings as StateFlow + + override fun submitPreferences(preferences: P) { + viewModel.submitPreferences(preferences) + } + + // Navigator override val currentLocator: StateFlow get() = viewModel.currentLocator @@ -244,4 +237,31 @@ class PdfNavigatorFragment + get() = settings.mapStateIn(lifecycleScope) { settings -> + pdfEngineProvider.computePresentation(settings) + } + + override val readingProgression: PublicationReadingProgression + get() = when (presentation.value.readingProgression) { + ReadingProgression.LTR -> PublicationReadingProgression.LTR + ReadingProgression.RTL -> PublicationReadingProgression.RTL + } + + private val inputListener = CompositeInputListener() + + override fun addInputListener(listener: InputListener) { + inputListener.add(listener) + } + + override fun removeInputListener(listener: InputListener) { + inputListener.remove(listener) + } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/util/DirectionalNavigationAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/util/DirectionalNavigationAdapter.kt new file mode 100644 index 0000000000..e1d83f1fb2 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/util/DirectionalNavigationAdapter.kt @@ -0,0 +1,105 @@ +package org.readium.r2.navigator.util + +import org.readium.r2.navigator.VisualNavigator +import org.readium.r2.navigator.goLeft +import org.readium.r2.navigator.goRight +import org.readium.r2.navigator.input.InputListener +import org.readium.r2.navigator.input.Key +import org.readium.r2.navigator.input.KeyEvent +import org.readium.r2.navigator.input.TapEvent +import org.readium.r2.shared.ExperimentalReadiumApi + +/** + * Helper handling directional UI events (e.g. edge taps or arrow keys) to turn the pages of a + * VisualNavigator. + * + * This takes into account the reading progression of the navigator to turn pages in the right + * direction. + * + * Add it to a navigator with `addInputListener(DirectionalNavigationAdapter())`. + * + * @param tapEdges: Indicates which viewport edges handle taps. + * @param handleTapsWhileScrolling: Indicates whether the page turns should be handled when the + * publication is scrollable. + * @param minimumHorizontalEdgeSize: The minimum horizontal edge dimension triggering page turns, in + * pixels. + * @param horizontalEdgeThresholdPercent: The percentage of the viewport dimension used to compute + * the horizontal edge size. When null, minimumHorizontalEdgeSize will be used instead. + * @param minimumVerticalEdgeSize: The minimum vertical edge dimension triggering page turns, in + * pixels. + * @param verticalEdgeThresholdPercent: The percentage of the viewport dimension used to compute the + * vertical edge size. When null, minimumVerticalEdgeSize will be used instead. + * @param animatedTransition: Indicates whether the page turns should be animated. + */ +@ExperimentalReadiumApi +class DirectionalNavigationAdapter( + private val tapEdges: Set = setOf(TapEdge.Horizontal), + private val handleTapsWhileScrolling: Boolean = false, + private val minimumHorizontalEdgeSize: Double = 80.0, + private val horizontalEdgeThresholdPercent: Double? = 0.3, + private val minimumVerticalEdgeSize: Double = 80.0, + private val verticalEdgeThresholdPercent: Double? = 0.3, + private val animatedTransition: Boolean = false +) : InputListener { + + /** + * Indicates which viewport edges trigger page turns on tap. + */ + enum class TapEdge { + Horizontal, Vertical; + } + + override fun onTap(navigator: VisualNavigator, event: TapEvent): Boolean { + if (navigator.presentation.value.scroll && !handleTapsWhileScrolling) { + return false + } + + if (tapEdges.contains(TapEdge.Horizontal)) { + val width = navigator.publicationView.width.toDouble() + + val horizontalEdgeSize = horizontalEdgeThresholdPercent?.let { + maxOf(minimumHorizontalEdgeSize, it * width) + } ?: minimumHorizontalEdgeSize + val leftRange = 0.0..horizontalEdgeSize + val rightRange = (width - horizontalEdgeSize)..width + + if (event.point.x in rightRange) { + return navigator.goRight(animated = animatedTransition) + } else if (event.point.x in leftRange) { + return navigator.goLeft(animated = animatedTransition) + } + } + + if (tapEdges.contains(TapEdge.Vertical)) { + val height = navigator.publicationView.height.toDouble() + + val verticalEdgeSize = verticalEdgeThresholdPercent?.let { + maxOf(minimumVerticalEdgeSize, it * height) + } ?: minimumVerticalEdgeSize + val topRange = 0.0..verticalEdgeSize + val bottomRange = (height - verticalEdgeSize)..height + + if (event.point.y in bottomRange) { + return navigator.goForward(animated = animatedTransition) + } else if (event.point.y in topRange) { + return navigator.goBackward(animated = animatedTransition) + } + } + + return false + } + + override fun onKey(navigator: VisualNavigator, event: KeyEvent): Boolean { + if (event.type != KeyEvent.Type.Down || !event.modifiers.isEmpty()) { + return false + } + + return when (event.key) { + Key.ArrowUp -> navigator.goBackward(animated = animatedTransition) + Key.ArrowDown, Key.Space -> navigator.goForward(animated = animatedTransition) + Key.ArrowLeft -> navigator.goLeft(animated = animatedTransition) + Key.ArrowRight -> navigator.goRight(animated = animatedTransition) + else -> false + } + } +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt index 12ceec7569..5685b82eb0 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt @@ -1,93 +1,12 @@ package org.readium.r2.navigator.util -import android.graphics.PointF -import android.view.View import org.readium.r2.navigator.VisualNavigator -import org.readium.r2.navigator.preferences.Axis -import org.readium.r2.navigator.preferences.ReadingProgression -import org.readium.r2.shared.ExperimentalReadiumApi -/** - * Convenience utility to handle page turns when tapping the edge of the screen. - * - * Call [EdgeTapNavigation.onTap] from the [VisualNavigator.Listener.onTap] callback to turn pages - * automatically. - * - * @param navigator Navigator used to turn pages. - * @param minimumEdgeSize The minimum edge dimension triggering page turns, in pixels. - * @param edgeThresholdPercent The percentage of the viewport dimension used to compute the edge - * dimension. When null, minimumEdgeSize will be used instead. - * @param animatedTransition Indicates whether the page turns should be animated. - */ -@OptIn(ExperimentalReadiumApi::class) +@Deprecated("Replaced by [DirectionalNavigationAdapter].", replaceWith = ReplaceWith("DirectionalNavigationAdapter"), level = DeprecationLevel.ERROR) class EdgeTapNavigation( private val navigator: VisualNavigator, private val minimumEdgeSize: Double = 200.0, private val edgeThresholdPercent: Double? = 0.3, private val animatedTransition: Boolean = false, private val handleTapsWhileScrolling: Boolean = false -) { - private enum class Transition { - FORWARD, BACKWARD, NONE; - - fun reverse() = when (this) { - FORWARD -> BACKWARD - BACKWARD -> FORWARD - NONE -> NONE - } - } - - /** - * Handles a tap in the navigator viewport and returns whether it was successful. - * - * To be called from [VisualNavigator.Listener.onTap]. - * - * @param view Navigator view from which the point is relative. - */ - fun onTap(point: PointF, view: View): Boolean { - val horizontalEdgeSize by lazy { - if (edgeThresholdPercent != null) - (edgeThresholdPercent * view.width).coerceAtLeast(minimumEdgeSize) - else minimumEdgeSize - } - val leftRange by lazy { 0.0..horizontalEdgeSize } - val rightRange by lazy { (view.width - horizontalEdgeSize)..view.width.toDouble() } - - val verticalEdgeSize by lazy { - if (edgeThresholdPercent != null) - (edgeThresholdPercent * view.height).coerceAtLeast(minimumEdgeSize) - else minimumEdgeSize - } - val topRange by lazy { 0.0..verticalEdgeSize } - val bottomRange by lazy { (view.height - verticalEdgeSize)..view.height.toDouble() } - - val presentation = navigator.presentation.value - - var transition: Transition = - when { - presentation.scroll && !handleTapsWhileScrolling -> - Transition.NONE - presentation.axis == Axis.HORIZONTAL -> - when { - rightRange.contains(point.x) -> Transition.FORWARD - leftRange.contains(point.x) -> Transition.BACKWARD - else -> Transition.NONE - } - else -> when { - bottomRange.contains(point.y) -> Transition.FORWARD - topRange.contains(point.y) -> Transition.BACKWARD - else -> Transition.NONE - } - } - - if (presentation.readingProgression == ReadingProgression.RTL) { - transition = transition.reverse() - } - - return when (transition) { - Transition.FORWARD -> navigator.goForward(animated = animatedTransition) - Transition.BACKWARD -> navigator.goBackward(animated = animatedTransition) - Transition.NONE -> false - } - } -} +) diff --git a/readium/navigator/src/main/res/layout/fragment_fxllayout_double.xml b/readium/navigator/src/main/res/layout/fragment_fxllayout_double.xml index b26c22522d..d063422717 100644 --- a/readium/navigator/src/main/res/layout/fragment_fxllayout_double.xml +++ b/readium/navigator/src/main/res/layout/fragment_fxllayout_double.xml @@ -10,6 +10,7 @@ @@ -17,11 +18,13 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" + android:focusable="false" android:scrollbars="none"> + android:layerType="hardware" + /> diff --git a/readium/navigator/src/main/res/layout/fragment_fxllayout_single.xml b/readium/navigator/src/main/res/layout/fragment_fxllayout_single.xml index 1ffae6ce46..e3af263831 100644 --- a/readium/navigator/src/main/res/layout/fragment_fxllayout_single.xml +++ b/readium/navigator/src/main/res/layout/fragment_fxllayout_single.xml @@ -10,6 +10,7 @@ @@ -17,11 +18,13 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" + android:focusable="false" android:scrollbars="none"> - showHighlightPopup(selectionRect, style) + private fun showHighlightPopupWithStyle(style: Highlight.Style) = + viewLifecycleOwner.lifecycleScope.launchWhenResumed { + // Get the rect of the current selection to know where to position the highlight + // popup. + (navigator as? SelectableNavigator)?.currentSelection()?.rect?.let { selectionRect -> + showHighlightPopup(selectionRect, style) + } } - } private fun showHighlightPopup(rect: RectF, style: Highlight.Style, highlightId: Long? = null) = viewLifecycleOwner.lifecycleScope.launchWhenResumed { @@ -438,55 +455,64 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List mode?.finish() } - private fun showAnnotationPopup(highlightId: Long? = null) = viewLifecycleOwner.lifecycleScope.launchWhenResumed { - val activity = activity ?: return@launchWhenResumed - val view = layoutInflater.inflate(R.layout.popup_note, null, false) - val note = view.findViewById(R.id.note) - val alert = AlertDialog.Builder(activity) - .setView(view) - .create() - - fun dismiss() { - alert.dismiss() - mode?.finish() - (activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) - .hideSoftInputFromWindow(note.applicationWindowToken, InputMethodManager.HIDE_NOT_ALWAYS) - } + private fun showAnnotationPopup(highlightId: Long? = null) = + viewLifecycleOwner.lifecycleScope.launchWhenResumed { + val activity = activity ?: return@launchWhenResumed + val view = layoutInflater.inflate(R.layout.popup_note, null, false) + val note = view.findViewById(R.id.note) + val alert = AlertDialog.Builder(activity) + .setView(view) + .create() + + fun dismiss() { + alert.dismiss() + mode?.finish() + (activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) + .hideSoftInputFromWindow( + note.applicationWindowToken, + InputMethodManager.HIDE_NOT_ALWAYS + ) + } - with(view) { - val highlight = highlightId?.let { model.highlightById(it) } - if (highlight != null) { - note.setText(highlight.annotation) - findViewById(R.id.sidemark).setBackgroundColor(highlight.tint) - findViewById(R.id.select_text).text = highlight.locator.text.highlight - - findViewById(R.id.positive).setOnClickListener { - val text = note.text.toString() - model.updateHighlightAnnotation(highlight.id, annotation = text) - dismiss() + with(view) { + val highlight = highlightId?.let { model.highlightById(it) } + if (highlight != null) { + note.setText(highlight.annotation) + findViewById(R.id.sidemark).setBackgroundColor(highlight.tint) + findViewById(R.id.select_text).text = highlight.locator.text.highlight + + findViewById(R.id.positive).setOnClickListener { + val text = note.text.toString() + model.updateHighlightAnnotation(highlight.id, annotation = text) + dismiss() + } + } else { + val tint = highlightTints.values.random() + findViewById(R.id.sidemark).setBackgroundColor(tint) + val navigator = navigator as? SelectableNavigator ?: return@launchWhenResumed + val selection = navigator.currentSelection() ?: return@launchWhenResumed + navigator.clearSelection() + findViewById(R.id.select_text).text = selection.locator.text.highlight + + findViewById(R.id.positive).setOnClickListener { + model.addHighlight( + locator = selection.locator, + style = Highlight.Style.HIGHLIGHT, + tint = tint, + annotation = note.text.toString() + ) + dismiss() + } } - } else { - val tint = highlightTints.values.random() - findViewById(R.id.sidemark).setBackgroundColor(tint) - val navigator = navigator as? SelectableNavigator ?: return@launchWhenResumed - val selection = navigator.currentSelection() ?: return@launchWhenResumed - navigator.clearSelection() - findViewById(R.id.select_text).text = selection.locator.text.highlight - - findViewById(R.id.positive).setOnClickListener { - model.addHighlight(locator = selection.locator, style = Highlight.Style.HIGHLIGHT, tint = tint, annotation = note.text.toString()) + + findViewById(R.id.negative).setOnClickListener { dismiss() } } - findViewById(R.id.negative).setOnClickListener { - dismiss() - } + alert.show() } - alert.show() - } - fun updateSystemUiVisibility() { if (navigatorFragment.isHidden) requireActivity().showSystemUi() @@ -503,23 +529,6 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List container.clearPadding() } } - - // VisualNavigator.Listener - - override fun onTap(point: PointF): Boolean { - val navigated = edgeTapNavigation.onTap(point, requireView()) - - if (!navigated) { - requireActivity().toggleSystemUi() - } - return true - } - - private val edgeTapNavigation by lazy { - EdgeTapNavigation( - navigator = navigator as VisualNavigator - ) - } } /** From 57bc32b7528b932b7165bd913f29741916950231 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Sat, 8 Jul 2023 16:58:24 +0200 Subject: [PATCH 12/65] Various changes on media3-based navigators (#363) --- ...avigator.kt => TimeBasedMediaNavigator.kt} | 6 ++--- .../media3/audio/AudioEngineProvider.kt | 2 +- ...udiobookNavigator.kt => AudioNavigator.kt} | 20 ++++++++--------- .../media3/audio/AudioNavigatorFactory.kt | 4 ++-- .../media3/exoplayer/ExoPlayerAliases.kt | 4 ++-- ...ioNavigator.kt => GuidedMediaNavigator.kt} | 22 +++++++++---------- .../r2/navigator/media3/tts/TtsNavigator.kt | 10 ++++++++- .../media3/tts/android/AndroidTtsEngine.kt | 22 +++++++++++-------- .../r2/testapp/reader/AudioReaderFragment.kt | 8 +++---- 9 files changed, 55 insertions(+), 43 deletions(-) rename readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/{AudioNavigator.kt => TimeBasedMediaNavigator.kt} (88%) rename readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/{AudiobookNavigator.kt => AudioNavigator.kt} (91%) rename readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/{GuidedAudioNavigator.kt => GuidedMediaNavigator.kt} (80%) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/AudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TimeBasedMediaNavigator.kt similarity index 88% rename from readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/AudioNavigator.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TimeBasedMediaNavigator.kt index 41227cacb4..8c5d89e5e7 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/AudioNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/TimeBasedMediaNavigator.kt @@ -11,11 +11,11 @@ import kotlinx.coroutines.flow.StateFlow import org.readium.r2.shared.ExperimentalReadiumApi /** - * A [MediaNavigator] which can play audio files. + * A [MediaNavigator] whose locations provide time offsets. */ @ExperimentalReadiumApi -interface AudioNavigator : MediaNavigator { +interface TimeBasedMediaNavigator : MediaNavigator { /** * Location of the navigator. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt index 39a352c128..21ea7681a6 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioEngineProvider.kt @@ -14,7 +14,7 @@ import org.readium.r2.shared.publication.Metadata import org.readium.r2.shared.publication.Publication /** - * To be implemented by adapters for third-party audio engines which can be used with [AudiobookNavigator]. + * To be implemented by adapters for third-party audio engines which can be used with [AudioNavigator]. */ @ExperimentalReadiumApi interface AudioEngineProvider, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt similarity index 91% rename from readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt index 94f541cd0e..172c30c9ed 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudiobookNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt @@ -16,9 +16,9 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.StateFlow import org.readium.r2.navigator.extensions.sum import org.readium.r2.navigator.extensions.time -import org.readium.r2.navigator.media3.api.AudioNavigator import org.readium.r2.navigator.media3.api.Media3Adapter import org.readium.r2.navigator.media3.api.MediaNavigator +import org.readium.r2.navigator.media3.api.TimeBasedMediaNavigator import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.extensions.mapStateIn @@ -30,13 +30,13 @@ import timber.log.Timber @ExperimentalReadiumApi @OptIn(ExperimentalTime::class) -class AudiobookNavigator> private constructor( +class AudioNavigator> private constructor( override val publication: Publication, private val audioEngine: AudioEngine, override val readingOrder: ReadingOrder, ) : - MediaNavigator, - AudioNavigator, + MediaNavigator, + TimeBasedMediaNavigator, Media3Adapter, Configurable by audioEngine { @@ -48,7 +48,7 @@ class AudiobookNavigator = publication.readingOrder, initialPreferences: P? = null, initialLocator: Locator? = null, - ): AudiobookNavigator? { + ): AudioNavigator? { if (readingOrder.isEmpty()) { return null } @@ -71,7 +71,7 @@ class AudiobookNavigator - ) : AudioNavigator.ReadingOrder { + ) : TimeBasedMediaNavigator.ReadingOrder { data class Item( val href: Href, override val duration: Duration? - ) : AudioNavigator.ReadingOrder.Item + ) : TimeBasedMediaNavigator.ReadingOrder.Item } data class Playback( @@ -109,7 +109,7 @@ class AudiobookNavigator? { - return AudiobookNavigator( + ): AudioNavigator? { + return AudioNavigator( publication = publication, audioEngineProvider = audioEngineProvider, initialPreferences = initialPreferences, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt index 792af970b5..9230ce5a2f 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerAliases.kt @@ -6,12 +6,12 @@ package org.readium.r2.navigator.media3.exoplayer +import org.readium.r2.navigator.media3.audio.AudioNavigator import org.readium.r2.navigator.media3.audio.AudioNavigatorFactory -import org.readium.r2.navigator.media3.audio.AudiobookNavigator import org.readium.r2.shared.ExperimentalReadiumApi @OptIn(ExperimentalReadiumApi::class) typealias ExoPlayerNavigatorFactory = AudioNavigatorFactory @OptIn(ExperimentalReadiumApi::class) -typealias ExoPlayerNavigator = AudiobookNavigator +typealias ExoPlayerNavigator = AudioNavigator diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedMediaNavigator.kt similarity index 80% rename from readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedMediaNavigator.kt index ea66c750f9..1c01c0c68b 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedAudioNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedMediaNavigator.kt @@ -9,11 +9,11 @@ package org.readium.r2.navigator.media3.syncmedia import androidx.media3.common.Player import kotlin.time.Duration import kotlinx.coroutines.flow.StateFlow -import org.readium.r2.navigator.media3.api.AudioNavigator import org.readium.r2.navigator.media3.api.Media3Adapter import org.readium.r2.navigator.media3.api.MediaNavigator import org.readium.r2.navigator.media3.api.TextAwareMediaNavigator -import org.readium.r2.navigator.media3.audio.AudiobookNavigator +import org.readium.r2.navigator.media3.api.TimeBasedMediaNavigator +import org.readium.r2.navigator.media3.audio.AudioNavigator import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.Link @@ -22,12 +22,12 @@ import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.util.Href @ExperimentalReadiumApi -class GuidedAudioNavigator>( - private val audioNavigator: AudiobookNavigator, +class GuidedMediaNavigator>( + private val audioNavigator: AudioNavigator, ) : - MediaNavigator, - AudioNavigator, - TextAwareMediaNavigator, + MediaNavigator, + TimeBasedMediaNavigator, + TextAwareMediaNavigator, Media3Adapter, Configurable { @@ -41,7 +41,7 @@ class GuidedAudioNavigator - ) : AudioNavigator.ReadingOrder, TextAwareMediaNavigator.ReadingOrder { + ) : TimeBasedMediaNavigator.ReadingOrder, TextAwareMediaNavigator.ReadingOrder { data class Item( val href: Href, override val duration: Duration? - ) : AudioNavigator.ReadingOrder.Item, TextAwareMediaNavigator.ReadingOrder.Item + ) : TimeBasedMediaNavigator.ReadingOrder.Item, TextAwareMediaNavigator.ReadingOrder.Item } override val publication: Publication = diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt index b54fc5c4a4..a0b9953998 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt @@ -44,7 +44,7 @@ class TtsNavigator, MediaNavigator, TextAwareMediaNavigator, Media3Adapter, - Configurable by player { + Configurable { companion object { @@ -247,6 +247,14 @@ class TtsNavigator, return true } + override val settings: StateFlow = + player.settings + + override fun submitPreferences(preferences: P) { + player.submitPreferences(preferences) + player.restartUtterance() + } + private fun navigatorPlayback(playback: TtsPlayer.Playback, utterance: TtsPlayer.Utterance) = Playback( state = playback.state.toState(), diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt index 46f2b6dfa8..f909547422 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt @@ -400,19 +400,23 @@ class AndroidTtsEngine private constructor( utteranceLanguage: Language?, voices: Set ): Boolean { - var language = utteranceLanguage + val language = utteranceLanguage .takeUnless { settings.overrideContentLanguage } + // We take utterance language if data are missing but not if the language is not supported + ?.takeIf { isLanguageAvailable(it.locale) != LANG_NOT_SUPPORTED } ?: settings.language + .takeIf { isLanguageAvailable(it.locale) != LANG_NOT_SUPPORTED } + ?: defaultVoice?.locale?.let { Language(it) } - utteranceListener?.onError(id, Error.LanguageMissingData(language)) - return false + if (language == null) { + // We don't know what to do. + utteranceListener?.onError(id, Error.Unknown) + return false + } - when (isLanguageAvailable(language.locale)) { - LANG_MISSING_DATA -> { - utteranceListener?.onError(id, Error.LanguageMissingData(language)) - return false - } - LANG_NOT_SUPPORTED -> language = Language(defaultVoice.locale) + if (isLanguageAvailable(language.locale) < LANG_AVAILABLE) { + utteranceListener?.onError(id, Error.LanguageMissingData(language)) + return false } val preferredVoiceWithRegion = diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt index df5b54970c..a7322e9288 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt @@ -23,8 +23,8 @@ import kotlin.time.DurationUnit import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import org.readium.r2.navigator.media3.api.AudioNavigator import org.readium.r2.navigator.media3.api.MediaNavigator +import org.readium.r2.navigator.media3.api.TimeBasedMediaNavigator import org.readium.r2.navigator.media3.exoplayer.ExoPlayerPreferences import org.readium.r2.navigator.media3.exoplayer.ExoPlayerSettings import org.readium.r2.navigator.preferences.Configurable @@ -40,7 +40,7 @@ import timber.log.Timber @OptIn(ExperimentalReadiumApi::class) class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListener { - override lateinit var navigator: AudioNavigator<*, *, *> + override lateinit var navigator: TimeBasedMediaNavigator<*, *, *> private var binding: FragmentAudiobookBinding by viewLifecycle() private var seekingItem: Int? = null @@ -88,7 +88,7 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene .launchIn(viewLifecycleOwner.lifecycleScope) } - private fun onPlaybackChanged(playback: AudioNavigator.Playback) { + private fun onPlaybackChanged(playback: TimeBasedMediaNavigator.Playback) { Timber.v("onPlaybackChanged $playback") if (playback.state is MediaNavigator.State.Error) { onPlayerError() @@ -111,7 +111,7 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene } } - private fun updateTimeline(playback: AudioNavigator.Playback) { + private fun updateTimeline(playback: TimeBasedMediaNavigator.Playback) { val currentItem = navigator.readingOrder.items[playback.index] binding.timelineBar.max = currentItem.duration?.inWholeSeconds?.toInt() ?: 0 binding.timelineDuration.text = currentItem.duration?.formatElapsedTime() From 2d80205b389ad0884b7cd1a3bd164dc0f968391e Mon Sep 17 00:00:00 2001 From: Steven Zeck <8315038+stevenzeck@users.noreply.github.com> Date: Fri, 14 Jul 2023 04:37:25 -0500 Subject: [PATCH 13/65] Remove Fuel and Kovenant dependencies (#364) --- docs/migration-guide.md | 25 ++++++ readium/opds/build.gradle.kts | 1 - .../java/org/readium/r2/opds/Extensions.kt | 18 ---- .../java/org/readium/r2/opds/OPDS1Parser.kt | 84 ------------------- .../java/org/readium/r2/opds/OPDS2Parser.kt | 25 ------ readium/shared/build.gradle.kts | 8 -- .../readium/r2/shared/FuelPromiseExtension.kt | 32 ------- .../readium/r2/shared/format/Deprecated.kt | 9 -- .../r2/shared/util/mediatype/Extensions.kt | 26 ------ 9 files changed, 25 insertions(+), 203 deletions(-) delete mode 100644 readium/opds/src/main/java/org/readium/r2/opds/Extensions.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/FuelPromiseExtension.kt diff --git a/docs/migration-guide.md b/docs/migration-guide.md index 504a339703..09f50ceba9 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -67,6 +67,31 @@ navigator.addInputListener(DirectionalNavigationAdapter( `DirectionalNavigationAdapter` offers a lot of customization options. Take a look at its API. +### Removal of Fuel and Kovenant + +Both the Fuel and Kovenant libraries have been completely removed from the toolkit. With that, several deprecated functions have also been removed. + +#### opds/OPDS1Parser + +* Both `parseURL(url: URL)` and `parseURL(headers: MutableMap, url: URL)` have been replaced with `parseUrlString(url: String, client: HttpClient = DefaultHttpClient())`. +* `fetchOpenSearchTemplate(feed: Feed)` has been replaced with `retrieveOpenSearchTemplate(feed: Feed)`. + +#### opds/OPDS2Parser + +* Both `parseURL(url: URL)` and `parseURL(headers: MutableMap, url: URL)` have been replaced with `parseUrlString(url: String, client: HttpClient = DefaultHttpClient())`. + +#### shared/FuelPromiseExtension + +* `Request.promise()` + +#### shared/format/Deprecated + +* `Response.sniffFormat` has been replaced with `org.readium.r2.shared.util.mediatype.sniffMediaType` + +#### shared/util/mediatype/Extensions + +* `Response.sniffMediaType(...)` has been replaced with `org.readium.r2.shared.util.mediatype.sniffMediaType` + ## 2.3.0 diff --git a/readium/opds/build.gradle.kts b/readium/opds/build.gradle.kts index 749f173f10..e0bd80f0e7 100644 --- a/readium/opds/build.gradle.kts +++ b/readium/opds/build.gradle.kts @@ -49,7 +49,6 @@ dependencies { implementation(libs.androidx.appcompat) implementation(libs.timber) implementation(libs.joda.time) - implementation("nl.komponents.kovenant:kovenant:3.3.0") implementation(libs.kotlinx.coroutines.core) // Tests diff --git a/readium/opds/src/main/java/org/readium/r2/opds/Extensions.kt b/readium/opds/src/main/java/org/readium/r2/opds/Extensions.kt deleted file mode 100644 index b46b1582af..0000000000 --- a/readium/opds/src/main/java/org/readium/r2/opds/Extensions.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2021 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.opds - -import kotlinx.coroutines.runBlocking -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.task -import org.readium.r2.shared.util.http.HttpClient -import org.readium.r2.shared.util.http.HttpFetchResponse -import org.readium.r2.shared.util.http.HttpRequest - -internal fun HttpClient.fetchPromise(request: HttpRequest): Promise { - return task { runBlocking { fetch(request).getOrThrow() } } -} diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt index e3258ee607..df1123cf1f 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt @@ -10,8 +10,6 @@ package org.readium.r2.opds import java.net.URL -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.then import org.joda.time.DateTime import org.readium.r2.shared.extensions.toList import org.readium.r2.shared.extensions.toMap @@ -60,29 +58,6 @@ class OPDS1Parser { } } - @Deprecated( - "Use `parseRequest` or `parseUrlString` with coroutines instead", - ReplaceWith("OPDS1Parser.parseUrlString(url)"), - DeprecationLevel.WARNING - ) - fun parseURL(url: URL): Promise { - return DefaultHttpClient().fetchPromise(HttpRequest(url.toString())) then { - this.parse(xmlData = it.body, url = url) - } - } - - @Deprecated( - "Use `parseRequest` or `parseUrlString` with coroutines instead", - ReplaceWith("OPDS1Parser.parseUrlString(url)"), - DeprecationLevel.WARNING - ) - @Suppress("unused") - fun parseURL(headers: MutableMap, url: URL): Promise { - return DefaultHttpClient().fetchPromise(HttpRequest(url = url.toString(), headers = headers)) then { - this.parse(xmlData = it.body, url = url) - } - } - fun parse(xmlData: ByteArray, url: URL): ParseData { val root = XmlParser().parse(xmlData.inputStream()) return if (root.name == "feed") @@ -254,65 +229,6 @@ class OPDS1Parser { } } - @Deprecated( - "Use `retrieveOpenSearchTemplate` with coroutines instead", - ReplaceWith("OPDS1Parser.retrieveOpenSearchTemplate(feed)"), - DeprecationLevel.WARNING - ) - @Suppress("unused") - fun fetchOpenSearchTemplate(feed: Feed): Promise { - - var openSearchURL: URL? = null - var selfMimeType: String? = null - - for (link in feed.links) { - if (link.rels.contains("self")) { - if (link.type != null) { - selfMimeType = link.type - } - } else if (link.rels.contains("search")) { - openSearchURL = URL(link.href) - } - } - - val unwrappedURL = openSearchURL?.let { - return@let it - } - - return DefaultHttpClient().fetchPromise(HttpRequest(unwrappedURL.toString())) then { - - val document = XmlParser().parse(it.body.inputStream()) - - val urls = document.get("Url", Namespaces.Search) - - var typeAndProfileMatch: ElementNode? = null - var typeMatch: ElementNode? = null - - selfMimeType?.let { s -> - - val selfMimeParams = parseMimeType(mimeTypeString = s) - for (url in urls) { - val urlMimeType = url.getAttr("type") ?: continue - val otherMimeParams = parseMimeType(mimeTypeString = urlMimeType) - if (selfMimeParams.type == otherMimeParams.type) { - if (typeMatch == null) { - typeMatch = url - } - if (selfMimeParams.parameters["profile"] == otherMimeParams.parameters["profile"]) { - typeAndProfileMatch = url - break - } - } - } - val match = typeAndProfileMatch ?: (typeMatch ?: urls[0]) - val template = match.getAttr("template") - - template - } - null - } - } - private fun parseEntry(entry: ElementNode, baseUrl: URL): Publication? { // A title is mandatory val title = entry.getFirst("title", Namespaces.Atom)?.text diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt index 9d98ea884b..8e5856d50a 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt @@ -10,8 +10,6 @@ package org.readium.r2.opds import java.net.URL -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.then import org.joda.time.DateTime import org.json.JSONArray import org.json.JSONObject @@ -53,29 +51,6 @@ class OPDS2Parser { } } - @Deprecated( - "Use `parseRequest` or `parseUrlString` with coroutines instead", - ReplaceWith("OPDS2Parser.parseUrlString(url)"), - DeprecationLevel.WARNING - ) - fun parseURL(url: URL): Promise { - return DefaultHttpClient().fetchPromise(HttpRequest(url.toString())) then { - this.parse(it.body, url) - } - } - - @Deprecated( - "Use `parseRequest` or `parseUrlString` with coroutines instead", - ReplaceWith("OPDS2Parser.parseUrlString(url)"), - DeprecationLevel.WARNING - ) - @Suppress("unused") - fun parseURL(headers: MutableMap, url: URL): Promise { - return DefaultHttpClient().fetchPromise(HttpRequest(url = url.toString(), headers = headers)) then { - this.parse(it.body, url) - } - } - fun parse(jsonData: ByteArray, url: URL): ParseData { return if (isFeed(jsonData)) { ParseData(parseFeed(jsonData, url), null, 2) diff --git a/readium/shared/build.gradle.kts b/readium/shared/build.gradle.kts index 219216d124..f856087046 100644 --- a/readium/shared/build.gradle.kts +++ b/readium/shared/build.gradle.kts @@ -47,16 +47,8 @@ apply(from = "$rootDir/scripts/publish-module.gradle") dependencies { implementation(libs.androidx.appcompat) implementation(libs.androidx.browser) - implementation("com.github.kittinunf.fuel:fuel-android:2.3.1") - implementation("com.github.kittinunf.fuel:fuel:2.3.1") implementation(libs.timber) implementation(libs.joda.time) - implementation("nl.komponents.kovenant:kovenant-android:3.3.0") - implementation("nl.komponents.kovenant:kovenant-combine:3.3.0") - implementation("nl.komponents.kovenant:kovenant-core:3.3.0") - implementation("nl.komponents.kovenant:kovenant-functional:3.3.0") - implementation("nl.komponents.kovenant:kovenant-jvm:3.3.0") - implementation("nl.komponents.kovenant:kovenant:3.3.0") implementation(libs.kotlin.reflect) implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/FuelPromiseExtension.kt b/readium/shared/src/main/java/org/readium/r2/shared/FuelPromiseExtension.kt deleted file mode 100644 index 555f827b18..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/FuelPromiseExtension.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Aferdita Muriqi, Clément Baumann - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared - -import com.github.kittinunf.fuel.core.Request -import com.github.kittinunf.fuel.core.Response -import com.github.kittinunf.result.Result -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.deferred -import nl.komponents.kovenant.task - -@Deprecated("Dependency to Fuel and kovenant will eventually be removed from the Readium Toolkit") -fun Request.promise(): Promise, Exception> { - val deferred = deferred, Exception>() - task { response() } success { - val (request, response, result) = it - when (result) { - is Result.Success -> deferred.resolve(Triple(request, response, result.value)) - is Result.Failure -> deferred.reject(result.error) - } - } fail { - deferred.reject(it) - } - return deferred.promise -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt b/readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt index 0695cf8f5d..89f4e5c43b 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt @@ -6,7 +6,6 @@ package org.readium.r2.shared.format -import com.github.kittinunf.fuel.core.Response import java.net.HttpURLConnection import org.readium.r2.shared.util.mediatype.MediaType as NewMediaType import org.readium.r2.shared.util.mediatype.Sniffer @@ -25,14 +24,6 @@ typealias FormatSniffers = Sniffers @Deprecated("Renamed SnifferContext", replaceWith = ReplaceWith("org.readium.r2.shared.util.mediatype.SnifferContext"), level = DeprecationLevel.ERROR) typealias FormatSnifferContext = SnifferContext -@Deprecated("Renamed to another package", ReplaceWith("org.readium.r2.shared.util.mediatype.sniffMediaType"), level = DeprecationLevel.ERROR) -suspend fun Response.sniffFormat( - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList(), - sniffers: List = NewMediaType.sniffers -): NewMediaType? = - sniffMediaType(mediaTypes, fileExtensions, sniffers) - @Deprecated("Renamed to another package", ReplaceWith("org.readium.r2.shared.util.mediatype.sniffMediaType"), level = DeprecationLevel.ERROR) suspend fun HttpURLConnection.sniffFormat( bytes: (() -> ByteArray)? = null, diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt index e06fd7b67f..6c7d3d5d58 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt @@ -6,7 +6,6 @@ package org.readium.r2.shared.util.mediatype -import com.github.kittinunf.fuel.core.Response import java.net.HttpURLConnection import org.readium.r2.shared.extensions.extension @@ -41,28 +40,3 @@ suspend fun HttpURLConnection.sniffMediaType( MediaType.of(mediaTypes = allMediaTypes, fileExtensions = allFileExtensions, sniffers = sniffers) } } - -/** - * Resolves the format for this [Response], with optional extra file extension and media type - * hints. - */ -suspend fun Response.sniffMediaType( - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList(), - sniffers: List = MediaType.sniffers -): MediaType? { - val allMediaTypes = mediaTypes.toMutableList() - val allFileExtensions = fileExtensions.toMutableList() - - // The value of the `Content-Type` HTTP header. - allMediaTypes.addAll(0, headers["Content-Type"]) - - // The URL file extension. - url.extension?.let { - allFileExtensions.add(0, it) - } - - // TODO: The suggested filename extension, part of the HTTP header `Content-Disposition`. - - return MediaType.ofBytes({ data }, mediaTypes = allMediaTypes, fileExtensions = allFileExtensions, sniffers = sniffers) -} From 6a489f76e83b37641ea066cc4fc2940d39dc89a8 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Mon, 17 Jul 2023 14:45:53 +0200 Subject: [PATCH 14/65] Abstract the toolkit over publication source (#353) --- .../pdfium/document/PdfiumDocument.kt | 9 +- .../navigator/PdfiumDocumentFragment.kt | 2 +- .../pspdfkit/document/PsPdfKitDocument.kt | 4 +- .../pspdfkit/document/ResourceDataProvider.kt | 7 +- .../readium/r2/lcp/LcpContentProtection.kt | 195 +++++++--- .../r2/lcp/LcpContentProtectionService.kt | 2 +- .../java/org/readium/r2/lcp/LcpDecryptor.kt | 15 +- .../org/readium/r2/lcp/LcpDecryptorTest.kt | 7 +- .../java/org/readium/r2/lcp/LcpLicense.kt | 4 +- .../java/org/readium/r2/lcp/LcpService.kt | 84 ++--- .../org/readium/r2/lcp/license/License.kt | 5 +- .../r2/lcp/license/LicenseValidation.kt | 8 +- .../container/ArchiveLicenseContainer.kt | 39 -- .../container/ContainerLicenseContainer.kt | 42 +++ .../container/FetcherLicenseContainer.kt | 42 --- .../container/LcplResourceLicenseContainer.kt | 34 ++ .../lcp/license/container/LicenseContainer.kt | 44 ++- .../org/readium/r2/lcp/service/CRLService.kt | 2 +- .../r2/lcp/service/LcpLicensedAsset.kt | 21 -- .../readium/r2/lcp/service/LicensesService.kt | 93 +++-- .../readium/r2/lcp/service/NetworkService.kt | 16 +- .../navigator/media2/ExoPlayerDataSource.kt | 7 +- .../navigator/media2/MediaNavigator.kt | 4 +- .../navigator/media2/SessionPlayerFacade.kt | 4 +- .../navigator/media2/SessionPlayerHelpers.kt | 2 +- .../readium/r2/navigator/R2BasicWebView.kt | 6 +- .../navigator/audio/PublicationDataSource.kt | 7 +- .../navigator/epub/EpubNavigatorFragment.kt | 4 +- .../readium/r2/navigator/epub/HtmlInjector.kt | 6 +- .../r2/navigator/epub/WebViewServer.kt | 13 +- .../r2/navigator/media/ExoMediaPlayer.kt | 22 +- .../readium/r2/navigator/media/MediaPlayer.kt | 2 +- .../r2/navigator/media/MediaService.kt | 2 +- .../navigator/media3/audio/AudioNavigator.kt | 4 +- .../media3/audio/MetadataRetriever.kt | 9 +- .../media3/exoplayer/ExoPlayerDataSource.kt | 9 +- .../media3/tts/session/TtsSessionAdapter.kt | 18 +- .../r2/navigator/pdf/PdfEngineProvider.kt | 2 +- .../r2/navigator/pdf/PdfNavigatorFragment.kt | 17 +- .../java/org/readium/r2/opds/OPDS1Parser.kt | 2 +- .../java/org/readium/r2/opds/OPDS2Parser.kt | 2 +- .../org/readium/r2/shared/UserException.kt | 2 +- .../java/org/readium/r2/shared/asset/Asset.kt | 82 ++++ .../readium/r2/shared/asset/AssetRetriever.kt | 356 ++++++++++++++++++ .../org/readium/r2/shared/asset/AssetType.kt | 29 ++ .../java/org/readium/r2/shared/error/Error.kt | 49 +++ .../java/org/readium/r2/shared/error/Try.kt | 139 +++++++ .../org/readium/r2/shared/extensions/File.kt | 4 +- .../r2/shared/fetcher/ArchiveFetcher.kt | 135 ------- .../r2/shared/fetcher/BytesResource.kt | 68 ++-- .../r2/shared/fetcher/ContainerFetcher.kt | 99 +++++ .../org/readium/r2/shared/fetcher/Fetcher.kt | 83 +++- .../readium/r2/shared/fetcher/FileFetcher.kt | 113 +----- .../readium/r2/shared/fetcher/HttpFetcher.kt | 183 --------- .../org/readium/r2/shared/fetcher/Resource.kt | 253 +++---------- .../fetcher/ResourceContentExtractor.kt | 12 +- .../r2/shared/fetcher/RoutingFetcher.kt | 3 +- .../r2/shared/fetcher/TransformingFetcher.kt | 2 +- .../readium/r2/shared/format/Deprecated.kt | 34 -- .../r2/shared/publication/Publication.kt | 63 +++- .../asset/DefaultPublicationAssetFactory.kt | 51 --- .../r2/shared/publication/asset/FileAsset.kt | 90 ----- .../publication/asset/PublicationAsset.kt | 31 -- .../asset/PublicationAssetFactory.kt | 26 -- .../shared/publication/asset/RemoteAsset.kt | 62 --- .../AdeptFallbackContentProtection.kt | 84 +++++ .../{ => protection}/ContentProtection.kt | 68 ++-- .../ContentProtectionSchemeRetriever.kt | 29 ++ .../publication/protection/EpubEncryption.kt | 14 + .../FallbackContentProtectionService.kt | 33 ++ .../LcpFallbackContentProtection.kt | 110 ++++++ .../services/ContentProtectionService.kt | 22 +- .../publication/services/CoverService.kt | 5 +- .../publication/services/PositionsService.kt | 5 +- .../iterators/HtmlResourceContentIterator.kt | 10 +- .../iterators/PublicationContentIterator.kt | 9 +- .../services/search/SearchService.kt | 6 +- .../services/search/StringSearchService.kt | 3 +- .../r2/shared/resource/BytesResource.kt | 63 ++++ .../readium/r2/shared/resource/Container.kt | 51 +++ .../r2/shared/resource/ContentResource.kt | 148 ++++++++ .../shared/resource/DefaultArchiveFactory.kt | 47 +++ .../r2/shared/resource/DirectoryContainer.kt | 95 +++++ .../readium/r2/shared/resource/Factories.kt | 208 ++++++++++ .../r2/shared/resource/FileChannelResource.kt | 102 +++++ .../r2/shared/resource/FileResource.kt | 126 +++++++ .../readium/r2/shared/resource/Resource.kt | 188 +++++++++ .../ResourceInputStream.kt | 14 +- .../r2/shared/resource/ZipContainer.kt | 154 ++++++++ .../org/readium/r2/shared/util/Deprecated.kt | 5 +- .../java/org/readium/r2/shared/util/Try.kt | 136 ------- .../java/org/readium/r2/shared/util/Url.kt | 48 ++- .../readium/r2/shared/util/archive/Archive.kt | 109 ------ .../r2/shared/util/archive/ExplodedArchive.kt | 74 ---- .../readium/r2/shared/util/archive/JavaZip.kt | 105 ------ .../{ChannelZip.kt => ChannelZipContainer.kt} | 119 ++++-- .../util/archive/channel/HttpChannel.kt | 3 +- .../util/archive/channel/ResourceChannel.kt | 103 +++++ .../r2/shared/util/http/DefaultHttpClient.kt | 30 +- .../readium/r2/shared/util/http/HttpClient.kt | 4 +- .../r2/shared/util/http/HttpException.kt | 2 +- .../r2/shared/util/http/HttpFetcher.kt | 70 ++++ .../r2/shared/util/http/HttpResource.kt | 144 +++++++ .../shared/util/http/HttpResourceFactory.kt | 27 ++ .../readium/r2/shared/util/http/MediaType.kt | 64 ++++ .../r2/shared/util/mediatype/Extensions.kt | 36 +- .../r2/shared/util/mediatype/MediaType.kt | 133 ++----- .../util/mediatype/MediaTypeRetriever.kt | 246 ++++++++++++ .../r2/shared/util/mediatype/Sniffer.kt | 172 ++++++--- .../shared/util/mediatype/SnifferContent.kt | 104 ----- .../shared/util/mediatype/SnifferContext.kt | 221 ++++++++--- .../readium/r2/shared/util/pdf/PdfDocument.kt | 6 +- .../shared/src/main/res/values/strings.xml | 4 +- .../java/org/readium/r2/shared/TestUtils.kt | 4 +- .../shared/fetcher/BufferingResourceTest.kt | 6 +- ...FetcherTest.kt => ContainerFetcherTest.kt} | 21 +- .../r2/shared/fetcher/FileFetcherTest.kt | 8 +- .../r2/shared/publication/PublicationTest.kt | 5 +- .../AdeptFallbackContentProtectionTest.kt | 83 ++++ .../LcpFallbackContentProtectionTest.kt | 100 +++++ .../publication/protection/TestContainer.kt | 53 +++ .../publication/services/CoverServiceTest.kt | 3 +- .../services/PositionsServiceTest.kt | 1 + .../ResourceInputStreamTest.kt | 7 +- .../ZipContainerTest.kt} | 64 ++-- .../util/mediatype/MediaTypeRetrieverTest.kt | 26 ++ .../r2/shared/util/mediatype/MediaTypeTest.kt | 8 - .../r2/shared/util/mediatype/SnifferTest.kt | 231 ++++++------ .../{util/archive => resource}/epub.epub | Bin .../epub/EPUB/cover.xhtml | 0 .../epub/EPUB/css/epub.css | 0 .../epub/EPUB/css/nav.css | 0 .../epub/EPUB/images/cover.png | Bin .../archive => resource}/epub/EPUB/nav.xhtml | 0 .../epub/EPUB/package.opf | 0 .../archive => resource}/epub/EPUB/s04.xhtml | 0 .../archive => resource}/epub/EPUB/toc.ncx | 0 .../epub/META-INF/container.xml | 0 .../{util/archive => resource}/epub/mimetype | 0 .../readium/r2/streamer/ParserAssetFactory.kt | 128 +++++++ .../readium/r2/streamer/PublicationFactory.kt | 268 +++++++++++++ .../java/org/readium/r2/streamer/Streamer.kt | 229 ----------- .../r2/streamer/container/Container.kt | 1 + .../readium/r2/streamer/extensions/Fetcher.kt | 35 +- .../readium/r2/streamer/fetcher/Fetcher.kt | 4 - .../r2/streamer/fetcher/HtmlInjector.kt | 343 ----------------- .../r2/streamer/fetcher/LcpDecryptor.kt | 166 -------- .../parser/FallbackContentProtection.kt | 99 ----- .../r2/streamer/parser/PublicationParser.kt | 57 ++- .../r2/streamer/parser/audio/AudioParser.kt | 62 +-- .../streamer/parser/epub/EpubDeobfuscator.kt | 9 +- .../r2/streamer/parser/epub/EpubParser.kt | 47 ++- .../parser/epub/EpubPositionsService.kt | 7 +- .../r2/streamer/parser/image/ImageParser.kt | 52 ++- .../r2/streamer/parser/pdf/PdfParser.kt | 19 +- .../parser/readium/ReadiumWebPubParser.kt | 44 ++- .../org/readium/r2/streamer/server/Assets.kt | 63 ---- .../org/readium/r2/streamer/server/Files.kt | 59 --- .../org/readium/r2/streamer/server/Globals.kt | 2 +- .../readium/r2/streamer/server/Resources.kt | 1 + .../org/readium/r2/streamer/server/Server.kt | 167 +------- .../r2/streamer/server/ServingFetcher.kt | 59 --- .../streamer/server/handler/AssetHandler.kt | 34 -- .../r2/streamer/server/handler/BaseHandler.kt | 75 ---- .../r2/streamer/server/handler/FileHandler.kt | 33 -- .../server/handler/ManifestHandler.kt | 28 -- .../handler/PublicationResourceHandler.kt | 182 --------- .../server/handler/ResourceHandler.kt | 37 -- .../streamer/server/handler/ResponseStatus.kt | 15 - .../java/org/readium/r2/streamer/TestUtils.kt | 9 +- .../r2/streamer/fetcher/HtmlInjectorTest.kt | 172 --------- .../parser/FallbackContentProtectionTest.kt | 146 ------- .../parser/epub/EpubDeobfuscatorTest.kt | 7 +- .../parser/epub/EpubPositionsServiceTest.kt | 8 +- .../streamer/parser/image/ImageParserTest.kt | 24 +- .../org/readium/r2/testapp/Application.kt | 4 +- .../org/readium/r2/testapp/MainActivity.kt | 2 +- .../readium/r2/testapp/PublicationError.kt | 77 ++++ .../java/org/readium/r2/testapp/Readium.kt | 75 +++- .../r2/testapp/bookshelf/BookRepository.kt | 217 +++++++---- .../r2/testapp/bookshelf/BookshelfFragment.kt | 69 ++-- .../testapp/bookshelf/BookshelfViewModel.kt | 62 ++- .../catalogs/CatalogFeedListViewModel.kt | 2 +- .../r2/testapp/catalogs/CatalogViewModel.kt | 4 +- .../catalogs/PublicationDetailFragment.kt | 2 +- .../readium/r2/testapp/domain/model/Book.kt | 50 ++- .../r2/testapp/drm/DrmManagementViewModel.kt | 2 +- .../r2/testapp/drm/LcpManagementViewModel.kt | 2 +- .../r2/testapp/reader/PdfReaderFragment.kt | 2 +- .../r2/testapp/reader/ReaderRepository.kt | 109 ++++-- .../r2/testapp/reader/ReaderViewModel.kt | 2 +- .../r2/testapp/search/SearchPagingSource.kt | 1 + .../r2/testapp/utils/extensions/File.kt | 10 +- .../r2/testapp/utils/extensions/Uri.kt | 9 +- test-app/src/main/res/values/arrays.xml | 5 +- test-app/src/main/res/values/strings.xml | 16 +- 196 files changed, 5723 insertions(+), 4655 deletions(-) delete mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt delete mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt delete mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/asset/AssetType.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/error/Try.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt rename readium/shared/src/main/java/org/readium/r2/shared/publication/{ => protection}/ContentProtection.kt (55%) create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/protection/EpubEncryption.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/protection/FallbackContentProtectionService.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt rename readium/shared/src/main/java/org/readium/r2/shared/{fetcher => resource}/ResourceInputStream.kt (90%) create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/ExplodedArchive.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/JavaZip.kt rename readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/{ChannelZip.kt => ChannelZipContainer.kt} (53%) create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt rename readium/shared/src/test/java/org/readium/r2/shared/fetcher/{ArchiveFetcherTest.kt => ContainerFetcherTest.kt} (91%) create mode 100644 readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt create mode 100644 readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt create mode 100644 readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt rename readium/shared/src/test/java/org/readium/r2/shared/{fetcher => resource}/ResourceInputStreamTest.kt (81%) rename readium/shared/src/test/java/org/readium/r2/shared/{util/archive/ArchiveTest.kt => resource/ZipContainerTest.kt} (51%) create mode 100644 readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeRetrieverTest.kt rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub.epub (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/cover.xhtml (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/css/epub.css (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/css/nav.css (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/images/cover.png (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/nav.xhtml (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/package.opf (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/s04.xhtml (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/EPUB/toc.ncx (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/META-INF/container.xml (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{util/archive => resource}/epub/mimetype (100%) create mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt create mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/HtmlInjector.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/LcpDecryptor.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/parser/FallbackContentProtection.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/Assets.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/Files.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/ServingFetcher.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/handler/AssetHandler.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/handler/BaseHandler.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/handler/FileHandler.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/handler/ManifestHandler.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/handler/PublicationResourceHandler.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/handler/ResourceHandler.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/server/handler/ResponseStatus.kt delete mode 100644 readium/streamer/src/test/java/org/readium/r2/streamer/fetcher/HtmlInjectorTest.kt delete mode 100644 readium/streamer/src/test/java/org/readium/r2/streamer/parser/FallbackContentProtectionTest.kt create mode 100644 test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt diff --git a/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt b/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt index d654bf1024..d6ffbff06e 100644 --- a/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt +++ b/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt @@ -16,9 +16,10 @@ import kotlin.reflect.KClass import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.PdfSupport +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.md5 import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.util.pdf.PdfDocument import org.readium.r2.shared.util.pdf.PdfDocumentFactory import org.readium.r2.shared.util.use @@ -89,19 +90,19 @@ class PdfiumDocumentFactory(context: Context) : PdfDocumentFactory Unit = { Timber.e(it) } ) : DataProvider { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt index 3a416cec4b..d687447808 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt @@ -7,89 +7,95 @@ package org.readium.r2.lcp import org.readium.r2.lcp.auth.LcpPassphraseAuthentication -import org.readium.r2.lcp.service.LcpLicensedAsset +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.error.ThrowableError +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.fetcher.ContainerFetcher import org.readium.r2.shared.fetcher.TransformingFetcher -import org.readium.r2.shared.publication.ContentProtection import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.FileAsset -import org.readium.r2.shared.publication.asset.PublicationAsset -import org.readium.r2.shared.publication.asset.RemoteAsset +import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.publication.services.contentProtectionServiceFactory -import org.readium.r2.shared.util.Try +import org.readium.r2.shared.resource.ArchiveFactory +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceFactory +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever internal class LcpContentProtection( private val lcpService: LcpService, - private val authentication: LcpAuthenticating + private val authentication: LcpAuthenticating, + private val mediaTypeRetriever: MediaTypeRetriever, + private val resourceFactory: ResourceFactory, + private val archiveFactory: ArchiveFactory ) : ContentProtection { + override val scheme: ContentProtection.Scheme = + ContentProtection.Scheme.Lcp + + override suspend fun supports( + asset: Asset + ): Boolean = + lcpService.isLcpProtected(asset) + override suspend fun open( - asset: PublicationAsset, + asset: Asset, credentials: String?, allowUserInteraction: Boolean, sender: Any? - ): Try? { + ): Try { + return when (asset) { + is Asset.Container -> openPublication(asset, credentials, allowUserInteraction, sender) + is Asset.Resource -> openLicense(asset, credentials, allowUserInteraction, sender) + } + } + + private suspend fun openPublication( + asset: Asset.Container, + credentials: String?, + allowUserInteraction: Boolean, + sender: Any? + ): Try { val license = retrieveLicense(asset, credentials, allowUserInteraction, sender) - ?: return null - return createProtectedAsset(asset, license) + return createResultAsset(asset, license) } - /* Returns null if the publication is not protected by LCP. */ private suspend fun retrieveLicense( - asset: PublicationAsset, + asset: Asset, credentials: String?, allowUserInteraction: Boolean, sender: Any? - ): Try? { - + ): Try { val authentication = credentials ?.let { LcpPassphraseAuthentication(it, fallback = this.authentication) } ?: this.authentication - val license = when (asset) { - is FileAsset -> - lcpService.retrieveLicense(asset.file, authentication, allowUserInteraction, sender) - is RemoteAsset -> - lcpService.retrieveLicense(asset.fetcher, asset.mediaType, authentication, allowUserInteraction, sender) - is LcpLicensedAsset -> - asset.license - ?.let { Try.success(it) } - ?: lcpService.retrieveLicense(asset.licenseFile, authentication, allowUserInteraction, sender) - else -> - null - } + val file = (asset as? Asset.Resource)?.resource?.file + ?: (asset as? Asset.Container)?.container?.file - return license?.takeUnless { result -> - result is Try.Failure<*, *> && result.exception is LcpException.Container - } + return file + // This is less restrictive with regard to network availability. + ?.let { lcpService.retrieveLicense(it, asset.mediaType, authentication, allowUserInteraction, sender) } + ?: lcpService.retrieveLicense(asset, authentication, allowUserInteraction, sender) } - private fun createProtectedAsset( - originalAsset: PublicationAsset, + private fun createResultAsset( + asset: Asset.Container, license: Try, - ): Try { + ): Try { val serviceFactory = LcpContentProtectionService - .createFactory(license.getOrNull(), license.exceptionOrNull()) + .createFactory(license.getOrNull(), license.failureOrNull()) - val newFetcher = TransformingFetcher( - originalAsset.fetcher, + val fetcher = TransformingFetcher( + ContainerFetcher(asset.container, mediaTypeRetriever), LcpDecryptor(license.getOrNull())::transform ) - val newAsset = when (originalAsset) { - is FileAsset -> { - originalAsset.copy(fetcher = newFetcher) - } - is RemoteAsset -> { - originalAsset.copy(fetcher = newFetcher) - } - is LcpLicensedAsset -> { - originalAsset.copy(fetcher = newFetcher) - } - else -> throw IllegalStateException() - } - - val protectedFile = ContentProtection.ProtectedAsset( - asset = newAsset, + val protectedFile = ContentProtection.Asset( + name = asset.name, + mediaType = asset.mediaType, + fetcher = fetcher, onCreatePublication = { servicesBuilder.contentProtectionServiceFactory = serviceFactory } @@ -97,4 +103,91 @@ internal class LcpContentProtection( return Try.success(protectedFile) } + + private suspend fun openLicense( + licenseAsset: Asset.Resource, + credentials: String?, + allowUserInteraction: Boolean, + sender: Any? + ): Try { + val license = retrieveLicense(licenseAsset, credentials, allowUserInteraction, sender) + + val licenseDoc = license.getOrNull()?.license + ?: licenseAsset.resource.read() + .map { + try { + LicenseDocument(it) + } catch (e: Exception) { + return Try.failure( + Publication.OpeningException.ParsingFailed( + ThrowableError(e) + ) + ) + } + } + .getOrElse { + return Try.failure( + it.wrap() + ) + } + + val link = checkNotNull(licenseDoc.link(LicenseDocument.Rel.publication)) + val url = Url(link.url.toString()) + ?: return Try.failure( + Publication.OpeningException.ParsingFailed( + ThrowableError( + LcpException.Parsing.Url(rel = LicenseDocument.Rel.publication.rawValue) + ) + ) + ) + + val resource = resourceFactory.create(url) + .getOrElse { return Try.failure(it.wrap()) } + + val container = archiveFactory.create(resource, password = null) + .getOrElse { return Try.failure(it.wrap()) } + + val publicationAsset = Asset.Container( + url.filename, + link.mediaType, + false, + container + ) + + return createResultAsset(publicationAsset, license) + } + + private fun ResourceFactory.Error.wrap(): Publication.OpeningException = + when (this) { + is ResourceFactory.Error.NotAResource -> + Publication.OpeningException.NotFound() + is ResourceFactory.Error.Forbidden -> + Publication.OpeningException.Forbidden() + is ResourceFactory.Error.SchemeNotSupported -> + Publication.OpeningException.UnsupportedAsset() + } + + private fun ArchiveFactory.Error.wrap(): Publication.OpeningException = + when (this) { + is ArchiveFactory.Error.FormatNotSupported -> + Publication.OpeningException.UnsupportedAsset() + is ArchiveFactory.Error.PasswordsNotSupported -> + Publication.OpeningException.UnsupportedAsset() + is ArchiveFactory.Error.ResourceReading -> + resourceException.wrap() + } + + private fun Resource.Exception.wrap(): Publication.OpeningException = + when (this) { + is Resource.Exception.Forbidden -> + Publication.OpeningException.Forbidden(ThrowableError(this)) + is Resource.Exception.NotFound -> + Publication.OpeningException.NotFound(ThrowableError(this)) + Resource.Exception.Offline, is Resource.Exception.Unavailable -> + Publication.OpeningException.Unavailable(ThrowableError(this)) + is Resource.Exception.Other, is Resource.Exception.BadRequest -> + Publication.OpeningException.Unexpected(this) + is Resource.Exception.OutOfMemory -> + Publication.OpeningException.OutOfMemory(ThrowableError(this)) + } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtectionService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtectionService.kt index 71eedd8890..4512832d25 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtectionService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtectionService.kt @@ -9,8 +9,8 @@ package org.readium.r2.lcp -import org.readium.r2.shared.publication.ContentProtection import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.publication.services.ContentProtectionService class LcpContentProtectionService(val license: LcpLicense?, override val error: LcpException?) : ContentProtectionService { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt index fdcfb8e9d1..703db1bbd8 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt @@ -10,21 +10,24 @@ package org.readium.r2.lcp import java.io.IOException +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.coerceFirstNonNegative import org.readium.r2.shared.extensions.inflate import org.readium.r2.shared.extensions.requireLengthFitInt import org.readium.r2.shared.fetcher.* import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.encryption.encryption -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry /** * Decrypts a resource protected with LCP. */ internal class LcpDecryptor(val license: LcpLicense?) { - fun transform(resource: Resource): Resource = LazyResource { + fun transform(resource: Fetcher.Resource): Fetcher.Resource = LazyResource { // Checks if the resource is encrypted and whether the encryption schemes of the resource // and the DRM license are the same. val link = resource.link() @@ -46,7 +49,7 @@ internal class LcpDecryptor(val license: LcpLicense?) { * resource, for example when the resource is deflated before encryption. */ private class FullLcpResource( - resource: Resource, + resource: Fetcher.Resource, private val license: LcpLicense ) : TransformingResource(resource) { @@ -65,9 +68,9 @@ internal class LcpDecryptor(val license: LcpLicense?) { * Supports random access for byte range requests, but the resource MUST NOT be deflated. */ private class CbcLcpResource( - private val resource: Resource, + private val resource: Fetcher.Resource, private val license: LcpLicense - ) : Resource { + ) : Fetcher.Resource { private class Cache( var startIndex: Int? = null, diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt index 299d4681ae..978ef987e5 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt @@ -10,11 +10,12 @@ package org.readium.r2.lcp import kotlin.math.ceil +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.coerceIn -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.mapCatching import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.use import timber.log.Timber @@ -110,7 +111,7 @@ private suspend fun checkExceedingRangesAreAllowed(publication: Publication) { } } -private suspend fun Resource.readByChunks( +private suspend fun Fetcher.Resource.readByChunks( chunkSize: Long, groundTruth: ByteArray, shuffle: Boolean = true diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt index e8ca3acc08..87a077f16e 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt @@ -15,8 +15,8 @@ import kotlinx.coroutines.runBlocking import org.joda.time.DateTime import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.lcp.license.model.StatusDocument +import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.services.ContentProtectionService -import org.readium.r2.shared.util.Try import timber.log.Timber /** @@ -129,7 +129,7 @@ interface LcpLicense : ContentProtectionService.UserRights { @DelicateCoroutinesApi fun returnPublication(completion: (LcpException?) -> Unit) { GlobalScope.launch { - completion(returnPublication().exceptionOrNull()) + completion(returnPublication().failureOrNull()) } } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt index 8b27d1c559..68e098b463 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt @@ -11,7 +11,11 @@ package org.readium.r2.lcp import android.content.Context import java.io.File -import kotlinx.coroutines.* +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.readium.r2.lcp.auth.LcpDialogAuthentication import org.readium.r2.lcp.persistence.LcpDatabase import org.readium.r2.lcp.service.CRLService @@ -23,15 +27,15 @@ import org.readium.r2.lcp.service.LicensesService import org.readium.r2.lcp.service.NetworkService import org.readium.r2.lcp.service.PassphrasesRepository import org.readium.r2.lcp.service.PassphrasesService -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.ContentProtection -import org.readium.r2.shared.publication.asset.PublicationAsset -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.archive.DefaultArchiveFactory -import org.readium.r2.shared.util.http.DefaultHttpClient -import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.resource.ArchiveFactory +import org.readium.r2.shared.resource.DefaultArchiveFactory +import org.readium.r2.shared.resource.FileResourceFactory +import org.readium.r2.shared.resource.ResourceFactory import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Service used to acquire and open publications protected with LCP. @@ -39,10 +43,15 @@ import org.readium.r2.shared.util.mediatype.MediaType interface LcpService { /** - * Returns if the publication is protected by LCP. + * Returns if the file is a LCP license document or a publication protected by LCP. */ suspend fun isLcpProtected(file: File): Boolean + /** + * Returns if the asset is a LCP license document or a publication protected by LCP. + */ + suspend fun isLcpProtected(asset: Asset): Boolean + /** * Acquires a protected publication from a standalone LCPL's bytes. * @@ -80,6 +89,7 @@ interface LcpService { */ suspend fun retrieveLicense( file: File, + mediaType: MediaType, authentication: LcpAuthenticating = LcpDialogAuthentication(), allowUserInteraction: Boolean, sender: Any? = null @@ -87,7 +97,7 @@ interface LcpService { /** * Opens the LCP license of a protected publication, to access its DRM metadata and decipher - * its content. As the updated license cannot be stored through a [Fetcher], + * its content. As the updated license cannot be stored through a [Asset], * you'll get an exception if the license points to a LSD server that cannot be reached, * for instance because no Internet gateway is available. * @@ -99,11 +109,10 @@ interface LcpService { * presenting dialogs with [LcpAuthenticating]. */ suspend fun retrieveLicense( - fetcher: Fetcher, - mediaType: MediaType, + asset: Asset, authentication: LcpAuthenticating = LcpDialogAuthentication(), allowUserInteraction: Boolean, - sender: Any? = null + sender: Any? ): Try /** @@ -114,13 +123,9 @@ interface LcpService { * LCP license. The default implementation [LcpDialogAuthentication] presents a dialog to the * user to enter their passphrase. */ - fun contentProtection(authentication: LcpAuthenticating = LcpDialogAuthentication()): ContentProtection = - LcpContentProtection(this, authentication) - - /** - * Builds a [PublicationAsset] to open a LCP-protected publication from its license file. - */ - suspend fun remoteAssetForLicense(license: File): Try + fun contentProtection( + authentication: LcpAuthenticating = LcpDialogAuthentication(), + ): ContentProtection /** * Information about an acquired publication protected with LCP. @@ -145,8 +150,9 @@ interface LcpService { */ operator fun invoke( context: Context, - archiveFactory: ArchiveFactory = DefaultArchiveFactory(), - httpClient: HttpClient = DefaultHttpClient() + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), + resourceFactory: ResourceFactory = FileResourceFactory(), + archiveFactory: ArchiveFactory = DefaultArchiveFactory() ): LcpService? { if (!LcpClient.isAvailable()) return null @@ -155,7 +161,7 @@ interface LcpService { val deviceRepository = DeviceRepository(db) val passphraseRepository = PassphrasesRepository(db) val licenseRepository = LicensesRepository(db) - val network = NetworkService() + val network = NetworkService(mediaTypeRetriever = mediaTypeRetriever) val device = DeviceService(repository = deviceRepository, network = network, context = context) val crl = CRLService(network = network, context = context) val passphrases = PassphrasesService(repository = passphraseRepository) @@ -166,8 +172,9 @@ interface LcpService { network = network, passphrases = passphrases, context = context, - archiveFactory = archiveFactory, - httpClient = httpClient + mediaTypeRetriever = mediaTypeRetriever, + resourceFactory = resourceFactory, + archiveFactory = archiveFactory ) } @@ -175,7 +182,7 @@ interface LcpService { fun create(context: Context): LcpService? = invoke(context) } - @Deprecated("Use `acquirePublication()` with coroutines instead", ReplaceWith("acquirePublication(lcpl)")) + @Deprecated("Use `acquirePublication()` with coroutines instead", ReplaceWith("acquirePublication(lcpl)"), level = DeprecationLevel.ERROR) @DelicateCoroutinesApi fun importPublication( lcpl: ByteArray, @@ -189,35 +196,20 @@ interface LcpService { } } - @Deprecated("Use `retrieveLicense()` with coroutines instead", ReplaceWith("retrieveLicense(File(publication), authentication, allowUserInteraction = true)")) + @Deprecated("Use `retrieveLicense()` with coroutines instead", ReplaceWith("retrieveLicense(File(publication), authentication, allowUserInteraction = true)"), level = DeprecationLevel.ERROR) @DelicateCoroutinesApi fun retrieveLicense( publication: String, authentication: LcpAuthenticating?, completion: (LcpLicense?, LcpException?) -> Unit ) { - GlobalScope.launch { - val result = - try { - retrieveLicense(File(publication), authentication ?: LcpDialogAuthentication(), allowUserInteraction = true) - } catch (e: CancellationException) { - null - } - - if (result == null) { - completion(null, null) - } else { - result - .onSuccess { completion(it, null) } - .onFailure { completion(null, it) } - } - } + throw NotImplementedError() } } -@Deprecated("Renamed to `LcpService()`", replaceWith = ReplaceWith("LcpService(context)")) +@Deprecated("Renamed to `LcpService()`", replaceWith = ReplaceWith("LcpService(context)"), level = DeprecationLevel.ERROR) fun R2MakeLCPService(context: Context): LcpService = LcpService(context) ?: throw Exception("liblcp is missing on the classpath") -@Deprecated("Renamed to `LcpService.AcquiredPublication`", replaceWith = ReplaceWith("LcpService.AcquiredPublication")) +@Deprecated("Renamed to `LcpService.AcquiredPublication`", replaceWith = ReplaceWith("LcpService.AcquiredPublication"), level = DeprecationLevel.ERROR) typealias LCPImportedPublication = LcpService.AcquiredPublication diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt index faef7f453a..6842b9062c 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt @@ -25,10 +25,11 @@ import org.readium.r2.lcp.service.DeviceService import org.readium.r2.lcp.service.LcpClient import org.readium.r2.lcp.service.LicensesRepository import org.readium.r2.lcp.service.NetworkService +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.toIso8601String import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt index 1c539beef2..594a30d723 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt @@ -18,8 +18,12 @@ import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.lcp.license.model.StatusDocument import org.readium.r2.lcp.license.model.components.Link -import org.readium.r2.lcp.service.* -import org.readium.r2.shared.util.getOrElse +import org.readium.r2.lcp.service.CRLService +import org.readium.r2.lcp.service.DeviceService +import org.readium.r2.lcp.service.LcpClient +import org.readium.r2.lcp.service.NetworkService +import org.readium.r2.lcp.service.PassphrasesService +import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt deleted file mode 100644 index b26ffce22a..0000000000 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ArchiveLicenseContainer.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.lcp.license.container - -import kotlinx.coroutines.runBlocking -import org.readium.r2.lcp.LcpException -import org.readium.r2.lcp.license.model.LicenseDocument -import org.readium.r2.shared.util.archive.Archive - -/** - * Access to a License Document stored in a read-only ZIP archive. - */ -internal class ArchiveLicenseContainer( - private val archive: Archive, - private val entryPath: String, -) : LicenseContainer { - - override fun read(): ByteArray { - val entry = try { - runBlocking { archive.entry(entryPath) } - } catch (e: Exception) { - throw LcpException.Container.FileNotFound(entryPath) - } - - return try { - runBlocking { entry.read() } - } catch (e: Exception) { - throw LcpException.Container.ReadFailed(entryPath) - } - } - - override fun write(license: LicenseDocument) { - throw LcpException.Container.WriteFailed(entryPath) - } -} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt new file mode 100644 index 0000000000..502a0f4a10 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.license.container + +import kotlinx.coroutines.runBlocking +import org.readium.r2.lcp.LcpException +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource + +/** + * Access to a License Document stored in a read-only container. + */ +internal class ContainerLicenseContainer( + private val container: Container, + private val entryPath: String, +) : LicenseContainer { + + override fun read(): ByteArray { + return runBlocking { + container + .entry(entryPath) + .read() + .mapFailure { + when (it) { + is Resource.Exception.NotFound -> LcpException.Container.FileNotFound(entryPath) + else -> LcpException.Container.ReadFailed(entryPath) + } + } + .getOrThrow() + } + } + + override fun write(license: LicenseDocument) { + throw LcpException.Container.WriteFailed(entryPath) + } +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt deleted file mode 100644 index ed15736b71..0000000000 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FetcherLicenseContainer.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.lcp.license.container - -import kotlinx.coroutines.runBlocking -import org.readium.r2.lcp.LcpException -import org.readium.r2.lcp.license.model.LicenseDocument -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.Resource -import org.readium.r2.shared.util.use - -/** - * Access to a License Document stored in a [Fetcher]. - */ -internal class FetcherLicenseContainer( - private val fetcher: Fetcher, - private val entryPath: String, -) : LicenseContainer { - - override fun read(): ByteArray = - runBlocking { - fetcher.get(entryPath).use { resource -> - resource.read() - .mapFailure { it.toLcpException() } - .getOrThrow() - } - } - - private fun Resource.Exception.toLcpException() = - when (this) { - is Resource.Exception.NotFound -> LcpException.Container.FileNotFound(entryPath) - else -> LcpException.Container.ReadFailed(entryPath) - } - - override fun write(license: LicenseDocument) { - throw LcpException.Container.WriteFailed(entryPath) - } -} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt new file mode 100644 index 0000000000..6277b4a003 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt @@ -0,0 +1,34 @@ +/* + * Module: r2-lcp-kotlin + * Developers: Aferdita Muriqi, Mickaël Menu + * + * Copyright (c) 2019. Readium Foundation. All rights reserved. + * Use of this source code is governed by a BSD-style license which is detailed in the + * LICENSE file present in the project repository where this source code is maintained. + */ + +package org.readium.r2.lcp.license.container + +import kotlinx.coroutines.runBlocking +import org.readium.r2.lcp.LcpException +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.resource.Resource + +/** + * Access a License Document stored in an LCP License Document file (LCPL) readable through a + * [Resource]. + */ +internal class LcplResourceLicenseContainer(private val resource: Resource) : LicenseContainer { + + override fun read(): ByteArray = + try { + runBlocking { resource.read().getOrThrow() } + } catch (e: Exception) { + throw LcpException.Container.OpenFailed + } + + override fun write(license: LicenseDocument) { + throw LcpException.Container.WriteFailed("") + } +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt index b07b00df1c..52fcce6347 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt @@ -9,10 +9,13 @@ package org.readium.r2.lcp.license.container +import java.io.File import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.extensions.addPrefix -import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.mediatype.MediaType private const val LICENSE_IN_EPUB = "META-INF/license.lcpl" @@ -28,28 +31,37 @@ internal interface LicenseContainer { fun write(license: LicenseDocument) } -internal suspend fun createLicenseContainer( - filepath: String, - mediaTypes: List = emptyList() -): LicenseContainer { - val mediaType = MediaType.ofFile(filepath, mediaTypes = mediaTypes, fileExtensions = emptyList()) - ?: throw LcpException.Container.OpenFailed - return createLicenseContainer(filepath, mediaType) -} - internal fun createLicenseContainer( - filepath: String, + file: File, mediaType: MediaType ): LicenseContainer = when (mediaType) { - MediaType.EPUB -> ZIPLicenseContainer(filepath, LICENSE_IN_EPUB) - MediaType.LCP_LICENSE_DOCUMENT -> LCPLLicenseContainer(filepath) + MediaType.EPUB -> ZIPLicenseContainer(file.path, LICENSE_IN_EPUB) + MediaType.LCP_LICENSE_DOCUMENT -> LCPLLicenseContainer(file.path) // Assuming it's a Readium WebPub package (e.g. audiobook, LCPDF, etc.) as a fallback - else -> ZIPLicenseContainer(filepath, LICENSE_IN_RPF) + else -> ZIPLicenseContainer(file.path, LICENSE_IN_RPF) + } + +internal fun createLicenseContainer( + asset: Asset, +): LicenseContainer = + when (asset) { + is Asset.Resource -> createLicenseContainer(asset.resource, asset.mediaType) + is Asset.Container -> createLicenseContainer(asset.container, asset.mediaType) } internal fun createLicenseContainer( - fetcher: Fetcher, + resource: Resource, + mediaType: MediaType +): LicenseContainer { + if (mediaType != MediaType.LCP_LICENSE_DOCUMENT) { + throw LcpException.Container.OpenFailed + } + return LcplResourceLicenseContainer(resource) +} + +internal fun createLicenseContainer( + container: Container, mediaType: MediaType, ): LicenseContainer { val licensePath = when (mediaType) { @@ -57,5 +69,5 @@ internal fun createLicenseContainer( // Assuming it's a Readium WebPub package (e.g. audiobook, LCPDF, etc.) as a fallback else -> LICENSE_IN_RPF.addPrefix("/") } - return FetcherLicenseContainer(fetcher, licensePath) + return ContainerLicenseContainer(container, licensePath) } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt index 992ca8e40b..053f49ea50 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt @@ -18,7 +18,7 @@ import org.joda.time.DateTime import org.joda.time.Days import org.readium.r2.lcp.BuildConfig.DEBUG import org.readium.r2.lcp.LcpException -import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.error.getOrElse import timber.log.Timber @OptIn(ExperimentalTime::class) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt deleted file mode 100644 index 0123186cf6..0000000000 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpLicensedAsset.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.lcp.service - -import java.io.File -import org.readium.r2.lcp.LcpLicense -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.asset.PublicationAsset -import org.readium.r2.shared.util.mediatype.MediaType - -data class LcpLicensedAsset( - override val name: String, - override val mediaType: MediaType, - override val fetcher: Fetcher, - val licenseFile: File, - val license: LcpLicense? -) : PublicationAsset diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index b42fcf95a3..9e0de40c18 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -12,26 +12,31 @@ package org.readium.r2.lcp.service import android.content.Context import java.io.File import kotlin.coroutines.resume -import kotlinx.coroutines.* +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.withContext import org.readium.r2.lcp.LcpAuthenticating +import org.readium.r2.lcp.LcpContentProtection import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.LcpLicense import org.readium.r2.lcp.LcpService -import org.readium.r2.lcp.auth.LcpDumbAuthentication import org.readium.r2.lcp.license.License import org.readium.r2.lcp.license.LicenseValidation import org.readium.r2.lcp.license.container.LicenseContainer import org.readium.r2.lcp.license.container.createLicenseContainer import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.tryOr -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.asset.PublicationAsset -import org.readium.r2.shared.publication.asset.RemoteAsset -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.resource.ArchiveFactory +import org.readium.r2.shared.resource.ResourceFactory import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber internal class LicensesService( @@ -41,50 +46,34 @@ internal class LicensesService( private val network: NetworkService, private val passphrases: PassphrasesService, private val context: Context, - private val archiveFactory: ArchiveFactory, - private val httpClient: HttpClient + private val mediaTypeRetriever: MediaTypeRetriever, + private val resourceFactory: ResourceFactory, + private val archiveFactory: ArchiveFactory ) : LcpService, CoroutineScope by MainScope() { override suspend fun isLcpProtected(file: File): Boolean = tryOr(false) { - createLicenseContainer(file.path).read() + val mediaType = mediaTypeRetriever.retrieve(file) ?: return false + createLicenseContainer(file, mediaType).read() true } - override suspend fun remoteAssetForLicense(license: File): Try { - return try { - Try.success(remoteAssetForLicenseThrowing(license)) - } catch (e: Exception) { - Try.failure(LcpException.wrap(e)) + override suspend fun isLcpProtected(asset: Asset): Boolean = + tryOr(false) { + when (asset) { + is Asset.Resource -> + asset.mediaType == MediaType.LCP_LICENSE_DOCUMENT + is Asset.Container -> { + createLicenseContainer(asset.container, asset.mediaType).read() + true + } + } } - } - - private suspend fun remoteAssetForLicenseThrowing(licenseFile: File): PublicationAsset { - // Update the license file to get a fresh publication URL. - val license = retrieveLicense(licenseFile, LcpDumbAuthentication(), false) - .getOrNull() - - val licenseDoc = license?.license - ?: LicenseDocument(licenseFile.readBytes()) - val link = checkNotNull(licenseDoc.link(LicenseDocument.Rel.publication)) - val url = try { - Url(link.url.toString()) ?: throw IllegalStateException() - } catch (e: Exception) { - throw LcpException.Parsing.Url(rel = LicenseDocument.Rel.publication.rawValue) - } - val baseAsset = RemoteAsset.Factory(archiveFactory, httpClient) - .createAsset(url, link.mediaType) - .getOrThrow() - - return LcpLicensedAsset( - baseAsset.name, - baseAsset.mediaType, - baseAsset.fetcher, - licenseFile, - license - ) - } + override fun contentProtection( + authentication: LcpAuthenticating, + ): ContentProtection = + LcpContentProtection(this, authentication, mediaTypeRetriever, resourceFactory, archiveFactory) override suspend fun acquirePublication(lcpl: ByteArray, onProgress: (Double) -> Unit): Try = try { @@ -97,12 +86,13 @@ internal class LicensesService( override suspend fun retrieveLicense( file: File, + mediaType: MediaType, authentication: LcpAuthenticating, allowUserInteraction: Boolean, sender: Any? ): Try = try { - val container = createLicenseContainer(file.path) + val container = createLicenseContainer(file, mediaType) val license = retrieveLicense(container, authentication, allowUserInteraction, true, sender) Try.success(license) } catch (e: Exception) { @@ -110,15 +100,14 @@ internal class LicensesService( } override suspend fun retrieveLicense( - fetcher: Fetcher, - mediaType: MediaType, + asset: Asset, authentication: LcpAuthenticating, allowUserInteraction: Boolean, sender: Any? ): Try = try { - val container = createLicenseContainer(fetcher, mediaType) - val license = retrieveLicense(container, authentication, allowUserInteraction, false, sender) + val licenseContainer = createLicenseContainer(asset) + val license = retrieveLicense(licenseContainer, authentication, allowUserInteraction, false, sender) Try.success(license) } catch (e: Exception) { Try.failure(LcpException.wrap(e)) @@ -238,10 +227,12 @@ internal class LicensesService( } Timber.i("LCP destination $destination") - val mediaType = network.download(url, destination, mediaType = link.type, onProgress = onProgress) ?: MediaType.of(mediaType = link.type) ?: MediaType.EPUB + val mediaType = network.download(url, destination, mediaType = link.type, onProgress = onProgress) + ?: mediaTypeRetriever.retrieve(mediaType = link.type) + ?: MediaType.EPUB // Saves the License Document into the downloaded publication - val container = createLicenseContainer(destination.path, mediaType) + val container = createLicenseContainer(destination, mediaType) container.write(license) return LcpService.AcquiredPublication( diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt index 182592ecaf..ff4d7524fa 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt @@ -17,21 +17,22 @@ import java.net.HttpURLConnection import java.net.URL import kotlin.math.round import kotlin.time.Duration -import kotlin.time.ExperimentalTime import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.lcp.LcpException -import org.readium.r2.shared.util.Try +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.http.retrieve import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.mediatype.sniffMediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber internal typealias URLParameters = Map internal class NetworkException(val status: Int?, cause: Throwable? = null) : Exception("Network failure with status $status", cause) -@OptIn(ExperimentalTime::class) -internal class NetworkService { +internal class NetworkService( + private val mediaTypeRetriever: MediaTypeRetriever +) { enum class Method(val rawValue: String) { GET("GET"), POST("POST"), PUT("PUT"); @@ -132,7 +133,10 @@ internal class NetworkService { } } - connection.sniffMediaType(mediaTypes = listOfNotNull(mediaType)) + mediaTypeRetriever.retrieve( + connection = connection, + mediaType = mediaType + ) } catch (e: Exception) { Timber.e(e) throw LcpException.Network(e) diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt index 16836b801b..88cc175613 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt @@ -15,7 +15,8 @@ import com.google.android.exoplayer2.upstream.DataSpec import com.google.android.exoplayer2.upstream.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.buffered import org.readium.r2.shared.publication.Publication @@ -44,7 +45,7 @@ class ExoPlayerDataSource internal constructor(private val publication: Publicat } private data class OpenedResource( - val resource: Resource, + val resource: Fetcher.Resource, val uri: Uri, var position: Long, ) @@ -80,7 +81,7 @@ class ExoPlayerDataSource internal constructor(private val publication: Publicat /** Cached content lengths indexed by their URL. */ private var cachedLengths: MutableMap = mutableMapOf() - private fun contentLengthOf(uri: Uri, resource: Resource): Long? { + private fun contentLengthOf(uri: Uri, resource: Fetcher.Resource): Long? { cachedLengths[uri.toString()]?.let { return it } val length = runBlocking { resource.length() }.getOrNull() diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt index 3332e877fa..017b4f6b04 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt @@ -31,12 +31,12 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.readium.navigator.media2.MediaNavigator.Companion.create import org.readium.r2.navigator.Navigator +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.indexOfFirstWithHref -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap import timber.log.Timber /** diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt index 081f536af9..89f7e085ec 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt @@ -26,8 +26,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap import timber.log.Timber /** diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt index f6895327cc..70e19e83c2 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt @@ -12,7 +12,7 @@ import androidx.media2.common.SessionPlayer import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlin.time.ExperimentalTime -import org.readium.r2.shared.util.Try +import org.readium.r2.shared.error.Try internal enum class SessionPlayerState { Idle, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt index 5d9a189711..760a4eecb1 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt @@ -39,13 +39,15 @@ import org.readium.r2.navigator.input.InputModifier import org.readium.r2.navigator.input.Key import org.readium.r2.navigator.input.KeyEvent import org.readium.r2.shared.InternalReadiumApi +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.optNullableString import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.ReadingProgression +import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.use import timber.log.Timber @@ -84,7 +86,7 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte @InternalReadiumApi fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? = null @InternalReadiumApi - fun resourceAtUrl(url: String): Resource? = null + fun resourceAtUrl(url: String): Fetcher.Resource? = null /** * Requests to load the next resource in the reading order. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt index 5ac5dad6e0..54c60c192b 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt @@ -15,7 +15,8 @@ import com.google.android.exoplayer2.upstream.DataSpec import com.google.android.exoplayer2.upstream.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.buffered import org.readium.r2.shared.publication.Publication @@ -44,7 +45,7 @@ internal class PublicationDataSource(private val publication: Publication) : Bas } private data class OpenedResource( - val resource: Resource, + val resource: Fetcher.Resource, val uri: Uri, var position: Long, ) @@ -80,7 +81,7 @@ internal class PublicationDataSource(private val publication: Publication) : Bas /** Cached content lengths indexed by their URL. */ private var cachedLengths: MutableMap = mutableMapOf() - private fun contentLengthOf(uri: Uri, resource: Resource): Long? { + private fun contentLengthOf(uri: Uri, resource: Fetcher.Resource): Long? { cachedLengths[uri.toString()]?.let { return it } val length = runBlocking { resource.length() }.getOrNull() diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt index 03bb6e9ecd..26e8b54811 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt @@ -68,7 +68,7 @@ import org.readium.r2.navigator.util.createFragmentFactory import org.readium.r2.shared.DelicateReadiumApi import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.extensions.tryOrLog -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication @@ -821,7 +821,7 @@ class EpubNavigatorFragment internal constructor( override fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? = viewModel.shouldInterceptRequest(request) - override fun resourceAtUrl(url: String): Resource? = + override fun resourceAtUrl(url: String): Fetcher.Resource? = viewModel.internalLinkFromUrl(url) ?.let { publication.get(it) } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt index d93b172c4a..e6165e9d0a 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt @@ -8,7 +8,7 @@ package org.readium.r2.navigator.epub import org.readium.r2.navigator.epub.css.ReadiumCss import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.TransformingResource import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.epub.EpubLayout @@ -22,12 +22,12 @@ import timber.log.Timber * @param baseHref Base URL where the Readium CSS and scripts are served. */ @OptIn(ExperimentalReadiumApi::class) -internal fun Resource.injectHtml( +internal fun Fetcher.Resource.injectHtml( publication: Publication, css: ReadiumCss, baseHref: String, disableSelectionWhenProtected: Boolean -): Resource = +): Fetcher.Resource = TransformingResource(this) { bytes -> val link = link() check(link.mediaType.isHtml) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt index 602444cf12..29643b2baa 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt @@ -16,12 +16,13 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.navigator.epub.css.ReadiumCss import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Resource -import org.readium.r2.shared.fetcher.ResourceInputStream +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.StringResource import org.readium.r2.shared.fetcher.fallback import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceInputStream import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.http.HttpHeaders import org.readium.r2.shared.util.http.HttpRange @@ -83,7 +84,11 @@ internal class WebViewServer( ?.copy(href = href) ?: Link(href = href) - var resource = publication.get(link) + // Drop anchor because it is meant to be interpreted by the client. + val linkWithoutAnchor = link + .copy(href.takeWhile { it != '#' }) + + var resource = publication.get(linkWithoutAnchor) .fallback { errorResource(link, error = it) } if (link.mediaType.isHtml) { resource = resource.injectHtml( @@ -110,7 +115,7 @@ internal class WebViewServer( } } - private fun errorResource(link: Link, error: Resource.Exception): Resource = + private fun errorResource(link: Link, error: Resource.Exception): Fetcher.Resource = StringResource(link.copy(type = MediaType.XHTML.toString())) { withContext(Dispatchers.IO) { assetManager diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt index 2b0f617a5e..b117efd2cf 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt @@ -18,7 +18,12 @@ import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.session.MediaControllerCompat import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.PlaybackStateCompat -import com.google.android.exoplayer2.* +import com.google.android.exoplayer2.C +import com.google.android.exoplayer2.ExoPlayer +import com.google.android.exoplayer2.MediaItem +import com.google.android.exoplayer2.PlaybackException +import com.google.android.exoplayer2.PlaybackParameters +import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.audio.AudioAttributes import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator @@ -31,14 +36,23 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSource import java.net.UnknownHostException import kotlin.time.Duration.Companion.seconds import kotlin.time.ExperimentalTime -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.async +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch import org.readium.r2.navigator.ExperimentalAudiobook import org.readium.r2.navigator.R import org.readium.r2.navigator.audio.PublicationDataSource import org.readium.r2.navigator.extensions.timeWithDuration import org.readium.r2.shared.extensions.asInstance -import org.readium.r2.shared.fetcher.Resource -import org.readium.r2.shared.publication.* +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.PublicationId +import org.readium.r2.shared.publication.indexOfFirstWithHref +import org.readium.r2.shared.resource.Resource import timber.log.Timber /** diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaPlayer.kt index dba53f0d02..e1eb17c5b6 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaPlayer.kt @@ -11,11 +11,11 @@ import android.graphics.Bitmap import android.os.Bundle import android.os.ResultReceiver import org.readium.r2.navigator.ExperimentalAudiobook -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.PublicationId +import org.readium.r2.shared.resource.Resource /** * Media player compatible with Android's MediaSession and handling the playback for diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt index 2b7ed5e74b..9f43bb3c2c 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt @@ -27,12 +27,12 @@ import org.readium.r2.navigator.ExperimentalAudiobook import org.readium.r2.navigator.extensions.let import org.readium.r2.navigator.extensions.splitAt import org.readium.r2.navigator.media.extensions.publicationId -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.PublicationId import org.readium.r2.shared.publication.services.cover +import org.readium.r2.shared.resource.Resource import timber.log.Timber /** diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt index 172c30c9ed..fbf95e41a7 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt @@ -80,7 +80,9 @@ class AudioNavigator> if (duration == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val resource = publication.get(link) - duration = MetadataRetriever(resource).duration() + val metadataRetriever = MetadataRetriever(resource) + duration = metadataRetriever.duration() + metadataRetriever.close() } return duration diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt index d3c063ccf4..3815cb0ddb 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt @@ -15,11 +15,12 @@ import java.io.IOException import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.fetcher.Fetcher @RequiresApi(Build.VERSION_CODES.M) internal class MetadataRetriever( - private val resource: Resource + resource: Fetcher.Resource ) { private val retriever: MediaMetadataRetriever = @@ -35,11 +36,11 @@ internal class MetadataRetriever( ?.milliseconds fun close() { - runBlocking { resource.close() } + retriever.close() } class ResourceMediaDataSource( - private val resource: Resource + private val resource: Fetcher.Resource ) : MediaDataSource() { override fun readAt(position: Long, buffer: ByteArray, offset: Int, size: Int): Int { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt index 739fa40017..51ad447912 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt @@ -15,9 +15,11 @@ import androidx.media3.datasource.DataSpec import androidx.media3.datasource.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.buffered import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Resource sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException(message, cause) { class NotOpened(message: String) : ExoPlayerDataSourceException(message, null) @@ -47,7 +49,7 @@ internal class ExoPlayerDataSource internal constructor( } private data class OpenedResource( - val resource: Resource, + val resource: Fetcher.Resource, val uri: Uri, var position: Long, ) @@ -143,8 +145,9 @@ internal class ExoPlayerDataSource internal constructor( if (e !is InterruptedException) { throw e } + } finally { + openedResource = null } } - openedResource = null } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt index 86dd383884..caddfa9d67 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt @@ -13,10 +13,22 @@ import android.view.Surface import android.view.SurfaceHolder import android.view.SurfaceView import android.view.TextureView -import androidx.media3.common.* +import androidx.media3.common.AudioAttributes import androidx.media3.common.C.* +import androidx.media3.common.DeviceInfo +import androidx.media3.common.FlagSet +import androidx.media3.common.IllegalSeekPositionException +import androidx.media3.common.MediaItem +import androidx.media3.common.MediaMetadata +import androidx.media3.common.PlaybackException import androidx.media3.common.PlaybackException.* +import androidx.media3.common.PlaybackParameters +import androidx.media3.common.Player import androidx.media3.common.Player.* +import androidx.media3.common.Timeline +import androidx.media3.common.TrackSelectionParameters +import androidx.media3.common.Tracks +import androidx.media3.common.VideoSize import androidx.media3.common.text.CueGroup import androidx.media3.common.util.Clock import androidx.media3.common.util.ListenerSet @@ -30,7 +42,7 @@ import kotlinx.coroutines.flow.onEach import org.readium.r2.navigator.media3.tts.TtsEngine import org.readium.r2.navigator.media3.tts.TtsPlayer import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.resource.Resource /** * Adapts the [TtsPlayer] to media3 [Player] interface. @@ -876,8 +888,6 @@ internal class TtsSessionAdapter( PlaybackException(exception.message, exception.cause, ERROR_CODE_IO_NETWORK_CONNECTION_FAILED) is Resource.Exception.OutOfMemory -> PlaybackException(exception.message, exception.cause, ERROR_CODE_UNSPECIFIED) - is Resource.Exception.Cancelled -> - PlaybackException(exception.message, exception.cause, ERROR_CODE_IO_UNSPECIFIED) is Resource.Exception.Other -> PlaybackException(exception.message, exception.cause, ERROR_CODE_UNSPECIFIED) else -> diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfEngineProvider.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfEngineProvider.kt index a517691302..addb6e00a7 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfEngineProvider.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfEngineProvider.kt @@ -12,10 +12,10 @@ import org.readium.r2.navigator.VisualNavigator import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.navigator.preferences.PreferencesEditor import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Metadata import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Resource /** * To be implemented by adapters for third-party PDF engines which can be used with [PdfNavigatorFragment]. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt index ad1b78cf81..ac1a4e3144 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt @@ -11,11 +11,22 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.fragment.app.* +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentContainerView +import androidx.fragment.app.FragmentFactory +import androidx.fragment.app.commitNow +import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import org.readium.r2.navigator.R import org.readium.r2.navigator.VisualNavigator @@ -30,12 +41,12 @@ import org.readium.r2.navigator.preferences.ReadingProgression import org.readium.r2.navigator.util.createFragmentFactory import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.extensions.mapStateIn -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.ReadingProgression as PublicationReadingProgression import org.readium.r2.shared.publication.services.isRestricted +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt index df1123cf1f..4a90f1cc60 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt @@ -11,6 +11,7 @@ package org.readium.r2.opds import java.net.URL import org.joda.time.DateTime +import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.toList import org.readium.r2.shared.extensions.toMap import org.readium.r2.shared.opds.* @@ -19,7 +20,6 @@ import org.readium.r2.shared.parser.xml.XmlParser import org.readium.r2.shared.publication.* import org.readium.r2.shared.toJSON import org.readium.r2.shared.util.Href -import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpRequest diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt index 8e5856d50a..39360086cf 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt @@ -13,13 +13,13 @@ import java.net.URL import org.joda.time.DateTime import org.json.JSONArray import org.json.JSONObject +import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.removeLastComponent import org.readium.r2.shared.opds.* import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.util.Href -import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpRequest diff --git a/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt b/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt index 4629b285b6..2d42c4fc21 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt @@ -10,7 +10,7 @@ import android.content.Context import androidx.annotation.PluralsRes import androidx.annotation.StringRes import java.text.DateFormat -import java.util.* +import java.util.Date import org.joda.time.DateTime import org.readium.r2.shared.extensions.asInstance diff --git a/readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt b/readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt new file mode 100644 index 0000000000..2c79a6637b --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.asset + +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * An asset which is either a single resource or a container that holds multiple resources. + */ +sealed class Asset { + + /** + * Name of the asset, e.g. a filename. + */ + abstract val name: String + + /** + * Media type of the asset. + */ + abstract val mediaType: MediaType + + /** + * Type of the asset source. + */ + abstract val assetType: AssetType + + /** + * Releases in-memory resources related to this asset. + */ + abstract suspend fun close() + + /** + * A single resource asset. + * + * @param name Name of the asset. + * @param mediaType Media type of the asset. + * @param resource Opened resource to access the asset. + */ + class Resource( + override val name: String, + override val mediaType: MediaType, + val resource: org.readium.r2.shared.resource.Resource + ) : Asset() { + + override val assetType: AssetType = + AssetType.Resource + + override suspend fun close() { + resource.close() + } + } + + /** + * A container asset providing access to several resources. + * + * @param name Name of the asset. + * @param mediaType Media type of the asset. + * @param exploded If this container is an exploded or packaged container. + * @param container Opened container to access asset resources. + */ + class Container( + override val name: String, + override val mediaType: MediaType, + exploded: Boolean, + val container: org.readium.r2.shared.resource.Container + ) : Asset() { + + override val assetType: AssetType = + if (exploded) + AssetType.Directory + else + AssetType.Archive + + override suspend fun close() { + container.close() + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt new file mode 100644 index 0000000000..a8daa0f188 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt @@ -0,0 +1,356 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.asset + +import android.content.ContentResolver +import android.content.Context +import android.net.Uri +import java.io.File +import org.readium.r2.shared.error.ThrowableError +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.resource.* +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.* +import org.readium.r2.shared.util.toUrl + +class AssetRetriever( + private val resourceFactory: ResourceFactory, + private val containerFactory: ContainerFactory, + private val archiveFactory: ArchiveFactory, + contentResolver: ContentResolver, + sniffers: List +) { + + constructor(context: Context) : this( + resourceFactory = FileResourceFactory(), + containerFactory = DirectoryContainerFactory(), + archiveFactory = DefaultArchiveFactory(), + contentResolver = context.contentResolver, + sniffers = MediaType.sniffers + ) + + sealed class Error : org.readium.r2.shared.error.Error { + + class SchemeNotSupported( + val scheme: String, + override val cause: org.readium.r2.shared.error.Error?, + ) : Error() { + + constructor(scheme: String, exception: Exception) : + this(scheme, ThrowableError(exception)) + + override val message: String = + "Scheme $scheme is not supported." + } + + class NotFound( + val url: Url, + override val cause: org.readium.r2.shared.error.Error? + ) : Error() { + + constructor(url: Url, exception: Exception) : + this(url, ThrowableError(exception)) + + override val message: String = + "Asset could not be found at $url." + } + + class InvalidAsset( + override val cause: org.readium.r2.shared.error.Error? + ) : Error() { + + constructor(exception: Exception) : + this(ThrowableError(exception)) + + override val message: String = + "Asset looks corrupted." + } + + class ArchiveFormatNotSupported( + override val cause: org.readium.r2.shared.error.Error? + ) : Error() { + + constructor(exception: Exception) : + this(ThrowableError(exception)) + + override val message: String = + "Archive factory does not support this kind of archive." + } + + class Forbidden( + val url: Url, + override val cause: org.readium.r2.shared.error.Error + ) : Error() { + + constructor(url: Url, exception: Exception) : + this(url, ThrowableError(exception)) + + override val message: String = + "Access to asset at url $url is forbidden." + } + + class Unavailable( + override val cause: org.readium.r2.shared.error.Error + ) : Error() { + + constructor(exception: Exception) : + this(ThrowableError(exception)) + + override val message: String = + "Asset seems not to be available at the moment." + } + + class OutOfMemory( + error: OutOfMemoryError + ) : Error() { + + override val message: String = + "There is not enough memory on the device to load the asset." + + override val cause: org.readium.r2.shared.error.Error = + ThrowableError(error) + } + + class Unknown( + private val exception: Exception + ) : Error() { + + override val message: String = + exception.message ?: "Something unexpected happened." + + override val cause: org.readium.r2.shared.error.Error = + ThrowableError(exception) + } + } + + /** + * Retrieves an asset from a known media and asset type again. + */ + suspend fun retrieve( + url: Url, + mediaType: MediaType, + assetType: AssetType + ): Try = + when (assetType) { + AssetType.Archive -> + retrieveArchiveAsset(url, mediaType) + AssetType.Directory -> + retrieveDirectoryAsset(url, mediaType) + AssetType.Resource -> + retrieveResourceAsset(url, mediaType) + } + + private suspend fun retrieveArchiveAsset( + url: Url, + mediaType: MediaType + ): Try { + return retrieveResource(url) + .flatMap { resource: Resource -> + archiveFactory.create(resource, password = null) + .mapFailure { error -> + when (error) { + is ArchiveFactory.Error.FormatNotSupported -> + Error.ArchiveFormatNotSupported(error) + is ArchiveFactory.Error.ResourceReading -> + error.resourceException.wrap(url) + is ArchiveFactory.Error.PasswordsNotSupported -> + Error.ArchiveFormatNotSupported(error) + } + } + } + .map { container -> Asset.Container(url.filename, mediaType, false, container) } + } + + private suspend fun retrieveDirectoryAsset( + url: Url, + mediaType: MediaType + ): Try { + return containerFactory.create(url) + .map { container -> + Asset.Container(url.filename, mediaType, true, container) + } + .mapFailure { error -> + when (error) { + is ContainerFactory.Error.NotAContainer -> + Error.NotFound(url, error) + is ContainerFactory.Error.Forbidden -> + Error.Forbidden(url, error) + is ContainerFactory.Error.SchemeNotSupported -> + Error.SchemeNotSupported(error.scheme, error) + } + } + } + + private suspend fun retrieveResourceAsset( + url: Url, + mediaType: MediaType + ): Try { + return retrieveResource(url) + .map { resource -> Asset.Resource(url.filename, mediaType, resource) } + } + + private suspend fun retrieveResource( + url: Url, + ): Try { + return resourceFactory.create(url) + .mapFailure { error -> + when (error) { + is ResourceFactory.Error.NotAResource -> + Error.NotFound(url, error) + is ResourceFactory.Error.Forbidden -> + Error.Forbidden(url, error) + is ResourceFactory.Error.SchemeNotSupported -> + Error.SchemeNotSupported(error.scheme, error) + } + } + } + + private fun Resource.Exception.wrap(url: Url): Error = + when (this) { + is Resource.Exception.Forbidden -> + Error.Forbidden(url, this) + is Resource.Exception.NotFound -> + Error.InvalidAsset(this) + is Resource.Exception.Unavailable, Resource.Exception.Offline -> + Error.Unavailable(this) + is Resource.Exception.OutOfMemory -> + Error.OutOfMemory(cause) + is Resource.Exception.Other -> + Error.Unknown(this) + else -> Error.Unknown(this) + } + + /* Sniff unknown assets */ + + private val snifferContextFactory: UrlSnifferContextFactory = + UrlSnifferContextFactory(resourceFactory, containerFactory, archiveFactory) + + private val mediaTypeRetriever: MediaTypeRetriever = + MediaTypeRetriever(resourceFactory, containerFactory, archiveFactory, contentResolver, sniffers) + + /** + * Retrieves an asset from a local file. + */ + suspend fun retrieve( + file: File, + mediaType: String? = null, + fileExtension: String? = null, + ): Asset? = + retrieve( + file, + mediaTypes = listOfNotNull(mediaType), + fileExtensions = listOfNotNull(fileExtension) + ) + + /** + * Retrieves an asset from a local file. + */ + suspend fun retrieve( + file: File, + mediaTypes: List, + fileExtensions: List, + ): Asset? { + val context = snifferContextFactory + .createContext( + file.toUrl(), + mediaTypes = mediaTypes, + fileExtensions = listOf(file.extension) + fileExtensions + ) ?: return null + + return retrieve(context, file.name) + } + + /** + * Retrieves an asset from an Uri. + */ + suspend fun retrieve( + uri: Uri, + mediaType: String? = null, + fileExtension: String? = null, + ): Asset? = + retrieve( + uri, + mediaTypes = listOfNotNull(mediaType), + fileExtensions = listOfNotNull(fileExtension) + ) + + /** + * Retrieves an asset from a Uri. + */ + suspend fun retrieve( + uri: Uri, + mediaTypes: List, + fileExtensions: List, + ): Asset? { + val url = uri.toUrl() + ?: return null + + return retrieve(url, mediaTypes, fileExtensions) + } + + /** + * Retrieves an asset from a Url. + */ + suspend fun retrieve( + url: Url, + mediaType: String? = null, + fileExtension: String? = null + ): Asset? { + return retrieve(url, listOfNotNull(mediaType), listOfNotNull(fileExtension)) + } + + /** + * Retrieves an asset from a Url. + */ + suspend fun retrieve( + url: Url, + mediaTypes: List, + fileExtensions: List + ): Asset? { + val context = snifferContextFactory + .createContext( + url, + mediaTypes = mediaTypes, + fileExtensions = buildList { + addAll(fileExtensions) + url.extension?.let { add(it) } + } + ) + ?: return null + + return retrieve(context, url.filename) + } + + private suspend fun retrieve( + context: ContentAwareSnifferContext, + fallbackName: String + ): Asset? { + + val mediaType = mediaTypeRetriever.doRetrieve( + fullContext = { context }, + mediaTypes = context.mediaTypes.map(MediaType::toString), + fileExtensions = context.fileExtensions + ) ?: return null + + return when (context) { + is ContainerSnifferContext -> + Asset.Container( + name = context.container.name().getOrNull() ?: fallbackName, + mediaType = mediaType, + exploded = context.isExploded, + container = context.container + ) + is ResourceSnifferContext -> + Asset.Resource( + name = context.resource.name().getOrNull() ?: fallbackName, + mediaType = mediaType, + resource = context.resource + ) + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetType.kt b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetType.kt new file mode 100644 index 0000000000..9e678234b3 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetType.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.asset + +import org.readium.r2.shared.util.MapCompanion + +enum class AssetType(val rawValue: String) { + + /** + * A simple resource. + */ + Resource("resource"), + + /** + * A directory container. + */ + Directory("directory"), + + /** + * An archive container. + */ + Archive("archive"); + + companion object : MapCompanion(values(), AssetType::rawValue) +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt b/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt new file mode 100644 index 0000000000..7ab7005c5e --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.error + +/** + * Describes an error. + */ +interface Error { + + /** + * An error message. + */ + val message: String + + /** + * The cause error or null if there is none. + */ + val cause: Error? +} + +/** + * An error caused by the catch of a throwable. + * + * @param throwable the cause Throwable + */ +class ThrowableError( + val throwable: Throwable +) : Error { + + override val message: String = + throwable.message ?: "Exception" + + override val cause: Error? = + null +} + +/** + * A basic [Error] implementation with a message. + */ +class MessageError( + override val message: String, +) : Error { + + override val cause: Error? = null +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/error/Try.kt b/readium/shared/src/main/java/org/readium/r2/shared/error/Try.kt new file mode 100644 index 0000000000..c20b8f444c --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/error/Try.kt @@ -0,0 +1,139 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.error + +/** A [Result] type which can be used as a return type. */ +sealed class Try { + + companion object { + /** Returns an instance that encapsulates the given value as successful value. */ + fun success(success: Success): Try = Success(success) + + /** Returns the encapsulated Throwable exception if this instance represents failure or null if it is success. */ + fun failure(failure: Failure): Try = Failure(failure) + } + + abstract val isSuccess: Boolean + abstract val isFailure: Boolean + + /** Returns the encapsulated value if this instance represents success or null if it is failure. */ + abstract fun getOrNull(): Success? + + /** Returns the encapsulated [Throwable] exception if this instance represents failure or null if it is success. */ + abstract fun failureOrNull(): Failure? + + class Success(val value: S) : Try() { + override val isSuccess: Boolean get() = true + override val isFailure: Boolean get() = false + override fun getOrNull(): S? = value + override fun failureOrNull(): F? = null + } + + class Failure(val value: F) : Try() { + override val isSuccess: Boolean get() = false + override val isFailure: Boolean get() = true + override fun getOrNull(): S? = null + override fun failureOrNull(): F = value + } + + /** + * Returns the encapsulated result of the given transform function applied to the encapsulated value + * if this instance represents success or the original encapsulated [Throwable] exception if it is failure. + */ + inline fun map(transform: (value: Success) -> R): Try = + when (this) { + is Try.Success -> success(transform(value)) + is Try.Failure -> failure(value) + } + + /** + * Returns the encapsulated result of the given transform function applied to the encapsulated failure + * if this instance represents failure or the original encapsulated success value if it is a success. + */ + inline fun mapFailure(transform: (value: Failure) -> F): Try = + when (this) { + is Try.Success -> success(value) + is Try.Failure -> failure(transform(failureOrNull()!!)) + } + + /** + * Returns the result of [onSuccess] for the encapsulated value if this instance represents success or + * the result of [onFailure] function for the encapsulated value if it is failure. + */ + inline fun fold(onSuccess: (value: Success) -> R, onFailure: (exception: Failure) -> R): R = + when (this) { + is Try.Success -> onSuccess(value) + is Try.Failure -> onFailure(failureOrNull()!!) + } + + /** + * Performs the given action on the encapsulated value if this instance represents success. + * Returns the original [Try] unchanged. + */ + inline fun onSuccess(action: (value: Success) -> Unit): Try { + if (this is Try.Success) action(value) + return this + } + + /** + * Performs the given action on the encapsulated value if this instance represents failure. + * Returns the original [Try] unchanged. + */ + inline fun onFailure(action: (exception: Failure) -> Unit): Try { + if (this is Try.Failure) action(failureOrNull()!!) + return this + } +} + +/** + * Returns the encapsulated value if this instance represents success + * or throws the encapsulated Throwable exception if it is failure. + */ +fun Try.getOrThrow(): S = + when (this) { + is Try.Success -> value + is Try.Failure -> throw value + } + +/** + * Returns the encapsulated value if this instance represents success or the [defaultValue] if it is failure. + */ +fun Try.getOrDefault(defaultValue: R): R = + when (this) { + is Try.Success -> value + is Try.Failure -> defaultValue + } + +/** + * Returns the encapsulated value if this instance represents success or the result of [onFailure] function + * for the encapsulated value if it is failure. + */ +inline fun Try.getOrElse(onFailure: (exception: F) -> R): R = + when (this) { + is Try.Success -> value + is Try.Failure -> onFailure(value) + } + +/** + * Returns the encapsulated result of the given transform function applied to the encapsulated + * value if this instance represents success or the original encapsulated value if it is failure. + */ +inline fun Try.flatMap(transform: (value: S) -> Try): Try = + when (this) { + is Try.Success -> transform(value) + is Try.Failure -> Try.failure(value) + } + +/** + * Returns the encapsulated result of the given transform function applied to the encapsulated value + * if this instance represents failure or the original encapsulated value if it is success. + */ +inline fun Try.tryRecover(transform: (exception: F) -> Try): Try = + when (this) { + is Try.Success -> Try.success(value) + is Try.Failure -> transform(value) + } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt index 674043168f..88831e7826 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt @@ -13,6 +13,7 @@ import java.io.File import java.io.FileInputStream import java.security.MessageDigest import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber /** @@ -64,5 +65,6 @@ fun File.isParentOf(other: File): Boolean { * * If unknown, fallback on `MediaType.BINARY`. */ +@Deprecated("Explicitly use MediaTypeRetriever", level = DeprecationLevel.ERROR) suspend fun File.mediaType(mediaTypeHint: String? = null): MediaType = - MediaType.ofFile(this, mediaType = mediaTypeHint) ?: MediaType.BINARY + MediaTypeRetriever().retrieve(this, mediaType = mediaTypeHint) ?: MediaType.BINARY diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt deleted file mode 100644 index cbf4991165..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ArchiveFetcher.kt +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.fetcher - -import java.io.File -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.readium.r2.shared.extensions.addPrefix -import org.readium.r2.shared.extensions.tryOr -import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Properties -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.archive.Archive -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.archive.DefaultArchiveFactory -import org.readium.r2.shared.util.mediatype.MediaType -import timber.log.Timber - -/** Provides access to entries of an archive. */ -class ArchiveFetcher private constructor(private val archive: Archive) : Fetcher { - - override suspend fun links(): List = - tryOr(emptyList()) { archive.entries() } - .map { it.toLink() } - - override fun get(link: Link): Resource = - EntryResource(link, archive) - - override suspend fun close() = withContext(Dispatchers.IO) { - try { - archive.close() - } catch (e: Exception) { - Timber.e(e) - } - } - - companion object { - - suspend fun fromPath(path: String, archiveFactory: ArchiveFactory = DefaultArchiveFactory()): ArchiveFetcher? = - withContext(Dispatchers.IO) { - tryOrNull { ArchiveFetcher(archiveFactory.open(File(path), password = null)) } - } - - suspend fun fromUrl(url: Url, archiveFactory: ArchiveFactory = DefaultArchiveFactory()): ArchiveFetcher? = - withContext(Dispatchers.IO) { - tryOrNull { ArchiveFetcher(archiveFactory.open(url, password = null)) } - } - } - - private class EntryResource(val originalLink: Link, val archive: Archive) : Resource { - - private lateinit var _entry: ResourceTry - - suspend fun entry(): ResourceTry { - if (!::_entry.isInitialized) { - _entry = try { - Try.success(findEntry(originalLink)) - } catch (e: Exception) { - Try.failure(Resource.Exception.NotFound(e)) - } - } - - return _entry - } - - suspend fun findEntry(link: Link): Archive.Entry { - val href = link.href.removePrefix("/") - return try { - archive.entry(href) - } catch (e: Exception) { - // Try again after removing query parameters and anchors from the href. - archive.entry(href.takeWhile { it !in "#?" }) - } - } - - override suspend fun link(): Link { - val entry = entry().getOrNull() ?: return originalLink - return originalLink.addProperties(entry.toLinkProperties()) - } - - override suspend fun read(range: LongRange?): ResourceTry = - entry().mapCatching { - it.read(range) - } - - override suspend fun length(): ResourceTry = - metadataLength()?.let { Try.success(it) } - ?: read().map { it.size.toLong() } - - override suspend fun close() { - if (::_entry.isInitialized) { - _entry.onSuccess { it.close() } - } - } - - private suspend fun metadataLength(): Long? = - entry().getOrNull()?.length - - override fun toString(): String = - "${javaClass.simpleName}(${archive::class.java.simpleName}, ${originalLink.href})" - } -} - -private suspend fun Archive.Entry.toLink(): Link { - return Link( - href = path.addPrefix("/"), - type = MediaType.of(fileExtension = File(path).extension)?.toString(), - properties = Properties(toLinkProperties()) - ) -} - -private fun Archive.Entry.toLinkProperties(): Map { - val properties = mutableMapOf( - "archive" to mapOf( - "entryLength" to (compressedLength ?: length ?: 0), - "isEntryCompressed" to (compressedLength != null) - ) - ) - - compressedLength?.let { - // FIXME: Legacy property, should be removed in 3.0.0 - properties["compressedLength"] = it - } - - return properties -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt index c0998838af..a2c8654237 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt @@ -1,65 +1,51 @@ /* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ - package org.readium.r2.shared.fetcher import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.extensions.coerceIn -import org.readium.r2.shared.extensions.requireLengthFitInt +import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.util.Try - -sealed class BaseBytesResource(val link: Link, val bytes: suspend () -> ByteArray) : Resource { - - private lateinit var _bytes: ByteArray - - override suspend fun link(): Link = link +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry - override suspend fun read(range: LongRange?): ResourceTry { - try { - if (!::_bytes.isInitialized) - _bytes = bytes() +sealed class BaseBytesResource( + private val link: Link, + protected val resource: org.readium.r2.shared.resource.BytesResource +) : Resource by resource, Fetcher.Resource { - if (range == null) - return Try.success(_bytes) + constructor(link: Link, bytes: suspend () -> ResourceTry) : + this(link, org.readium.r2.shared.resource.BytesResource(bytes)) - @Suppress("NAME_SHADOWING") - val range = range - .coerceIn(0L until _bytes.size) - .requireLengthFitInt() + constructor(link: Link, bytes: ByteArray) : + this(link, { Try.success(bytes) }) - return Try.success(_bytes.sliceArray(range.map(Long::toInt))) - } catch (e: Exception) { - return Try.failure(Resource.Exception.wrap(e)) - } - } + override suspend fun link(): Link = + link - override suspend fun length(): ResourceTry = - read().map { it.size.toLong() } - - override suspend fun close() {} + override fun toString(): String = + "${javaClass.simpleName}(${runBlocking { length().getOrNull() }} bytes)" } /** Creates a Resource serving [ByteArray]. */ -class BytesResource(link: Link, bytes: suspend () -> ByteArray) : BaseBytesResource(link, bytes) { +class BytesResource( + link: Link, + bytes: suspend () -> ByteArray +) : BaseBytesResource(link, { Try.success(bytes()) }) { constructor(link: Link, bytes: ByteArray) : this(link, { bytes }) - - override fun toString(): String = - "${javaClass.simpleName}(${runBlocking { bytes().size }} bytes)" } /** Creates a Resource serving a [String]. */ -class StringResource(link: Link, string: suspend () -> String) : BaseBytesResource(link, { string().toByteArray() }) { +class StringResource( + link: Link, + string: suspend () -> String +) : BaseBytesResource(link, { Try.success(string()).map { it.toByteArray() } }) { constructor(link: Link, string: String) : this(link, { string }) override fun toString(): String = - "${javaClass.simpleName}(${runBlocking { bytes().toString() }})" + "${javaClass.simpleName}(${runBlocking { resource.bytes().map { it.toString() } } })" } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt new file mode 100644 index 0000000000..62a0bde77d --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt @@ -0,0 +1,99 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.fetcher + +import java.io.File +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrDefault +import org.readium.r2.shared.error.tryRecover +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Properties +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.ZipContainer +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.util.use + +/** Provides access to entries of a [Container]. */ +class ContainerFetcher( + private val container: Container, + private val mediaTypeRetriever: MediaTypeRetriever +) : Fetcher { + + override suspend fun links(): List = + container.entries() + ?.map { it.toLink(mediaTypeRetriever) } + ?: emptyList() + + override fun get(link: Link): Fetcher.Resource = + EntryResource(link, container) + + override suspend fun close() = + container.close() + + private class EntryResource( + val originalLink: Link, + val container: Container + ) : Fetcher.Resource { + + override suspend fun link(): Link = + withEntry { entry -> + val enhancedLink = (entry as? ZipContainer.Entry) + ?.let { originalLink.addProperties(entry.toLinkProperties()) } + ?: originalLink + + Try.success(enhancedLink) + }.getOrDefault(originalLink) + + override suspend fun read(range: LongRange?): ResourceTry = + withEntry { entry -> entry.read(range) } + + override suspend fun length(): ResourceTry = + metadataLength() + .tryRecover { read().map { it.size.toLong() } } + + override suspend fun close() { + } + + private suspend fun metadataLength(): ResourceTry = + withEntry { entry -> entry.length() } + + suspend fun withEntry(block: suspend (Container.Entry) -> ResourceTry): ResourceTry = + originalLink.href + .let { href -> container.entry(href) } + .let { entry -> entry.use { block(entry) } } + .takeIf { result -> result.failureOrNull() !is Resource.Exception.NotFound } + ?: run { + // Try again after removing query and fragment. + originalLink.href + .takeWhile { it !in "#?" } + .let { href -> container.entry(href) } + .let { entry -> entry.use { block(entry) } } + } + + override fun toString(): String = + "${javaClass.simpleName}(${container::class.java.simpleName}, ${originalLink.href})" + } +} + +private suspend fun Container.Entry.toLink(mediaTypeRetriever: MediaTypeRetriever): Link { + return Link( + href = path, + type = mediaTypeRetriever.retrieve(fileExtension = File(path).extension)?.toString(), + properties = Properties((this as? ZipContainer.Entry)?.toLinkProperties().orEmpty()) + ) +} + +private suspend fun ZipContainer.Entry.toLinkProperties(): Map { + return mutableMapOf( + "archive" to mapOf( + "entryLength" to (compressedLength ?: length().getOrNull() ?: 0), + "isEntryCompressed" to (compressedLength != null) + ) + ) +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt index 1c22fad46c..bd918c12e4 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt @@ -1,20 +1,34 @@ /* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.shared.fetcher +import java.io.File +import org.readium.r2.shared.fetcher.Fetcher.Resource import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.util.SuspendingCloseable /** Provides access to a [Resource] from a [Link]. */ interface Fetcher : SuspendingCloseable { + /** + * Acts as a proxy to an actual resource by handling read access. + */ + interface Resource : org.readium.r2.shared.resource.Resource { + + /** + * Returns the link from which the resource was retrieved. + * + * It might be modified by the [Resource] to include additional metadata, e.g. the + * `Content-Type` HTTP header in [Link.type]. + */ + suspend fun link(): Link + } + /** * Known resources available in the medium, such as file paths on the file system * or entries in a ZIP archive. This list is not exhaustive, and additional @@ -44,9 +58,62 @@ interface Fetcher : SuspendingCloseable { /** A [Fetcher] providing no resources at all. */ class EmptyFetcher : Fetcher { - override suspend fun links(): List = emptyList() + override suspend fun links(): List = + emptyList() - override fun get(link: Link): Resource = FailureResource(link, Resource.Exception.NotFound()) + override fun get(link: Link): Resource = + FailureResource(link, org.readium.r2.shared.resource.Resource.Exception.NotFound()) override suspend fun close() {} } + +class ResourceFetcher( + private val link: Link, + private val resource: org.readium.r2.shared.resource.Resource +) : Fetcher { + + companion object { + + suspend operator fun invoke(resource: Resource): ResourceFetcher { + val link = resource.link() + return ResourceFetcher(link, resource) + } + } + + class Resource( + private val link: Link, + private val resource: org.readium.r2.shared.resource.Resource + ) : Fetcher.Resource { + + override val file: File? = + resource.file + + override suspend fun link() = + link + + override suspend fun length(): ResourceTry = + resource.length() + + override suspend fun read(range: LongRange?): ResourceTry = + resource.read(range) + + override suspend fun close() { + } + } + + override suspend fun links(): List = + listOf(link) + + override fun get(link: Link): Fetcher.Resource { + if (link.href.takeWhile { it !in "#?" } != this.link.href) { + val exception = org.readium.r2.shared.resource.Resource.Exception.NotFound() + return FailureResource(link, exception) + } + + return Resource(link, resource) + } + + override suspend fun close() { + resource.close() + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt index d2c2f50651..7133e5c086 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt @@ -10,19 +10,12 @@ package org.readium.r2.shared.fetcher import java.io.File -import java.io.FileNotFoundException -import java.io.RandomAccessFile import java.lang.ref.WeakReference -import java.nio.channels.Channels import java.util.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import org.readium.r2.shared.extensions.* import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.isLazyInitialized -import org.readium.r2.shared.util.mediatype.MediaType -import timber.log.Timber +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Provides access to resources on the local file system. @@ -30,12 +23,16 @@ import timber.log.Timber * [paths] contains the reachable local paths, indexed by the exposed HREF. Sub-paths are reachable * as well, to be able to access a whole directory. */ -class FileFetcher(private val paths: Map) : Fetcher { +class FileFetcher( + private val paths: Map, + private val mediaTypeRetriever: MediaTypeRetriever +) : Fetcher { /** Provides access to the given local [file] at [href]. */ - constructor(href: String, file: File) : this(mapOf(href to file)) + constructor(href: String, file: File, mediaTypeRetriever: MediaTypeRetriever) : + this(mapOf(href to file), mediaTypeRetriever) - private val openedResources: MutableList> = LinkedList() + private val openedResources: MutableList> = LinkedList() override suspend fun links(): List = paths.toSortedMap().flatMap { (href, file) -> @@ -46,14 +43,14 @@ class FileFetcher(private val paths: Map) : Fetcher { } else { Link( href = File(href, it.canonicalPath.removePrefix(file.canonicalPath)).canonicalPath, - type = MediaType.ofFile(file, fileExtension = it.extension)?.toString() + type = mediaTypeRetriever.retrieve(it)?.toString() ) } } } } - override fun get(link: Link): Resource { + override fun get(link: Link): Fetcher.Resource { val linkHref = link.href.addPrefix("/") for ((itemHref, itemFile) in paths) { @Suppress("NAME_SHADOWING") @@ -72,93 +69,23 @@ class FileFetcher(private val paths: Map) : Fetcher { } override suspend fun close() { - openedResources.mapNotNull(WeakReference::get).forEach { it.close() } + openedResources.mapNotNull(WeakReference::get).forEach { it.close() } openedResources.clear() } - class FileResource(val link: Link, override val file: File) : Resource { + class FileResource(val link: Link, val resource: org.readium.r2.shared.resource.FileResource) : + Resource by resource, Fetcher.Resource { - private val randomAccessFile by lazy { - ResourceTry.catching { - RandomAccessFile(file, "r") - } - } - - override suspend fun link(): Link = link - - override suspend fun close() = withContext(Dispatchers.IO) { - if (::randomAccessFile.isLazyInitialized) { - randomAccessFile.onSuccess { - try { - it.close() - } catch (e: java.lang.Exception) { - Timber.e(e) - } - } - } - } - - override suspend fun read(range: LongRange?): ResourceTry = - withContext(Dispatchers.IO) { - ResourceTry.catching { - readSync(range) - } - } - - private fun readSync(range: LongRange?): ByteArray { - if (range == null) { - return file.readBytes() - } - - @Suppress("NAME_SHADOWING") - val range = range - .coerceFirstNonNegative() - .requireLengthFitInt() - - if (range.isEmpty()) { - return ByteArray(0) - } - - return randomAccessFile.getOrThrow().run { - channel.position(range.first) + companion object { - // The stream must not be closed here because it would close the underlying - // [FileChannel] too. Instead, [close] is responsible for that. - Channels.newInputStream(channel).run { - val length = range.last - range.first + 1 - read(length) - } - } + operator fun invoke(link: Link, file: File): FileResource = + FileResource(link, org.readium.r2.shared.resource.FileResource(file)) } - override suspend fun length(): ResourceTry = - metadataLength?.let { Try.success(it) } - ?: read().map { it.size.toLong() } - - private val metadataLength: Long? = - try { - if (file.isFile) - file.length() - else - null - } catch (e: Exception) { - null - } - - private inline fun Try.Companion.catching(closure: () -> T): ResourceTry = - try { - success(closure()) - } catch (e: FileNotFoundException) { - failure(Resource.Exception.NotFound(e)) - } catch (e: SecurityException) { - failure(Resource.Exception.Forbidden(e)) - } catch (e: Exception) { - failure(Resource.Exception.wrap(e)) - } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. - failure(Resource.Exception.wrap(e)) - } + override suspend fun link(): Link = + link override fun toString(): String = - "${javaClass.simpleName}(${file.path})" + "${javaClass.simpleName}(${resource.file.path})" } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt deleted file mode 100644 index c6f28e5d7a..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/HttpFetcher.kt +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2021 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.fetcher - -import android.webkit.URLUtil -import java.io.InputStream -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.readium.r2.shared.extensions.read -import org.readium.r2.shared.extensions.tryOrLog -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap -import org.readium.r2.shared.util.http.HttpClient -import org.readium.r2.shared.util.http.HttpException -import org.readium.r2.shared.util.http.HttpException.Kind -import org.readium.r2.shared.util.http.HttpRequest -import org.readium.r2.shared.util.http.HttpRequest.Method -import org.readium.r2.shared.util.http.HttpResponse -import org.readium.r2.shared.util.io.CountingInputStream -import timber.log.Timber - -/** - * Fetches remote resources through HTTP. - * - * Since this fetcher is used when doing progressive download streaming (e.g. audiobook), the HTTP - * byte range requests are open-ended and reused. This helps to avoid issuing too many requests. - * - * @param client HTTP client used to perform HTTP requests. - * @param baseUrl Base URL from which relative HREF are served. - * @param links A set of links that are known to be available through this fetcher. - */ -class HttpFetcher( - private val client: HttpClient, - private val baseUrl: String? = null, - private val links: List = emptyList(), -) : Fetcher { - - override suspend fun links(): List = links - - override fun get(link: Link): Resource { - val url = link.toUrl(baseUrl) - - return if (url == null || !URLUtil.isNetworkUrl(url)) { - val cause = IllegalArgumentException("Invalid HREF: ${link.href}, produced URL: $url") - Timber.e(cause) - FailureResource(link, error = Resource.Exception.BadRequest(cause = cause)) - } else { - HttpResource(client, link, url, MAX_SKIP_BYTES) - } - } - - override suspend fun close() {} - - /** Provides access to an external URL. */ - private class HttpResource( - private val client: HttpClient, - private val link: Link, - private val url: String, - private val maxSkipBytes: Long - ) : Resource { - - override suspend fun link(): Link = - headResponse() - .map { link.copy(type = it.mediaType.toString()) } - .getOrNull() ?: link - - override suspend fun length(): ResourceTry = - headResponse().flatMap { - val contentLength = it.contentLength - return if (contentLength != null) { - Try.success(contentLength) - } else { - Try.failure(Resource.Exception.Unavailable()) - } - } - - override suspend fun close() {} - - override suspend fun read(range: LongRange?): ResourceTry = withContext(Dispatchers.IO) { - try { - stream(range?.first).map { stream -> - if (range != null) { - stream.read(range.count().toLong()) - } else { - stream.readBytes() - } - } - } catch (e: HttpException) { - Try.failure(Resource.Exception.wrapHttp(e)) - } catch (e: Exception) { - Try.failure(Resource.Exception.wrap(e)) - } - } - - /** Cached HEAD response to get the expected content length and other metadata. */ - private lateinit var _headResponse: ResourceTry - - private suspend fun headResponse(): ResourceTry { - if (::_headResponse.isInitialized) - return _headResponse - - _headResponse = client.fetch(HttpRequest(url, method = Method.HEAD)) - .map { it.response } - .mapFailure { Resource.Exception.wrapHttp(it) } - - return _headResponse - } - - /** - * Returns an HTTP stream for the resource, starting at the [from] byte offset. - * - * The stream is cached and reused for next calls, if the next [from] offset is not too far - * and in a forward direction. - */ - private suspend fun stream(from: Long? = null): ResourceTry { - val stream = inputStream - if (from != null && stream != null) { - tryOrLog { - val bytesToSkip = from - (inputStreamStart + stream.count) - if (bytesToSkip in 0 until maxSkipBytes) { - stream.skip(bytesToSkip) - return Try.success(stream) - } - } - } - tryOrLog { inputStream?.close() } - - val request = HttpRequest(url) { - from?.let { setRange(from..-1) } - } - - return client.stream(request) - .fold( - { response -> - if (response.response.statusCode == 206) { - Try.success(response) - } else { - val exception = Exception("Server seems not to support range requests.") - Try.failure(HttpException.wrap(exception)) - } - }, - { exception -> - Try.failure(exception) - } - ) - .map { CountingInputStream(it.body) } - .mapFailure { Resource.Exception.wrapHttp(it) } - .onSuccess { - inputStream = it - inputStreamStart = from ?: 0 - } - } - - private var inputStream: CountingInputStream? = null - private var inputStreamStart = 0L - - private fun Resource.Exception.Companion.wrapHttp(e: HttpException): Resource.Exception = - when (e.kind) { - Kind.MalformedRequest, Kind.BadRequest -> - Resource.Exception.BadRequest(cause = e) - Kind.Timeout, Kind.Offline -> - Resource.Exception.Unavailable(e) - Kind.Unauthorized, Kind.Forbidden -> - Resource.Exception.Forbidden(e) - Kind.NotFound -> - Resource.Exception.NotFound(e) - Kind.Cancelled -> - Resource.Exception.Cancelled - Kind.MalformedResponse, Kind.ClientError, Kind.ServerError, Kind.Other -> - Resource.Exception.Other(e) - } - } - - companion object { - - private const val MAX_SKIP_BYTES: Long = 8192 - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt index 0f95ec36f2..50fa83e464 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt @@ -1,37 +1,23 @@ /* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.shared.fetcher -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import androidx.annotation.StringRes -import java.io.ByteArrayInputStream import java.io.File -import java.nio.charset.Charset import kotlinx.coroutines.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import org.json.JSONObject -import org.readium.r2.shared.R -import org.readium.r2.shared.UserException +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.extensions.coerceIn import org.readium.r2.shared.extensions.contains import org.readium.r2.shared.extensions.requireLengthFitInt -import org.readium.r2.shared.parser.xml.ElementNode -import org.readium.r2.shared.parser.xml.XmlParser import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.util.SuspendingCloseable -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap - -typealias ResourceTry = Try +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry /** * Implements the transformation of a Resource. It can be used, for example, to decrypt, @@ -40,160 +26,11 @@ typealias ResourceTry = Try * * If the transformation doesn't apply, simply return resource unchanged. */ -typealias ResourceTransformer = (Resource) -> Resource - -/** - * Acts as a proxy to an actual resource by handling read access. - */ -interface Resource : SuspendingCloseable { - - /** - * Direct file to this resource, when available. - * - * This is meant to be used as an optimization for consumers which can't work efficiently - * with streams. However, [file] is not guaranteed to be set, for example if the resource - * underwent transformations or is being read from an archive. Therefore, consumers should - * always fallback on regular stream reading, using [read] or [ResourceInputStream]. - */ - val file: File? get() = null - - /** - * Returns the link from which the resource was retrieved. - * - * It might be modified by the [Resource] to include additional metadata, e.g. the - * `Content-Type` HTTP header in [Link.type]. - */ - suspend fun link(): Link - - /** - * Returns data length from metadata if available, or calculated from reading the bytes otherwise. - * - * This value must be treated as a hint, as it might not reflect the actual bytes length. To get - * the real length, you need to read the whole resource. - */ - suspend fun length(): ResourceTry - - /** - * Reads the bytes at the given range. - * - * When [range] is null, the whole content is returned. Out-of-range indexes are clamped to the - * available length automatically. - */ - suspend fun read(range: LongRange? = null): ResourceTry - - /** - * Reads the full content as a [String]. - * - * If [charset] is null, then it is parsed from the `charset` parameter of link().type, - * or falls back on UTF-8. - */ - suspend fun readAsString(charset: Charset? = null): ResourceTry = - read().mapCatching { - String(it, charset = charset ?: link().mediaType.charset ?: Charsets.UTF_8) - } - - /** - * Reads the full content as a JSON object. - */ - suspend fun readAsJson(): ResourceTry = - readAsString(charset = Charsets.UTF_8).mapCatching { JSONObject(it) } - - /** - * Reads the full content as an XML document. - */ - suspend fun readAsXml(): ResourceTry = - read().mapCatching { XmlParser().parse(ByteArrayInputStream(it)) } - - /** - * Reads the full content as a [Bitmap]. - */ - suspend fun readAsBitmap(): ResourceTry = - read().mapCatching { - BitmapFactory.decodeByteArray(it, 0, it.size) - ?: throw kotlin.Exception("Could not decode resource ${link().href} as a bitmap") - } - - companion object { - /** - * Creates a cached resource wrapping this resource. - */ - @Deprecated( - "If you were caching a TransformingResource, build it with cacheBytes set to true." + - "Otherwise, please report your use case.", - level = DeprecationLevel.ERROR - ) - fun Resource.cached(): Resource = this - } - - /** - * Errors occurring while accessing a resource. - */ - sealed class Exception(@StringRes userMessageId: Int, cause: Throwable? = null) : UserException(userMessageId, cause = cause) { - - /** Equivalent to a 400 HTTP error. */ - class BadRequest(val parameters: Map = emptyMap(), cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_bad_request, cause) - - /** Equivalent to a 404 HTTP error. */ - class NotFound(cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_not_found, cause) - - /** - * Equivalent to a 403 HTTP error. - * - * This can be returned when trying to read a resource protected with a DRM that is not - * unlocked. - */ - class Forbidden(cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_forbidden, cause) - - /** - * Equivalent to a 503 HTTP error. - * - * Used when the source can't be reached, e.g. no Internet connection, or an issue with the - * file system. Usually this is a temporary error. - */ - class Unavailable(cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_unavailable, cause) - - /** - * The Internet connection appears to be offline. - */ - object Offline : Exception(R.string.r2_shared_resource_exception_offline) - - /** - * Equivalent to a 507 HTTP error. - * - * Used when the requested range is too large to be read in memory. - */ - class OutOfMemory(cause: OutOfMemoryError) : - Exception(R.string.r2_shared_resource_exception_out_of_memory, cause) - - /** - * The request was cancelled by the caller. - * - * For example, when a coroutine is cancelled. - */ - object Cancelled : Exception(R.string.r2_shared_resource_exception_cancelled) - - /** For any other error, such as HTTP 500. */ - class Other(cause: Throwable) : Exception(R.string.r2_shared_resource_exception_other, cause) - - companion object { - - fun wrap(e: Throwable): Exception = - when (e) { - is Resource.Exception -> e - is CancellationException -> Cancelled - is OutOfMemoryError -> OutOfMemory(e) - else -> Other(e) - } - } - } -} +typealias ResourceTransformer = (Fetcher.Resource) -> Fetcher.Resource /** Creates a Resource that will always return the given [error]. */ -class FailureResource(private val link: Link, private val error: Resource.Exception) : Resource { +class FailureResource(private val link: Link, private val error: Resource.Exception) : + Fetcher.Resource { internal constructor(link: Link, cause: Throwable) : this(link, Resource.Exception.Other(cause)) @@ -213,18 +50,19 @@ class FailureResource(private val link: Link, private val error: Resource.Except * Resource that will act as a proxy to a fallback resource if the [originalResource] errors out. */ class FallbackResource( - private val originalResource: Resource, - private val fallbackResourceFactory: (Resource.Exception) -> Resource -) : Resource { + private val originalResource: Fetcher.Resource, + private val fallbackResourceFactory: (Resource.Exception) -> Fetcher.Resource +) : Fetcher.Resource { private val coroutineScope = CoroutineScope(Dispatchers.Default) - private val resource: Deferred = coroutineScope.async { - when (val result = originalResource.length()) { - is Try.Success -> originalResource - is Try.Failure -> fallbackResourceFactory(result.exception) + private val resource: Deferred = + coroutineScope.async { + when (val result = originalResource.length()) { + is Try.Success -> originalResource + is Try.Failure -> fallbackResourceFactory(result.value) + } } - } override suspend fun link(): Link = resource.await().link() @@ -247,13 +85,13 @@ class FallbackResource( /** * Falls back to alternative resources when the receiver fails. */ -fun Resource.fallback(fallbackResourceFactory: (Resource.Exception) -> Resource): Resource = +fun Fetcher.Resource.fallback(fallbackResourceFactory: (Resource.Exception) -> Fetcher.Resource): Fetcher.Resource = FallbackResource(this, fallbackResourceFactory) /** - * Falls back to the given alternative [resource] when the receiver fails. + * Falls back to the given alternative [Fetcher.Resource] when the receiver fails. */ -fun Resource.fallback(fallbackResource: Resource): Resource = +fun Fetcher.Resource.fallback(fallbackResource: Fetcher.Resource): Fetcher.Resource = FallbackResource(this) { fallbackResource } /** @@ -261,7 +99,9 @@ fun Resource.fallback(fallbackResource: Resource): Resource = * * Every function is delegating to the proxied resource, and subclasses should override some of them. */ -abstract class ProxyResource(protected val resource: Resource) : Resource { +abstract class ProxyResource(protected val resource: Fetcher.Resource) : Fetcher.Resource { + + override val file: File? = resource.file override suspend fun link(): Link = resource.link() @@ -271,8 +111,6 @@ abstract class ProxyResource(protected val resource: Resource) : Resource { override suspend fun close() = resource.close() - override val file: File? get() = resource.file - override fun toString(): String = "${javaClass.simpleName}($resource)" } @@ -287,7 +125,7 @@ abstract class ProxyResource(protected val resource: Resource) : Resource { * large resources which can't be held in memory. */ abstract class TransformingResource( - resource: Resource, + resource: Fetcher.Resource, private val cacheBytes: Boolean = true ) : ProxyResource(resource) { @@ -295,7 +133,7 @@ abstract class TransformingResource( /** * Creates a [TransformingResource] using the given [transform] function. */ - operator fun invoke(resource: Resource, transform: suspend (ByteArray) -> ByteArray): TransformingResource = + operator fun invoke(resource: Fetcher.Resource, transform: suspend (ByteArray) -> ByteArray): TransformingResource = object : TransformingResource(resource) { override suspend fun transform(data: ResourceTry): ResourceTry = data.mapCatching { transform(it) } @@ -334,24 +172,27 @@ abstract class TransformingResource( } /** - * Wraps a [Resource] which will be created only when first accessing one of its members. + * Wraps a [Fetcher.Resource] which will be created only when first accessing one of its members. */ -class LazyResource(private val factory: suspend () -> Resource) : Resource { +class LazyResource(private val factory: suspend () -> Fetcher.Resource) : Fetcher.Resource { - private lateinit var _resource: Resource + private lateinit var _resource: Fetcher.Resource - private suspend fun resource(): Resource { + private suspend fun resource(): Fetcher.Resource { if (!::_resource.isInitialized) _resource = factory() return _resource } - override suspend fun link(): Link = resource().link() + override suspend fun link(): Link = + resource().link() - override suspend fun length(): ResourceTry = resource().length() + override suspend fun length(): ResourceTry = + resource().length() - override suspend fun read(range: LongRange?): ResourceTry = resource().read(range) + override suspend fun read(range: LongRange?): ResourceTry = + resource().read(range) override suspend fun close() { if (::_resource.isInitialized) @@ -372,11 +213,14 @@ class LazyResource(private val factory: suspend () -> Resource) : Resource { * This doesn't implement [ProxyResource] to avoid forgetting the synchronization for a future API. */ class SynchronizedResource( - private val resource: Resource -) : Resource { + private val resource: Fetcher.Resource +) : Fetcher.Resource { private val mutex = Mutex() + override val file: File? = + resource.file + override suspend fun link(): Link = mutex.withLock { resource.link() } @@ -389,9 +233,6 @@ class SynchronizedResource( override suspend fun close() = mutex.withLock { resource.close() } - override val file: File? get() = - resource.file - override fun toString(): String = "${javaClass.simpleName}($resource)" } @@ -399,7 +240,7 @@ class SynchronizedResource( /** * Wraps this resource in a [SynchronizedResource] to protect the access from multiple threads. */ -fun Resource.synchronized(): SynchronizedResource = +fun Fetcher.Resource.synchronized(): SynchronizedResource = SynchronizedResource(this) /** @@ -420,7 +261,7 @@ fun Resource.synchronized(): SynchronizedResource = * @param bufferSize Size of the buffer chunks to read. */ class BufferingResource( - resource: Resource, + resource: Fetcher.Resource, resourceLength: Long? = null, private val bufferSize: Long = DEFAULT_BUFFER_SIZE, ) : ProxyResource(resource) { @@ -537,9 +378,9 @@ class BufferingResource( * * @param resourceLength The total length of the resource, when known. This can improve performance * by avoiding requesting the length from the underlying resource. - * @param bufferSize Size of the buffer chunks to read. + * @param size Size of the buffer chunks to read. */ -fun Resource.buffered( +fun Fetcher.Resource.buffered( resourceLength: Long? = null, size: Long = BufferingResource.DEFAULT_BUFFER_SIZE ) = @@ -552,7 +393,7 @@ fun Resource.buffered( */ inline fun ResourceTry.mapCatching(transform: (value: S) -> R): ResourceTry = try { - Try.success((transform(getOrThrow()))) + map(transform) } catch (e: Exception) { Try.failure(Resource.Exception.wrap(e)) } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceContentExtractor.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceContentExtractor.kt index 3efae6aeaa..2ec26954f2 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceContentExtractor.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceContentExtractor.kt @@ -11,7 +11,9 @@ import kotlinx.coroutines.withContext import org.jsoup.Jsoup import org.jsoup.parser.Parser import org.readium.r2.shared.Search -import org.readium.r2.shared.util.Try +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.mediatype.MediaType /** @@ -23,7 +25,7 @@ interface ResourceContentExtractor { /** * Extracts the text content of the given [resource]. */ - suspend fun extractText(resource: Resource): ResourceTry = Try.success("") + suspend fun extractText(resource: Fetcher.Resource): ResourceTry = Try.success("") interface Factory { /** @@ -31,14 +33,14 @@ interface ResourceContentExtractor { * * Return null if the resource format is not supported. */ - suspend fun createExtractor(resource: Resource): ResourceContentExtractor? + suspend fun createExtractor(resource: Fetcher.Resource): ResourceContentExtractor? } } @Search class DefaultResourceContentExtractorFactory : ResourceContentExtractor.Factory { - override suspend fun createExtractor(resource: Resource): ResourceContentExtractor? = + override suspend fun createExtractor(resource: Fetcher.Resource): ResourceContentExtractor? = when (resource.link().mediaType) { MediaType.HTML, MediaType.XHTML -> HtmlResourceContentExtractor() else -> null @@ -51,7 +53,7 @@ class DefaultResourceContentExtractorFactory : ResourceContentExtractor.Factory @Search class HtmlResourceContentExtractor : ResourceContentExtractor { - override suspend fun extractText(resource: Resource): ResourceTry = withContext(Dispatchers.IO) { + override suspend fun extractText(resource: Fetcher.Resource): ResourceTry = withContext(Dispatchers.IO) { resource.readAsString().mapCatching { html -> val body = Jsoup.parse(html).body().text() // Transform HTML entities into their actual characters. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt index ca70619e83..50977135fc 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt @@ -10,6 +10,7 @@ package org.readium.r2.shared.fetcher import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.resource.Resource /** * Routes requests to child fetchers, depending on a provided predicate. @@ -33,7 +34,7 @@ class RoutingFetcher(private val routes: List) : Fetcher { override suspend fun links(): List = routes.flatMap { it.fetcher.links() } - override fun get(link: Link): Resource = + override fun get(link: Link): Fetcher.Resource = routes.firstOrNull { it.accepts(link) }?.fetcher?.get(link) ?: FailureResource(link, Resource.Exception.NotFound()) override suspend fun close() { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt index 2cecc76398..682e4a4616 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt @@ -25,7 +25,7 @@ class TransformingFetcher( override suspend fun links(): List = fetcher.links() - override fun get(link: Link): Resource { + override fun get(link: Link): Fetcher.Resource { val resource = fetcher.get(link) return transformers.fold(resource) { acc, transformer -> transformer(acc) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt b/readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt deleted file mode 100644 index 89f4e5c43b..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/format/Deprecated.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.format - -import java.net.HttpURLConnection -import org.readium.r2.shared.util.mediatype.MediaType as NewMediaType -import org.readium.r2.shared.util.mediatype.Sniffer -import org.readium.r2.shared.util.mediatype.SnifferContext -import org.readium.r2.shared.util.mediatype.Sniffers -import org.readium.r2.shared.util.mediatype.sniffMediaType - -@Deprecated("Moved to another package", replaceWith = ReplaceWith("org.readium.r2.shared.util.mediatype.MediaType"), level = DeprecationLevel.ERROR) -typealias MediaType = NewMediaType -@Deprecated("Format and MediaType got merged together", replaceWith = ReplaceWith("org.readium.r2.shared.util.mediatype.MediaType"), level = DeprecationLevel.ERROR) -typealias Format = NewMediaType -@Deprecated("Renamed Sniffer", replaceWith = ReplaceWith("org.readium.r2.shared.util.mediatype.Sniffer"), level = DeprecationLevel.ERROR) -typealias FormatSniffer = Sniffer -@Deprecated("Renamed Sniffers", replaceWith = ReplaceWith("org.readium.r2.shared.util.mediatype.Sniffers"), level = DeprecationLevel.ERROR) -typealias FormatSniffers = Sniffers -@Deprecated("Renamed SnifferContext", replaceWith = ReplaceWith("org.readium.r2.shared.util.mediatype.SnifferContext"), level = DeprecationLevel.ERROR) -typealias FormatSnifferContext = SnifferContext - -@Deprecated("Renamed to another package", ReplaceWith("org.readium.r2.shared.util.mediatype.sniffMediaType"), level = DeprecationLevel.ERROR) -suspend fun HttpURLConnection.sniffFormat( - bytes: (() -> ByteArray)? = null, - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList(), - sniffers: List = NewMediaType.sniffers -): NewMediaType? = - sniffMediaType(bytes, mediaTypes, fileExtensions, sniffers) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt index c3ece07f08..c80c036e5f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt @@ -11,7 +11,6 @@ package org.readium.r2.shared.publication import android.net.Uri import android.os.Parcelable -import androidx.annotation.StringRes import java.net.URL import java.net.URLEncoder import kotlin.reflect.KClass @@ -22,11 +21,13 @@ import kotlinx.parcelize.Parcelize import org.json.JSONObject import org.readium.r2.shared.* import org.readium.r2.shared.BuildConfig.DEBUG +import org.readium.r2.shared.error.Error +import org.readium.r2.shared.error.MessageError +import org.readium.r2.shared.error.ThrowableError import org.readium.r2.shared.extensions.* import org.readium.r2.shared.extensions.removeLastComponent import org.readium.r2.shared.fetcher.EmptyFetcher import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.epub.listOfAudioClips import org.readium.r2.shared.publication.epub.listOfVideoClips import org.readium.r2.shared.publication.services.CacheService @@ -166,7 +167,7 @@ class Publication( /** * Returns the resource targeted by the given non-templated [link]. */ - fun get(link: Link): Resource { + fun get(link: Link): Fetcher.Resource { if (DEBUG) { require(!link.templated) { "You must expand templated links before calling [Publication.get]" } } services.services.forEach { service -> service.get(link)?.let { return it } } @@ -352,7 +353,7 @@ class Publication( * @return The [Resource] containing the response, or null if the service doesn't recognize * this request. */ - fun get(link: Link): Resource? = null + fun get(link: Link): Fetcher.Resource? = null /** * Closes any opened file handles, removes temporary files, etc. @@ -432,39 +433,79 @@ class Publication( /** * Errors occurring while opening a Publication. */ - sealed class OpeningException(@StringRes userMessageId: Int, cause: Throwable? = null) : UserException(userMessageId, cause = cause) { + sealed class OpeningException : Error { /** * The file format could not be recognized by any parser. */ - class UnsupportedFormat(cause: Throwable? = null) : OpeningException(R.string.r2_shared_publication_opening_exception_unsupported_format, cause) + class UnsupportedAsset(override val cause: Error? = null) : OpeningException() { + + constructor(message: String) : this(MessageError(message)) + + override val message: String = + "Asset is not supported." + } /** * The publication file was not found on the file system. */ - class NotFound(cause: Throwable? = null) : OpeningException(R.string.r2_shared_publication_opening_exception_not_found, cause) + class NotFound(override val cause: Error? = null) : OpeningException() { + + override val message: String = + "Asset couldn't be found." + } /** * The publication parser failed with the given underlying exception. */ - class ParsingFailed(cause: Throwable? = null) : OpeningException(R.string.r2_shared_publication_opening_exception_parsing_failed, cause) + class ParsingFailed(override val cause: Error? = null) : OpeningException() { + + override val message: String = + "The asset is corrupted so the publication cannot be opened." + } /** * We're not allowed to open the publication at all, for example because it expired. */ - class Forbidden(cause: Throwable? = null) : OpeningException(R.string.r2_shared_publication_opening_exception_forbidden, cause) + class Forbidden(override val cause: Error? = null) : OpeningException() { + + override val message: String = + "You are not allowed to open this publication." + } /** * The publication can't be opened at the moment, for example because of a networking error. * This error is generally temporary, so the operation may be retried or postponed. */ - class Unavailable(cause: Throwable? = null) : OpeningException(R.string.r2_shared_publication_opening_exception_unavailable, cause) + class Unavailable(override val cause: Error? = null) : OpeningException() { + + override val message: String = + "Not available, please try again later." + } /** * The provided credentials are incorrect and we can't open the publication in a * `restricted` state (e.g. for a password-protected ZIP). */ - object IncorrectCredentials : OpeningException(R.string.r2_shared_publication_opening_exception_incorrect_credentials) + class IncorrectCredentials(override val cause: Error? = null) : OpeningException() { + + override val message: String = + "Provided credentials were incorrect." + } + + class OutOfMemory(override val cause: Error? = null) : OpeningException() { + + override val message: String = + "There is not enough memory available to open device to read the publication." + } + + class Unexpected(override val cause: Error? = null) : OpeningException() { + + constructor(exception: Exception) : this(ThrowableError(exception)) + + override val message: String = + "An expected error occurred." + } } /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt deleted file mode 100644 index 42b4c8255f..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/DefaultPublicationAssetFactory.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.publication.asset - -import java.io.File -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.archive.DefaultArchiveFactory -import org.readium.r2.shared.util.http.DefaultHttpClient -import org.readium.r2.shared.util.http.HttpClient -import org.readium.r2.shared.util.mediatype.MediaType - -/** - * A factory for various [PublicationAsset]s. - * - * Supported protocols are file, http and https. - */ -class DefaultPublicationAssetFactory( - val archiveFactory: ArchiveFactory = DefaultArchiveFactory(), - val httpClient: HttpClient = DefaultHttpClient() -) : PublicationAssetFactory { - - private val fileAssetFactory: FileAsset.Factory = - FileAsset.Factory(archiveFactory, httpClient) - - private val remoteAssetFactory: RemoteAsset.Factory = - RemoteAsset.Factory(archiveFactory, httpClient) - - /** - * Creates an asset for a publication available at [url]. - * - * @param url the url at which the publication is available - * @param mediaType the publication media type - */ - override suspend fun createAsset( - url: Url, - mediaType: MediaType, - ): Try { - return when (url.protocol) { - "file" -> fileAssetFactory.createAsset(File(url.path), mediaType) - "http", "https" -> remoteAssetFactory.createAsset(url, mediaType) - else -> throw IllegalArgumentException("Protocol not supported.") - } - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt deleted file mode 100644 index 4688b91220..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/FileAsset.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.publication.asset - -import java.io.File -import java.io.FileNotFoundException -import java.nio.charset.Charset -import org.json.JSONObject -import org.readium.r2.shared.fetcher.* -import org.readium.r2.shared.publication.Manifest -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.getOrElse -import org.readium.r2.shared.util.http.HttpClient -import org.readium.r2.shared.util.mediatype.MediaType - -/** - * A [PublicationAsset] built from a [File]. - */ -data class FileAsset( - val file: File, - override val mediaType: MediaType, - override val fetcher: Fetcher -) : PublicationAsset { - - override val name: String = - file.name - - internal class Factory( - private val archiveFactory: ArchiveFactory, - private val httpClient: HttpClient - ) { - - suspend fun createAsset( - file: File, - mediaType: MediaType - ): Try = - createFetcher(file, mediaType) - .map { fetcher -> FileAsset(file, mediaType, fetcher) } - - private suspend fun createFetcher(file: File, mediaType: MediaType): Try { - return try { - when { - file.isDirectory -> Try.success(FileFetcher(href = "/", file = file)) - file.exists() -> createFetcherForFile(file, mediaType) - else -> throw FileNotFoundException(file.path) - } - } catch (e: SecurityException) { - Try.failure(Publication.OpeningException.Forbidden(e)) - } catch (e: FileNotFoundException) { - Try.failure(Publication.OpeningException.NotFound(e)) - } - } - - private suspend fun createFetcherForFile(file: File, mediaType: MediaType): Try { - ArchiveFetcher.fromPath(file.path, archiveFactory) - ?.let { return Try.success(it) } - - if (mediaType.isRwpm) { - val manifest = file.readAsRwpm(packaged = false) - .mapFailure { Publication.OpeningException.ParsingFailed(it) } - .getOrElse { return Try.failure(it) } - - val fileFetcher = FileFetcher(href = "/manifest.json", file = file) - val baseUrl = manifest.linkWithRel("self")?.let { File(it.href).parent } - val httpFetcher = HttpFetcher(httpClient, baseUrl) - return Try.success(RoutingFetcher(fileFetcher, httpFetcher)) - } - - return Try.success(FileFetcher(href = "/${file.name}", file = file)) - } - - private fun File.readAsRwpm(packaged: Boolean): Try = - try { - val bytes = readBytes() - val string = String(bytes, Charset.defaultCharset()) - val json = JSONObject(string) - val manifest = Manifest.fromJSON(json, packaged = packaged) - ?: throw Exception("Failed to parse the RWPM Manifest") - Try.success(manifest) - } catch (e: Exception) { - Try.failure(e) - } - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt deleted file mode 100644 index 83ac049455..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAsset.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.publication.asset - -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.util.mediatype.MediaType - -/** Represents a digital medium (e.g. a file) offering access to a publication. */ -interface PublicationAsset { - - /** - * Name of the asset, e.g. a filename. - */ - val name: String - - /** - * Media type of the asset. - * - * If unknown, fallback on `MediaType.BINARY`. - */ - val mediaType: MediaType - - /** - * [Fetcher] to provide access to the asset content. - */ - val fetcher: Fetcher -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt deleted file mode 100644 index 83f62d9db9..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/PublicationAssetFactory.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.publication.asset - -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.mediatype.MediaType - -/** - * Builds [PublicationAsset]s for publications that can be accessed through various means. - */ -interface PublicationAssetFactory { - - /** - * Creates a [PublicationAsset] for a publication with media type [mediaType] available at [url]. - */ - suspend fun createAsset( - url: Url, - mediaType: MediaType - ): Try -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt deleted file mode 100644 index 3e4d32b612..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/asset/RemoteAsset.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.publication.asset - -import org.readium.r2.shared.InternalReadiumApi -import org.readium.r2.shared.fetcher.ArchiveFetcher -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.HttpFetcher -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.http.HttpClient -import org.readium.r2.shared.util.mediatype.MediaType - -/** - * A [PublicationAsset] built for a remote publication. - */ -data class RemoteAsset( - val url: Url, - override val mediaType: MediaType, - override val fetcher: Fetcher -) : PublicationAsset { - - override val name: String = - url.file - - @InternalReadiumApi - class Factory( - private val archiveFactory: ArchiveFactory, - private val httpClient: HttpClient - ) { - suspend fun createAsset( - url: Url, - mediaType: MediaType, - ): Try = - createFetcher(url, mediaType) - .map { fetcher -> RemoteAsset(url, mediaType, fetcher) } - - private suspend fun createFetcher(url: Url, mediaType: MediaType): Try { - ArchiveFetcher.fromUrl(url, archiveFactory) - ?.let { return Try.success(it) } - - // This enables support for both exploded containers (thanks to baseUrl) and - // single-file publications (thanks to links). - val httpFetcher = HttpFetcher( - client = httpClient, - baseUrl = url.toString(), - links = listOf( - Link(href = url.toString(), type = mediaType.toString()) - ) - ) - - return Try.success(httpFetcher) - } - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt new file mode 100644 index 0000000000..34e47cd2f1 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.fetcher.ContainerFetcher +import org.readium.r2.shared.parser.xml.ElementNode +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.protection.ContentProtection.Scheme +import org.readium.r2.shared.publication.services.contentProtectionServiceFactory +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.readAsXml +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever + +/** + * [ContentProtection] implementation used as a fallback by the Streamer to detect Adept DRM, + * if it is not supported by the app. + */ +class AdeptFallbackContentProtection( + private val mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever() +) : ContentProtection { + + override val scheme: Scheme = Scheme.Adept + + override suspend fun supports(asset: Asset): Boolean { + if (asset !is Asset.Container) { + return false + } + + return isAdept(asset.container, asset.mediaType) + } + + override suspend fun open( + asset: Asset, + credentials: String?, + allowUserInteraction: Boolean, + sender: Any? + ): Try { + if (asset !is Asset.Container) { + return Try.failure( + Publication.OpeningException.UnsupportedAsset("A container asset was expected.") + ) + } + + val protectedFile = ContentProtection.Asset( + asset.name, + asset.mediaType, + ContainerFetcher(asset.container, mediaTypeRetriever), + onCreatePublication = { + servicesBuilder.contentProtectionServiceFactory = + FallbackContentProtectionService.createFactory(scheme, "Adobe ADEPT") + } + ) + + return Try.success(protectedFile) + } + + private suspend fun isAdept(container: Container, mediaType: MediaType): Boolean { + if (!mediaType.matches(MediaType.EPUB)) { + return false + } + val rightsXml = container.entry("/META-INF/rights.xml").readAsXmlOrNull() + val encryptionXml = container.entry("/META-INF/encryption.xml").readAsXmlOrNull() + + return encryptionXml != null && ( + rightsXml?.namespace == "http://ns.adobe.com/adept" || + encryptionXml + .get("EncryptedData", EpubEncryption.ENC) + .flatMap { it.get("KeyInfo", EpubEncryption.SIG) } + .flatMap { it.get("resource", "http://ns.adobe.com/adept") } + .isNotEmpty() + ) + } +} + +private suspend inline fun Resource.readAsXmlOrNull(): ElementNode? = + readAsXml().getOrNull() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt similarity index 55% rename from readium/shared/src/main/java/org/readium/r2/shared/publication/ContentProtection.kt rename to readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt index 10347eadb8..ea5feb1776 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt @@ -7,74 +7,82 @@ * LICENSE file present in the project repository where this source code is maintained. */ -package org.readium.r2.shared.publication +package org.readium.r2.shared.publication.protection import androidx.annotation.StringRes import org.readium.r2.shared.R import org.readium.r2.shared.UserException +import org.readium.r2.shared.error.Try import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.asset.PublicationAsset +import org.readium.r2.shared.publication.LocalizedString +import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.ContentProtectionService -import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.mediatype.MediaType /** * Bridge between a Content Protection technology and the Readium toolkit. * * Its responsibilities are to: - * - Unlock a publication by returning a customized [Fetcher]. + * - Create a [Fetcher] one can access the publication through. * - Create a [ContentProtectionService] publication service. */ interface ContentProtection { + val scheme: Scheme + + /** + * Returns if this [ContentProtection] supports the given [asset]. + */ + suspend fun supports( + asset: org.readium.r2.shared.asset.Asset + ): Boolean + /** * Attempts to unlock a potentially protected publication asset. * - * @return A [ProtectedAsset] in case of success, null if the asset is not protected by this - * technology or a [Publication.OpeningException] if the asset can't be successfully opened, - * even in restricted mode. + * @return A [Asset] in case of success or a [Publication.OpeningException] if the + * asset can't be successfully opened even in restricted mode. */ suspend fun open( - asset: PublicationAsset, + asset: org.readium.r2.shared.asset.Asset, credentials: String?, allowUserInteraction: Boolean, sender: Any? - ): Try? + ): Try /** - * Holds the result of opening a [PublicationAsset] with a [ContentProtection]. - * - * @property asset Protected asset which will be provided to the parsers. - * It is likely to be different from the asset provided to ContentProtection::open(): - * - If the original fetcher is wrapped into a new fetcher able to decipher content. - * - If the original asset has a media type that can't be recognized by parsers, - * the Content Protection must return an asset with the matching unprotected media type. - * - If the Content Protection technology needs to redirect the Streamer to a different file. - * For example, this could be used to decrypt a publication to a temporary secure location. + * Holds the result of opening an [Asset] with a [ContentProtection]. * - * @property onCreatePublication Called on every parsed Publication.Builder. + * @property name Asset name + * @property mediaType Media type of the asset + * @property fetcher Fetcher to access the publication through + * @property onCreatePublication Called on every parsed Publication.Builder * It can be used to modify the `Manifest`, the root [Fetcher] or the list of service factories * of a [Publication]. */ - data class ProtectedAsset( - val asset: PublicationAsset, + data class Asset( + val name: String, + val mediaType: MediaType, + val fetcher: Fetcher, val onCreatePublication: Publication.Builder.() -> Unit = {} ) /** * Represents a specific Content Protection technology, uniquely identified with an [uri]. */ - class Scheme( + @JvmInline + value class Scheme( val uri: String, - val name: LocalizedString? ) { - override fun hashCode(): Int = uri.hashCode() - override fun equals(other: Any?): Boolean = (other as? Scheme)?.uri == uri + + @Deprecated("Define yourself the name to print to users.", level = DeprecationLevel.ERROR) + val name: LocalizedString? get() = null companion object { /** Readium LCP DRM scheme. */ - val Lcp = Scheme(uri = "http://readium.org/2014/01/lcp", name = LocalizedString("Readium LCP")) + val Lcp = Scheme(uri = "http://readium.org/2014/01/lcp") /** Adobe ADEPT DRM scheme. */ - val Adept = Scheme(uri = "http://ns.adobe.com/adept", name = LocalizedString("Adobe ADEPT")) + val Adept = Scheme(uri = "http://ns.adobe.com/adept") } } @@ -90,10 +98,10 @@ interface ContentProtection { * Exception returned when the given Content Protection [scheme] is not supported by the * app. */ - class SchemeNotSupported(val scheme: Scheme? = null) : Exception( - if (scheme?.name == null) R.string.r2_shared_publication_content_protection_exception_not_supported_unknown + class SchemeNotSupported(val scheme: Scheme? = null, name: String?) : Exception( + if (name == null) R.string.r2_shared_publication_content_protection_exception_not_supported_unknown else R.string.r2_shared_publication_content_protection_exception_not_supported, - scheme?.name?.string + name ) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt new file mode 100644 index 0000000000..d1f1bb982c --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever + +/** + * Retrieves [ContentProtection] schemes of assets. + */ +class ContentProtectionSchemeRetriever( + contentProtections: List, + mediaTypeRetriever: MediaTypeRetriever +) { + private val contentProtections: List = + contentProtections + listOf( + LcpFallbackContentProtection(mediaTypeRetriever), + AdeptFallbackContentProtection(mediaTypeRetriever) + ) + + suspend fun retrieve(asset: Asset): ContentProtection.Scheme? = + contentProtections + .firstOrNull { it.supports(asset) } + ?.scheme +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/EpubEncryption.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/EpubEncryption.kt new file mode 100644 index 0000000000..86dd5fe7e7 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/EpubEncryption.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +internal object EpubEncryption { + + const val ENC = "http://www.w3.org/2001/04/xmlenc#" + const val SIG = "http://www.w3.org/2000/09/xmldsig#" + const val COMP = "http://www.idpf.org/2016/encryption#compression" +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/FallbackContentProtectionService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/FallbackContentProtectionService.kt new file mode 100644 index 0000000000..b03d3c8eda --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/FallbackContentProtectionService.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +import org.readium.r2.shared.UserException +import org.readium.r2.shared.publication.LocalizedString +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.services.ContentProtectionService + +internal class FallbackContentProtectionService( + override val scheme: ContentProtection.Scheme?, + override val name: LocalizedString? +) : ContentProtectionService { + + override val isRestricted: Boolean = true + override val credentials: String? = null + override val rights = ContentProtectionService.UserRights.AllRestricted + override val error: UserException = + ContentProtection.Exception.SchemeNotSupported(scheme, name?.string) + + companion object { + + fun createFactory( + scheme: ContentProtection.Scheme?, + name: String? + ): (Publication.Service.Context) -> ContentProtectionService = + { FallbackContentProtectionService(scheme, name?.let { LocalizedString(it) }) } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt new file mode 100644 index 0000000000..6a2cedf84d --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt @@ -0,0 +1,110 @@ +/* + * Copyright 2021 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +import org.json.JSONObject +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.fetcher.ContainerFetcher +import org.readium.r2.shared.parser.xml.ElementNode +import org.readium.r2.shared.publication.Manifest +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.encryption.encryption +import org.readium.r2.shared.publication.protection.ContentProtection.Scheme +import org.readium.r2.shared.publication.services.contentProtectionServiceFactory +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.readAsJson +import org.readium.r2.shared.resource.readAsXml +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever + +/** + * [ContentProtection] implementation used as a fallback by the Streamer to detect LCP DRM + * if it is not supported by the app. + */ +class LcpFallbackContentProtection( + private val mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever() +) : ContentProtection { + + override val scheme: Scheme = + Scheme.Lcp + + override suspend fun supports(asset: Asset): Boolean = + when (asset) { + is Asset.Container -> isLcpProtected(asset.container, asset.mediaType) + is Asset.Resource -> asset.mediaType.matches(MediaType.LCP_LICENSE_DOCUMENT) + } + + override suspend fun open( + asset: Asset, + credentials: String?, + allowUserInteraction: Boolean, + sender: Any? + ): Try { + if (asset !is Asset.Container) { + return Try.failure( + Publication.OpeningException.UnsupportedAsset("A container asset was expected.") + ) + } + + val protectedFile = ContentProtection.Asset( + asset.name, + asset.mediaType, + ContainerFetcher(asset.container, mediaTypeRetriever), + onCreatePublication = { + servicesBuilder.contentProtectionServiceFactory = + FallbackContentProtectionService.createFactory(scheme, "Readium LCP") + } + ) + + return Try.success(protectedFile) + } + + private suspend fun isLcpProtected(container: Container, mediaType: MediaType): Boolean { + return when { + mediaType.matches(MediaType.READIUM_WEBPUB) || + mediaType.matches(MediaType.LCP_PROTECTED_PDF) || + mediaType.matches(MediaType.LCP_PROTECTED_AUDIOBOOK) -> { + if (container.entry("/license.lcpl").readAsJsonOrNull() != null) { + return true + } + + val manifestAsJson = container.entry("/manifest.json").readAsJsonOrNull() + ?: return false + + val manifest = Manifest.fromJSON(manifestAsJson) + ?: return false + + return manifest + .readingOrder + .any { it.properties.encryption?.scheme == "http://readium.org/2014/01/lcp" } + } + mediaType.matches(MediaType.EPUB) -> { + if (container.entry("/META-INF/license.lcpl").readAsJsonOrNull() != null) { + return true + } + + val encryptionXml = container.entry("/META-INF/encryption.xml").readAsXmlOrNull() + ?: return false + + return encryptionXml + .get("EncryptedData", EpubEncryption.ENC) + .flatMap { it.get("KeyInfo", EpubEncryption.SIG) } + .flatMap { it.get("RetrievalMethod", EpubEncryption.SIG) } + .any { it.getAttr("URI") == "license.lcpl#/encryption/content_key" } + } + else -> false + } + } +} + +private suspend inline fun Resource.readAsJsonOrNull(): JSONObject? = + readAsJson().getOrNull() + +private suspend inline fun Resource.readAsXmlOrNull(): ElementNode? = + readAsXml().getOrNull() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt index cfd3818d16..86fc8feba8 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt @@ -15,9 +15,15 @@ import org.readium.r2.shared.UserException import org.readium.r2.shared.extensions.putIfNotEmpty import org.readium.r2.shared.extensions.queryParameters import org.readium.r2.shared.fetcher.FailureResource -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.StringResource -import org.readium.r2.shared.publication.* +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.LocalizedString +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.PublicationServicesHolder +import org.readium.r2.shared.publication.ServiceFactory +import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.resource.Resource /** * Provides information about a publication's content protection and manages user rights. @@ -54,12 +60,12 @@ interface ContentProtectionService : Publication.Service { * User-facing name for this Content Protection, e.g. "Readium LCP". * It could be used in a sentence such as "Protected by {name}" */ - val name: LocalizedString? get() = scheme?.name + val name: LocalizedString? get() = null override val links: List get() = RouteHandler.links - override fun get(link: Link): Resource? { + override fun get(link: Link): Fetcher.Resource? { val route = RouteHandler.route(link) ?: return null return route.handleRequest(link, this) } @@ -243,7 +249,7 @@ private sealed class RouteHandler { abstract fun acceptRequest(link: Link): Boolean - abstract fun handleRequest(link: Link, service: ContentProtectionService): Resource + abstract fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource object ContentProtectionHandler : RouteHandler() { @@ -254,7 +260,7 @@ private sealed class RouteHandler { override fun acceptRequest(link: Link): Boolean = link.href == this.link.href - override fun handleRequest(link: Link, service: ContentProtectionService): Resource = + override fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource = StringResource(link) { JSONObject().apply { put("isRestricted", service.isRestricted) @@ -275,7 +281,7 @@ private sealed class RouteHandler { override fun acceptRequest(link: Link): Boolean = link.href.startsWith("/~readium/rights/copy") - override fun handleRequest(link: Link, service: ContentProtectionService): Resource { + override fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource { val parameters = link.href.queryParameters() val text = parameters["text"] ?: return FailureResource( @@ -313,7 +319,7 @@ private sealed class RouteHandler { override fun acceptRequest(link: Link): Boolean = link.href.startsWith("/~readium/rights/print") - override fun handleRequest(link: Link, service: ContentProtectionService): Resource { + override fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource { val parameters = link.href.queryParameters() val pageCountString = parameters["pageCount"] ?: return FailureResource( diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt index dff57253a7..6fb569e0d6 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt @@ -16,8 +16,8 @@ import org.readium.r2.shared.extensions.scaleToFit import org.readium.r2.shared.extensions.toPng import org.readium.r2.shared.fetcher.BytesResource import org.readium.r2.shared.fetcher.FailureResource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.LazyResource -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.ServiceFactory @@ -98,13 +98,14 @@ abstract class GeneratedCoverService : CoverService { abstract override suspend fun cover(): Bitmap - override fun get(link: Link): Resource? { + override fun get(link: Link): Fetcher.Resource? { if (link.href != coverLink.href) return null return LazyResource { val cover = cover() val png = cover.toPng() + if (png == null) { val error = Exception("Unable to convert cover to PNG.") FailureResource(coverLink, error) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt index f59fd811fa..45542e63f1 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt @@ -13,9 +13,10 @@ import kotlinx.coroutines.runBlocking import org.json.JSONObject import org.readium.r2.shared.extensions.mapNotNull import org.readium.r2.shared.extensions.toJsonOrNull -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.StringResource import org.readium.r2.shared.publication.* +import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.toJSON private val positionsLink = Link( @@ -40,7 +41,7 @@ interface PositionsService : Publication.Service { override val links get() = listOf(positionsLink) - override fun get(link: Link): Resource? { + override fun get(link: Link): Fetcher.Resource? { if (link.href != positionsLink.href) return null diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index 3dd2a118bc..a6918eaa3e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -15,8 +15,9 @@ import org.jsoup.parser.Parser import org.jsoup.select.NodeTraversor import org.jsoup.select.NodeVisitor import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication @@ -24,6 +25,7 @@ import org.readium.r2.shared.publication.html.cssSelector import org.readium.r2.shared.publication.services.content.Content import org.readium.r2.shared.publication.services.content.Content.* import org.readium.r2.shared.publication.services.positionsByReadingOrder +import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.Language import org.readium.r2.shared.util.mediatype.MediaType @@ -43,7 +45,7 @@ import org.readium.r2.shared.util.use */ @ExperimentalReadiumApi class HtmlResourceContentIterator internal constructor( - private val resource: Resource, + private val resource: Fetcher.Resource, private val totalProgressionRange: ClosedRange?, private val locator: Locator, private val beforeMaxLength: Int = 50 @@ -53,7 +55,7 @@ class HtmlResourceContentIterator internal constructor( override suspend fun create( publication: Publication, readingOrderIndex: Int, - resource: Resource, + resource: Fetcher.Resource, locator: Locator ): Content.Iterator? { if (!resource.link().mediaType.matchesAny(MediaType.HTML, MediaType.XHTML)) { @@ -407,7 +409,7 @@ class HtmlResourceContentIterator internal constructor( text = text, attributes = buildList { currentLanguage?.let { - add(Attribute(Content.AttributeKey.LANGUAGE, Language(it))) + add(Attribute(AttributeKey.LANGUAGE, Language(it))) } }, ) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt index 5eed04f3f5..f1626a9f39 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt @@ -7,7 +7,7 @@ package org.readium.r2.shared.publication.services.content.iterators import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication @@ -15,6 +15,11 @@ import org.readium.r2.shared.publication.indexOfFirstWithHref import org.readium.r2.shared.publication.services.content.Content import org.readium.r2.shared.util.Either +/** + * Creates a [Content.Iterator] instance for the [Resource], starting from the given [Locator]. + * + * Returns null if the resource media type is not supported. + */ @ExperimentalReadiumApi fun interface ResourceContentIteratorFactory { @@ -26,7 +31,7 @@ fun interface ResourceContentIteratorFactory { suspend fun create( publication: Publication, readingOrderIndex: Int, - resource: Resource, + resource: Fetcher.Resource, locator: Locator ): Content.Iterator? } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt index e4e5aa327a..10b6ce41ec 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt @@ -8,17 +8,16 @@ package org.readium.r2.shared.publication.services.search import android.os.Parcelable import androidx.annotation.StringRes -import kotlinx.coroutines.CancellationException import kotlinx.parcelize.Parcelize import org.readium.r2.shared.R import org.readium.r2.shared.Search import org.readium.r2.shared.UserException -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.LocatorCollection import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.ServiceFactory +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.SuspendingCloseable -import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.HttpException @Search @@ -68,7 +67,6 @@ sealed class SearchException(content: Content, cause: Throwable? = null) : UserE fun wrap(e: Throwable): SearchException = when (e) { is SearchException -> e - is CancellationException, is Resource.Exception.Cancelled -> Cancelled is Resource.Exception -> ResourceError(e) is HttpException -> if (e.kind == HttpException.Kind.Cancelled) { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt index 86aea70efc..859af9eb1d 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt @@ -17,6 +17,8 @@ import java.util.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.Search +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.fetcher.DefaultResourceContentExtractorFactory import org.readium.r2.shared.fetcher.ResourceContentExtractor import org.readium.r2.shared.publication.Link @@ -26,7 +28,6 @@ import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.positionsByReadingOrder import org.readium.r2.shared.publication.services.search.SearchService.Options import org.readium.r2.shared.util.Ref -import org.readium.r2.shared.util.Try import timber.log.Timber /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt new file mode 100644 index 0000000000..7366b6255f --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import kotlinx.coroutines.runBlocking +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.extensions.coerceIn +import org.readium.r2.shared.extensions.requireLengthFitInt + +sealed class BaseBytesResource( + val bytes: suspend () -> Try +) : Resource { + + private lateinit var _bytes: Try + + override suspend fun read(range: LongRange?): ResourceTry { + if (!::_bytes.isInitialized) + _bytes = bytes() + + if (range == null) + return _bytes + + return _bytes.map { it.read(range) } + } + + private fun ByteArray.read(range: LongRange): ByteArray { + @Suppress("NAME_SHADOWING") + val range = range + .coerceIn(0L until size) + .requireLengthFitInt() + + return sliceArray(range.map(Long::toInt)) + } + + override suspend fun length(): ResourceTry = + read().map { it.size.toLong() } + + override suspend fun close() {} +} + +/** Creates a Resource serving a [ByteArray]. */ +class BytesResource(bytes: suspend () -> Try) : BaseBytesResource(bytes) { + + constructor(bytes: ByteArray) : this({ Try.success(bytes) }) + + override fun toString(): String = + "${javaClass.simpleName}(${runBlocking { length() }} bytes)" +} + +/** Creates a Resource serving a [String]. */ +class StringResource( + string: suspend () -> ResourceTry +) : BaseBytesResource({ string().map { it.toByteArray() } }) { + + constructor(string: String) : this({ Try.success(string) }) + + override fun toString(): String = + "${javaClass.simpleName}(${runBlocking { readAsString() }})" +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt new file mode 100644 index 0000000000..fb3e578585 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import java.io.File +import org.readium.r2.shared.util.SuspendingCloseable + +/** + * A resource container as an archive or a directory. + */ +interface Container : SuspendingCloseable { + + /** + * Holds a container entry's. + */ + interface Entry : Resource { + + /** + * Absolute path to the entry in the archive. + * It MUST start with /. + */ + val path: String + } + + /** + * Direct file to this container, when available. + */ + val file: File? get() = null + + /** + * Gets the container name if any. + */ + suspend fun name(): ResourceTry + + /** + * List of all the container entries of null if such a list is not available. + */ + suspend fun entries(): Iterable? + + /** + * Returns the [Entry] at the given [path]. + * + * A [Entry] is always returned, since for some cases we can't know if it exists before + * actually fetching it, such as HTTP. Therefore, errors are handled at the Entry level. + */ + suspend fun entry(path: String): Entry +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt new file mode 100644 index 0000000000..493a39ac18 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt @@ -0,0 +1,148 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import android.content.ContentResolver +import android.net.Uri +import android.provider.OpenableColumns +import java.io.FileNotFoundException +import java.io.IOException +import java.io.InputStream +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.extensions.read +import org.readium.r2.shared.extensions.readFully +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.toUri + +/** + * Creates [ContentResource]s. + */ +class ContentResourceFactory( + private val contentResolver: ContentResolver +) : ResourceFactory { + + override suspend fun create(url: Url): Try { + if (url.scheme != ContentResolver.SCHEME_CONTENT) { + return Try.failure(ResourceFactory.Error.SchemeNotSupported(url.scheme)) + } + + val resource = ContentResource(url.toUri(), contentResolver) + + return Try.success(resource) + } +} + +/** + * A [Resource] to access content [uri] thanks to a [ContentResolver]. + */ +class ContentResource( + private val uri: Uri, + private val contentResolver: ContentResolver, +) : Resource { + + private lateinit var _length: ResourceTry + + override suspend fun name(): ResourceTry { + val cursor = contentResolver + .query(uri, null, null, null, null) + ?: return ResourceTry.failure(Resource.Exception.NotFound()) + + @Suppress("Name_shadowing") + cursor.use { cursor -> + if (!cursor.moveToFirst()) { + return ResourceTry.failure(Resource.Exception.NotFound()) + } + val columnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) + .takeUnless { it == -1 } + ?: return Try.success(uri.lastPathSegment) + + tryOrNull { cursor.getString(columnIndex) } + ?.let { return Try.success(it) } + ?: return Try.success(uri.lastPathSegment) + } + } + + override suspend fun mediaType(): ResourceTry = + Try.success(contentResolver.getType(uri)) + + override suspend fun close() { + } + + override suspend fun read(range: LongRange?): ResourceTry { + if (range == null) { + return readFully() + } + + @Suppress("NAME_SHADOWING") + val range = range + .coerceFirstNonNegative() + .requireLengthFitInt() + + if (range.isEmpty()) { + return Try.success(ByteArray(0)) + } + + return readRange(range) + } + + private suspend fun readFully(): ResourceTry = + withStream { it.readFully() } + + private suspend fun readRange(range: LongRange): ResourceTry = + withStream { + withContext(Dispatchers.IO) { + val skipped = it.skip(range.first) + check(skipped == range.first) + val length = range.last - range.first + 1 + it.read(length) + } + } + + override suspend fun length(): ResourceTry { + if (!::_length.isInitialized) { + _length = ResourceTry.catching { + contentResolver.openFileDescriptor(uri, "r") + .use { fd -> checkNotNull(fd?.statSize.takeUnless { it == -1L }) } + } + } + + return _length + } + + private suspend fun withStream(block: suspend (InputStream) -> T): Try = + ResourceTry.catching { + val stream = contentResolver.openInputStream(uri) + ?: throw Resource.Exception.Unavailable( + Exception("Content provider recently crashed.") + ) + val result = block(stream) + stream.close() + result + } + + private inline fun Try.Companion.catching(closure: () -> T): ResourceTry = + try { + success(closure()) + } catch (e: FileNotFoundException) { + failure(Resource.Exception.NotFound(e)) + } catch (e: SecurityException) { + failure(Resource.Exception.Forbidden(e)) + } catch (e: IOException) { + failure(Resource.Exception.Unavailable(e)) + } catch (e: Exception) { + failure(Resource.Exception.wrap(e)) + } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. + failure(Resource.Exception.wrap(e)) + } + + override fun toString(): String = + "${javaClass.simpleName}(${runBlocking { length() } } bytes )" +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt new file mode 100644 index 0000000000..a61e2cadd0 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import java.io.File +import java.util.zip.ZipException +import java.util.zip.ZipFile +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.MessageError +import org.readium.r2.shared.error.Try + +class DefaultArchiveFactory : ArchiveFactory { + + override suspend fun create(resource: Resource, password: String?): Try { + if (password != null) { + return Try.failure(ArchiveFactory.Error.PasswordsNotSupported()) + } + + return resource.file + ?.let { open(it) } + ?: Try.failure( + ArchiveFactory.Error.FormatNotSupported( + MessageError("Resource not supported because file cannot be directly access.") + ) + ) + } + + // Internal for testing purpose + internal suspend fun open(file: File): Try = + withContext(Dispatchers.IO) { + try { + val archive = JavaZipContainer(ZipFile(file), file) + Try.success(archive) + } catch (e: ZipException) { + Try.failure(ArchiveFactory.Error.FormatNotSupported(e)) + } catch (e: SecurityException) { + Try.failure(ArchiveFactory.Error.ResourceReading(Resource.Exception.Forbidden(e))) + } catch (e: Exception) { + Try.failure(ArchiveFactory.Error.ResourceReading(Resource.Exception.wrap(e))) + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt new file mode 100644 index 0000000000..1d14ea7171 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import android.content.ContentResolver +import java.io.File +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.extensions.addPrefix +import org.readium.r2.shared.extensions.isParentOf +import org.readium.r2.shared.extensions.tryOr +import org.readium.r2.shared.util.Url + +/** + * A file system directory as a [Container]. + */ +internal class DirectoryContainer( + private val root: File, + private val entries: List +) : Container { + + private inner class FailureEntry( + override val path: String + ) : Container.Entry, + Resource by FailureResource( + Resource.Exception.NotFound(Exception("No entry at path $path.")) + ) + + private inner class SuccessEntry( + override val file: File + ) : Container.Entry, Resource by FileResource(file) { + + override val path: String = + file.relativeTo(root).path.addPrefix("/") + + override suspend fun close() {} + } + + override suspend fun name(): ResourceTry = + ResourceTry.success(root.name) + + override suspend fun entries(): List = + entries.map { SuccessEntry(it) }.toList() + + override suspend fun entry(path: String): Container.Entry { + val file = File(root, path.removePrefix("/")) + + return if (!root.isParentOf(file)) + FailureEntry(path) + else + SuccessEntry(file) + } + + override suspend fun close() {} +} + +class DirectoryContainerFactory : ContainerFactory { + + override suspend fun create(url: Url): Try { + if (url.scheme != ContentResolver.SCHEME_FILE) { + return Try.failure(ContainerFactory.Error.SchemeNotSupported(url.scheme)) + } + + val file = File(url.path) + + if (!tryOr(false) { file.isDirectory }) { + return Try.failure(ContainerFactory.Error.NotAContainer(url)) + } + + return create(file) + } + + // Internal for testing purpose + internal suspend fun create(file: File): Try { + val entries = + try { + withContext(Dispatchers.IO) { + file.walk() + .filter { it.isFile } + .toList() + } + } catch (e: Exception) { + return Try.failure(ContainerFactory.Error.Forbidden(e)) + } + + val container = DirectoryContainer(file, entries) + + return Try.success(container) + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt new file mode 100644 index 0000000000..0f86cd81b1 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt @@ -0,0 +1,208 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import org.readium.r2.shared.error.ThrowableError +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.tryRecover +import org.readium.r2.shared.util.Url + +/** + * A factory to read [Resource]s from [Url]s. + * + * An exception must be returned if the url scheme is not supported or + * the resource cannot be found. + */ +fun interface ResourceFactory { + + sealed class Error : org.readium.r2.shared.error.Error { + + class SchemeNotSupported( + val scheme: String, + override val cause: org.readium.r2.shared.error.Error? = null + ) : Error() { + + constructor(scheme: String, exception: Exception) : this(scheme, ThrowableError(exception)) + + override val message: String = + "Url scheme $scheme is not supported." + } + + class NotAResource( + val url: Url, + override val cause: org.readium.r2.shared.error.Error? = null + ) : Error() { + + constructor(url: Url, exception: Exception) : this(url, ThrowableError(exception)) + + override val message: String = + "No resource found at url $url." + } + + class Forbidden( + override val cause: org.readium.r2.shared.error.Error + ) : Error() { + + constructor(exception: Exception) : this(ThrowableError(exception)) + + override val message: String = + "Access to the container is forbidden." + } + } + + suspend fun create(url: Url): Try +} + +/** + * A factory to create [Container]s from [Url]s. + * + * An exception must be returned if the url scheme is not supported or + * the url doesn't seem to point to a container. + */ +fun interface ContainerFactory { + + sealed class Error : org.readium.r2.shared.error.Error { + + class SchemeNotSupported( + val scheme: String, + override val cause: org.readium.r2.shared.error.Error? = null + ) : Error() { + + constructor(scheme: String, exception: Exception) : this(scheme, ThrowableError(exception)) + + override val message: String = + "Url scheme $scheme is not supported." + } + + class NotAContainer( + val url: Url, + override val cause: org.readium.r2.shared.error.Error? = null + ) : Error() { + + constructor(url: Url, exception: Exception) : this(url, ThrowableError(exception)) + + override val message: String = + "No container found at url $url." + } + + class Forbidden( + override val cause: org.readium.r2.shared.error.Error + ) : Error() { + + constructor(exception: Exception) : this(ThrowableError(exception)) + + override val message: String = + "Access to the container is forbidden." + } + } + + suspend fun create(url: Url): Try +} + +/** + * A factory to create [Container]s from archive [Resource]s. + * + * An exception must be returned if the resource type, password or media type is not supported. + */ +fun interface ArchiveFactory { + + sealed class Error : org.readium.r2.shared.error.Error { + + class FormatNotSupported( + override val cause: org.readium.r2.shared.error.Error? = null + ) : Error() { + + constructor(exception: Exception) : this(ThrowableError(exception)) + + override val message: String = + "Archive format not supported." + } + + class PasswordsNotSupported( + override val cause: org.readium.r2.shared.error.Error? = null + ) : Error() { + + constructor(exception: Exception) : this(ThrowableError(exception)) + + override val message: String = + "Password feature is not supported." + } + + class ResourceReading( + override val cause: org.readium.r2.shared.error.Error?, + val resourceException: Resource.Exception + ) : Error() { + + constructor(exception: Resource.Exception) : this(ThrowableError(exception), exception) + + override val message: String = + "An error occurred while attempting to read the resource." + } + } + + suspend fun create(resource: Resource, password: String?): Try +} + +/** + * A composite archive factory which first tries [primaryFactory] + * and falls back on [fallbackFactory] if it doesn't support the resource. + */ +class CompositeArchiveFactory( + private val primaryFactory: ArchiveFactory, + private val fallbackFactory: ArchiveFactory +) : ArchiveFactory { + + override suspend fun create(resource: Resource, password: String?): Try { + return primaryFactory.create(resource, password) + .tryRecover { error -> + if (error is ArchiveFactory.Error.FormatNotSupported) + fallbackFactory.create(resource, password) + else + Try.failure(error) + } + } +} + +/** + * A composite resource factory which first tries [primaryFactory] + * and falls back on [fallbackFactory] if it doesn't support the scheme. + */ +class CompositeResourceFactory( + private val primaryFactory: ResourceFactory, + private val fallbackFactory: ResourceFactory +) : ResourceFactory { + + override suspend fun create(url: Url): Try { + return primaryFactory.create(url) + .tryRecover { error -> + if (error is ResourceFactory.Error.SchemeNotSupported) + fallbackFactory.create(url) + else + Try.failure(error) + } + } +} + +/** + * A composite container factory which first tries [primaryFactory] + * and falls back on [fallbackFactory] if it doesn't support the scheme. + */ +class CompositeContainerFactory( + private val primaryFactory: ContainerFactory, + private val fallbackFactory: ContainerFactory +) : ContainerFactory { + + override suspend fun create(url: Url): Try { + return primaryFactory.create(url) + .tryRecover { error -> + if (error is ContainerFactory.Error.SchemeNotSupported) + fallbackFactory.create(url) + else + Try.failure(error) + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt new file mode 100644 index 0000000000..88b4935c36 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt @@ -0,0 +1,102 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import java.io.FileNotFoundException +import java.io.IOException +import java.nio.channels.Channels +import java.nio.channels.FileChannel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.extensions.read +import org.readium.r2.shared.extensions.readFully + +internal class FileChannelResource( + private val channel: FileChannel +) : Resource { + + private lateinit var _length: ResourceTry + + override suspend fun name(): ResourceTry = + ResourceTry.success(null) + + override suspend fun close() { + withContext(Dispatchers.IO) { + tryOrLog { channel.close() } + } + } + + override suspend fun read(range: LongRange?): ResourceTry = + ResourceTry.catching { + check(channel.isOpen) + if (range == null) { + return@catching readFullyThrowing() + } + + @Suppress("NAME_SHADOWING") + val range = range + .coerceFirstNonNegative() + .requireLengthFitInt() + + if (range.isEmpty()) { + return@catching ByteArray(0) + } + + readRangeThrowing(range) + } + + private suspend fun readFullyThrowing(): ByteArray = + withContext(Dispatchers.IO) { + channel.position(0) + val stream = Channels.newInputStream(channel) + stream.readFully() + } + + private suspend fun readRangeThrowing(range: LongRange): ByteArray = + withContext(Dispatchers.IO) { + channel.position(range.first) + + // The stream must not be closed here because it would close the underlying + // [FileChannel] too. Instead, [close] is responsible for that. + val stream = Channels.newInputStream(channel) + val length = range.last - range.first + 1 + stream.read(length) + } + + override suspend fun length(): ResourceTry { + if (!::_length.isInitialized) { + _length = withContext(Dispatchers.IO) { + try { + check(channel.isOpen) + Try.success(channel.size()) + } catch (e: IOException) { + Try.failure(Resource.Exception.Unavailable(e)) + } + } + } + + return _length + } + + private inline fun Try.Companion.catching(closure: () -> T): ResourceTry = + try { + success(closure()) + } catch (e: FileNotFoundException) { + failure(Resource.Exception.NotFound(e)) + } catch (e: SecurityException) { + failure(Resource.Exception.Forbidden(e)) + } catch (e: Exception) { + failure(Resource.Exception.wrap(e)) + } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. + failure(Resource.Exception.wrap(e)) + } + + override fun toString(): String = + "${javaClass.simpleName}(${channel.size()} bytes)" +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt new file mode 100644 index 0000000000..244bbc837f --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt @@ -0,0 +1,126 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import android.content.ContentResolver +import java.io.File +import java.io.FileNotFoundException +import java.io.RandomAccessFile +import java.nio.channels.Channels +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.extensions.read +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.isLazyInitialized + +/** + * A [Resource] to access a [file]. + */ +class FileResource(override val file: File) : Resource { + + private val randomAccessFile by lazy { + ResourceTry.catching { + RandomAccessFile(file, "r") + } + } + + override suspend fun name(): ResourceTry = + ResourceTry.success(file.name) + + override suspend fun close() = withContext(Dispatchers.IO) { + if (::randomAccessFile.isLazyInitialized) { + randomAccessFile.onSuccess { + tryOrLog { it.close() } + } + } + } + + override suspend fun read(range: LongRange?): ResourceTry = + withContext(Dispatchers.IO) { + ResourceTry.catching { + readSync(range) + } + } + + private fun readSync(range: LongRange?): ByteArray { + if (range == null) { + return file.readBytes() + } + + @Suppress("NAME_SHADOWING") + val range = range + .coerceFirstNonNegative() + .requireLengthFitInt() + + if (range.isEmpty()) { + return ByteArray(0) + } + + return randomAccessFile.getOrThrow().run { + channel.position(range.first) + + // The stream must not be closed here because it would close the underlying + // [FileChannel] too. Instead, [close] is responsible for that. + Channels.newInputStream(channel).run { + val length = range.last - range.first + 1 + read(length) + } + } + } + + override suspend fun length(): ResourceTry = + metadataLength?.let { Try.success(it) } + ?: read().map { it.size.toLong() } + + private val metadataLength: Long? = + tryOrNull { + if (file.isFile) + file.length() + else + null + } + + private inline fun Try.Companion.catching(closure: () -> T): ResourceTry = + try { + success(closure()) + } catch (e: FileNotFoundException) { + failure(Resource.Exception.NotFound(e)) + } catch (e: SecurityException) { + failure(Resource.Exception.Forbidden(e)) + } catch (e: Exception) { + failure(Resource.Exception.wrap(e)) + } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. + failure(Resource.Exception.wrap(e)) + } + + override fun toString(): String = + "${javaClass.simpleName}(${file.path})" +} + +class FileResourceFactory : ResourceFactory { + + override suspend fun create(url: Url): Try { + if (url.scheme != ContentResolver.SCHEME_FILE) { + return Try.failure(ResourceFactory.Error.SchemeNotSupported(url.scheme)) + } + + val file = File(url.path) + + try { + if (!file.isFile) { + return Try.failure(ResourceFactory.Error.NotAResource(url)) + } + } catch (e: Exception) { + return Try.failure(ResourceFactory.Error.Forbidden(e)) + } + + return Try.success(FileResource(file)) + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt new file mode 100644 index 0000000000..cfe7215657 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt @@ -0,0 +1,188 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import androidx.annotation.StringRes +import java.io.ByteArrayInputStream +import java.io.File +import java.nio.charset.Charset +import org.json.JSONObject +import org.readium.r2.shared.R +import org.readium.r2.shared.UserException +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.parser.xml.ElementNode +import org.readium.r2.shared.parser.xml.XmlParser +import org.readium.r2.shared.util.SuspendingCloseable + +typealias ResourceTry = Try + +/** + * Acts as a proxy to an actual resource by handling read access. + */ +interface Resource : SuspendingCloseable { + + /** + * Direct file to this resource, when available. + * + * This is meant to be used as an optimization for consumers which can't work efficiently + * with streams. However, [file] is not guaranteed to be set, for example if the resource + * underwent transformations or is being read from an archive. Therefore, consumers should + * always fallback on regular stream reading, using [read] or [ResourceInputStream]. + */ + val file: File? get() = null + + /** + * Returns the resource media type if known. + */ + suspend fun mediaType(): ResourceTry = ResourceTry.success(null) + + /** + * Returns the name of the resource if any. + */ + suspend fun name(): ResourceTry = ResourceTry.success(null) + + /** + * Returns data length from metadata if available, or calculated from reading the bytes otherwise. + * + * This value must be treated as a hint, as it might not reflect the actual bytes length. To get + * the real length, you need to read the whole resource. + */ + suspend fun length(): ResourceTry + + /** + * Reads the bytes at the given range. + * + * When [range] is null, the whole content is returned. Out-of-range indexes are clamped to the + * available length automatically. + */ + suspend fun read(range: LongRange? = null): ResourceTry + + /** + * Errors occurring while accessing a resource. + */ + sealed class Exception(@StringRes userMessageId: Int, cause: Throwable? = null) : UserException(userMessageId, cause = cause) { + + /** Equivalent to a 400 HTTP error. */ + class BadRequest(val parameters: Map = emptyMap(), cause: Throwable? = null) : + Exception(R.string.r2_shared_resource_exception_bad_request, cause) + + /** Equivalent to a 404 HTTP error. */ + class NotFound(cause: Throwable? = null) : + Exception(R.string.r2_shared_resource_exception_not_found, cause) + + /** + * Equivalent to a 403 HTTP error. + * + * This can be returned when trying to read a resource protected with a DRM that is not + * unlocked. + */ + class Forbidden(cause: Throwable? = null) : + Exception(R.string.r2_shared_resource_exception_forbidden, cause) + + /** + * Equivalent to a 503 HTTP error. + * + * Used when the source can't be reached, e.g. no Internet connection, or an issue with the + * file system. Usually this is a temporary error. + */ + class Unavailable(cause: Throwable? = null) : + Exception(R.string.r2_shared_resource_exception_unavailable, cause) + + /** + * The Internet connection appears to be offline. + */ + object Offline : Exception(R.string.r2_shared_resource_exception_offline) + + /** + * Equivalent to a 507 HTTP error. + * + * Used when the requested range is too large to be read in memory. + */ + class OutOfMemory(override val cause: OutOfMemoryError) : + Exception(R.string.r2_shared_resource_exception_out_of_memory) + + /** For any other error, such as HTTP 500. */ + class Other(cause: Throwable) : Exception(R.string.r2_shared_resource_exception_other, cause) + + companion object { + + fun wrap(e: Throwable): Exception = + when (e) { + is Exception -> e + is OutOfMemoryError -> OutOfMemory(e) + else -> Other(e) + } + } + } +} + +/** Creates a Resource that will always return the given [error]. */ +class FailureResource(private val error: Resource.Exception) : Resource { + + internal constructor(cause: Throwable) : this(Resource.Exception.wrap(cause)) + + override suspend fun read(range: LongRange?): ResourceTry = Try.failure(error) + + override suspend fun length(): ResourceTry = Try.failure(error) + + override suspend fun close() {} + + override fun toString(): String = + "${javaClass.simpleName}($error)" +} + +/** + * Maps the result with the given [transform] + * + * If the [transform] throws an [Exception], it is wrapped in a failure with Resource.Exception.Other. + */ +inline fun ResourceTry.mapCatching(transform: (value: S) -> R): ResourceTry = + try { + map(transform) + } catch (e: Exception) { + Try.failure(Resource.Exception.wrap(e)) + } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. + Try.failure(Resource.Exception.wrap(e)) + } + +inline fun ResourceTry.flatMapCatching(transform: (value: S) -> ResourceTry): ResourceTry = + mapCatching(transform).flatMap { it } + +/** + * Reads the full content as a [String]. + * + * If [charset] is null, then it is parsed from the `charset` parameter of link().type, + * or falls back on UTF-8. + */ +suspend fun Resource.readAsString(charset: Charset? = null): ResourceTry = + read().mapCatching { + String(it, charset = charset ?: Charsets.UTF_8) + } + +/** + * Reads the full content as a JSON object. + */ +suspend fun Resource.readAsJson(): ResourceTry = + readAsString(charset = Charsets.UTF_8).mapCatching { JSONObject(it) } + +/** + * Reads the full content as an XML document. + */ +suspend fun Resource.readAsXml(): ResourceTry = + read().mapCatching { XmlParser().parse(ByteArrayInputStream(it)) } + +/** + * Reads the full content as a [Bitmap]. + */ +suspend fun Resource.readAsBitmap(): ResourceTry = + read().mapCatching { + BitmapFactory.decodeByteArray(it, 0, it.size) + ?: throw kotlin.Exception("Could not decode resource as a bitmap") + } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceInputStream.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt similarity index 90% rename from readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceInputStream.kt rename to readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt index 67d2d92baa..4bf29c8bb1 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceInputStream.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt @@ -1,17 +1,15 @@ /* - * Module: r2-shared-kotlin - * Developers: Mickaël Menu - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ -package org.readium.r2.shared.fetcher +package org.readium.r2.shared.resource import java.io.IOException import java.io.InputStream import kotlinx.coroutines.runBlocking +import org.readium.r2.shared.error.getOrThrow /** * Input stream reading a [Resource]'s content. @@ -75,7 +73,7 @@ class ResourceInputStream( try { val bytes = runBlocking { resource.read(position until (position + 1)).getOrThrow() } position += 1 - return bytes.first().toInt() + return bytes.first().toUByte().toInt() } catch (e: Exception) { throw IOException("Can't read ResourceInputStream", e) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt new file mode 100644 index 0000000000..7c6d69c2c7 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import java.io.File +import java.io.IOException +import java.util.zip.ZipEntry +import java.util.zip.ZipFile +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.extensions.addPrefix +import org.readium.r2.shared.extensions.readFully +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.io.CountingInputStream + +/** + * A [Container] representing a Zip archive. + */ +interface ZipContainer : Container { + + interface Entry : Container.Entry { + + /** + * Compressed data length. + */ + val compressedLength: Long? + } +} + +internal class JavaZipContainer(private val archive: ZipFile, source: File) : ZipContainer { + + private inner class FailureEntry(override val path: String) : ZipContainer.Entry { + + override val compressedLength: Long? = null + + override suspend fun name(): ResourceTry = + Try.failure(Resource.Exception.NotFound()) + + override suspend fun length(): ResourceTry = + Try.failure(Resource.Exception.NotFound()) + + override suspend fun read(range: LongRange?): ResourceTry = + Try.failure(Resource.Exception.NotFound()) + + override suspend fun close() { + } + } + + private inner class Entry(private val entry: ZipEntry) : ZipContainer.Entry { + + override val path: String = + entry.name.addPrefix("/") + + override suspend fun name(): ResourceTry = + ResourceTry.success(File(path).name) + + override suspend fun length(): Try = + entry.size.takeUnless { it == -1L } + ?.let { Try.success(it) } + ?: Try.failure(Resource.Exception.Other(Exception("Unsupported operation"))) + + override val compressedLength: Long? = + if (entry.method == ZipEntry.STORED || entry.method == -1) + null + else + entry.compressedSize.takeUnless { it == -1L } + + override suspend fun read(range: LongRange?): Try = + try { + withContext(Dispatchers.IO) { + val bytes = + if (range == null) + readFully() + else + readRange(range) + Try.success(bytes) + } + } catch (e: IOException) { + Try.failure(Resource.Exception.Unavailable(e)) + } catch (e: Exception) { + Try.failure(Resource.Exception.wrap(e)) + } + + private suspend fun readFully(): ByteArray = + withContext(Dispatchers.IO) { + archive.getInputStream(entry) + .use { + it.readFully() + } + } + + private fun readRange(range: LongRange): ByteArray = + stream(range.first).readRange(range) + + /** + * Reading an entry in chunks (e.g. from the HTTP server) can be really slow if the entry + * is deflated in the archive, because we can't jump to an arbitrary offset in a deflated + * stream. This means that we need to read from the start of the entry for each chunk. + * + * To alleviate this issue, we cache a stream which will be reused as long as the chunks are + * requested in order. + * + * See this issue for more info: https://github.com/readium/r2-shared-kotlin/issues/129 + */ + private fun stream(fromIndex: Long): CountingInputStream { + // Reuse the current stream if it didn't exceed the requested index. + stream + ?.takeIf { it.count <= fromIndex } + ?.let { return it } + + stream?.close() + + return CountingInputStream(archive.getInputStream(entry)) + .also { stream = it } + } + + private var stream: CountingInputStream? = null + + override suspend fun close() { + withContext(Dispatchers.IO) { + tryOrLog { stream?.close() } + } + } + } + + override val file: File = source + + override suspend fun name(): ResourceTry = + ResourceTry.success(file.name) + + override suspend fun entries(): List = + archive.entries().toList() + .filterNot { it.isDirectory } + .mapNotNull { Entry(it) } + + override suspend fun entry(path: String): Container.Entry { + return archive.getEntry(path.removePrefix("/")) + ?.let { Entry(it) } + ?: FailureEntry(path) + } + + override suspend fun close() { + tryOrLog { + withContext(Dispatchers.IO) { + archive.close() + } + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt index 8d8dd13579..7066f6bbdd 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt @@ -8,10 +8,7 @@ package org.readium.r2.shared.util -import org.readium.r2.shared.publication.asset.FileAsset - -@Deprecated("Renamed into `FileAsset`", ReplaceWith("FileAsset"), level = DeprecationLevel.ERROR) -typealias File = FileAsset +import org.readium.r2.shared.error.Try /** * Returns the encapsulated result of the given transform function applied to the encapsulated |Throwable] exception diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt deleted file mode 100644 index b38243c739..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.util - -/** A [Result] type which can be used as a return type. */ -sealed class Try { - - companion object { - /** Returns an instance that encapsulates the given value as successful value. */ - fun success(success: Success): Try = Success(success) - - /** Returns the encapsulated Throwable exception if this instance represents failure or null if it is success. */ - fun failure(failure: Failure): Try = Failure(failure) - } - - abstract val isSuccess: Boolean - abstract val isFailure: Boolean - - /** - * Returns the encapsulated value if this instance represents success - * or throws the encapsulated Throwable exception if it is failure. - */ - abstract fun getOrThrow(): Success - - /** Returns the encapsulated value if this instance represents success or null if it is failure. */ - abstract fun getOrNull(): Success? - - /** Returns the encapsulated [Throwable] exception if this instance represents failure or null if it is success. */ - abstract fun exceptionOrNull(): Failure? - - class Success(val value: S) : Try() { - override val isSuccess: Boolean get() = true - override val isFailure: Boolean get() = false - override fun getOrThrow(): S = value - override fun getOrNull(): S? = value - override fun exceptionOrNull(): F? = null - } - - class Failure(val exception: F) : Try() { - override val isSuccess: Boolean get() = false - override val isFailure: Boolean get() = true - override fun getOrThrow(): S { throw exception } - override fun getOrNull(): S? = null - override fun exceptionOrNull(): F = exception - } - - /** - * Returns the encapsulated result of the given transform function applied to the encapsulated value - * if this instance represents success or the original encapsulated [Throwable] exception if it is failure. - */ - inline fun map(transform: (value: Success) -> R): Try = - if (isSuccess) - success(transform(getOrThrow())) - else - failure(exceptionOrNull()!!) - - /** - * Returns the encapsulated result of the given transform function applied to the encapsulated failure - * if this instance represents failure or the original encapsulated success value if it is a success. - */ - inline fun mapFailure(transform: (value: Failure) -> F): Try = - if (isSuccess) - success(getOrThrow()) - else - failure(transform(exceptionOrNull()!!)) - - /** - * Returns the result of [onSuccess] for the encapsulated value if this instance represents success or - * the result of [onFailure] function for the encapsulated [Throwable] exception if it is failure. - */ - inline fun fold(onSuccess: (value: Success) -> R, onFailure: (exception: Failure) -> R): R = - if (isSuccess) - onSuccess(getOrThrow()) - else - onFailure(exceptionOrNull()!!) - - /** - * Performs the given action on the encapsulated value if this instance represents success. - * Returns the original [Try] unchanged. - */ - inline fun onSuccess(action: (value: Success) -> Unit): Try { - if (isSuccess) action(getOrThrow()) - return this - } - - /** - * Performs the given action on the encapsulated [Throwable] exception if this instance represents failure. - * Returns the original [Try] unchanged. - */ - inline fun onFailure(action: (exception: Failure) -> Unit): Try { - if (isFailure) action(exceptionOrNull()!!) - return this - } -} - -/** - * Returns the encapsulated value if this instance represents success or the [defaultValue] if it is failure. - */ -fun Try.getOrDefault(defaultValue: R): R = - if (isSuccess) - getOrThrow() - else - defaultValue - -/** - * Returns the encapsulated value if this instance represents success or the result of [onFailure] function - * for the encapsulated [Throwable] exception if it is failure. - */ -inline fun Try.getOrElse(onFailure: (exception: F) -> R): R = - if (isSuccess) - getOrThrow() - else - onFailure(exceptionOrNull()!!) - -inline fun Try.flatMap(transform: (value: S) -> Try): Try = - if (isSuccess) - transform(getOrThrow()) - else - Try.failure(exceptionOrNull()!!) - -/** - * Returns the encapsulated result of the given transform function applied to the encapsulated |Throwable] exception - * if this instance represents failure or the original encapsulated value if it is success. - */ -inline fun Try.tryRecover(transform: (exception: F) -> Try): Try = - if (isSuccess) - Try.success(getOrThrow()) - else - transform(exceptionOrNull()!!) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt index 761bd3186a..da6dff8597 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt @@ -6,49 +6,61 @@ package org.readium.r2.shared.util +import android.net.Uri import java.io.File -import java.net.URL -import org.readium.r2.shared.extensions.extension import org.readium.r2.shared.extensions.tryOrNull /** * A Uniform Resource Locator. */ @JvmInline -value class Url internal constructor(internal val url: URL) { +value class Url private constructor(internal val uri: Uri) { - val protocol: String - get() = url.protocol + val scheme: String + get() = uri.scheme!! val authority: String - get() = url.authority + get() = uri.authority!! val path: String - get() = url.path + get() = uri.path!! - val file: String - get() = url.file + val filename: String + get() = File(path).name val extension: String? - get() = url.extension + get() = File(path).extension + .takeIf { it.isNotEmpty() } override fun toString(): String = - url.toString() + uri.toString() companion object { operator fun invoke(url: String): Url? = - tryOrNull { Url(URL(url)) } + invoke(Uri.parse(url)) + + internal operator fun invoke(uri: Uri): Url? = + tryOrNull { + requireNotNull(uri.scheme) + requireNotNull(uri.authority) + requireNotNull(uri.path) + Url(uri) + } } } -fun Url.toURL(): URL = - url - fun Url.isFile(): Boolean = - protocol == "file" + scheme == "file" -fun Url.readBytes() = url.openStream().use { it.readBytes() } +fun Url.isHttp(): Boolean = + scheme == "http" || scheme == "https" fun File.toUrl(): Url = - Url(toURI().toURL()!!) + Url(Uri.fromFile(this))!! + +fun Uri.toUrl(): Url? = + Url.invoke(this) + +fun Url.toUri() = + uri diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt deleted file mode 100644 index 3582989957..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/Archive.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.util.archive - -import java.io.File -import java.io.IOException -import java.net.URL -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.readium.r2.shared.extensions.tryOr -import org.readium.r2.shared.util.SuspendingCloseable -import org.readium.r2.shared.util.Url - -interface ArchiveFactory { - - /** Opens an archive from a local [file]. */ - suspend fun open(file: File, password: String?): Archive - - /** Opens an archive from a local or remote [URL]. */ - suspend fun open(url: Url, password: String?): Archive = - if (url.protocol == "file") { - open(File(url.path), password) - } else { - throw IOException("Cannot access ZIP archives through protocol ${url.protocol}.") - } -} - -class DefaultArchiveFactory : ArchiveFactory { - - private val javaZipFactory by lazy { JavaZipArchiveFactory() } - private val explodedArchiveFactory by lazy { ExplodedArchiveFactory() } - - /** Opens a ZIP or exploded archive. */ - override suspend fun open(file: File, password: String?): Archive = withContext(Dispatchers.IO) { - if (tryOr(false) { file.isDirectory }) { - explodedArchiveFactory.open(file, password) - } else { - javaZipFactory.open(file, password) - } - } -} - -class CompositeArchiveFactory( - private val primaryFactory: ArchiveFactory, - private val fallbackFactory: ArchiveFactory -) : ArchiveFactory { - - override suspend fun open(file: File, password: String?): Archive = - try { - primaryFactory.open(file, password) - } catch (e: Exception) { - fallbackFactory.open(file, password) - } - - override suspend fun open(url: Url, password: String?): Archive = - try { - primaryFactory.open(url, password) - } catch (e: Exception) { - fallbackFactory.open(url, password) - } -} - -/** - * Represents an immutable archive. - */ -interface Archive : SuspendingCloseable { - - /** - * Holds an archive entry's metadata. - */ - interface Entry : SuspendingCloseable { - - /** - * Absolute path to the entry in the archive. - * It MUST start with /. - */ - val path: String - - /** - * Uncompressed data length. - */ - val length: Long? - - /** - * Compressed data length. - */ - val compressedLength: Long? - - /** - * Reads the whole content of this entry. - * When [range] is null, the whole content is returned. Out-of-range indexes are clamped to the - * available length automatically. - */ - suspend fun read(range: LongRange? = null): ByteArray - } - - /** List of all the archived file entries. */ - suspend fun entries(): List - - /** Gets the entry at the given `path`. */ - suspend fun entry(path: String): Entry -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/ExplodedArchive.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/ExplodedArchive.kt deleted file mode 100644 index b6b89d0d01..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/ExplodedArchive.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.util.archive - -import java.io.File -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.readium.r2.shared.extensions.isParentOf -import org.readium.r2.shared.extensions.readFully -import org.readium.r2.shared.extensions.readRange -import org.readium.r2.shared.extensions.tryOr - -/** - * An archive exploded on the file system as a directory. - */ -internal class ExplodedArchive(private val directory: File) : Archive { - - private inner class Entry(private val file: File) : Archive.Entry { - - override val path: String get() = file.relativeTo(directory).path - - override val length: Long? = file.length() - - override val compressedLength: Long? = null - - override suspend fun read(range: LongRange?): ByteArray { - val stream = withContext(Dispatchers.IO) { - file.inputStream() - } - - return stream.use { - if (range == null) - it.readFully() - else - it.readRange(range) - } - } - - override suspend fun close() {} - } - - override suspend fun entries(): List = - directory.walk() - .filter { it.isFile } - .map { Entry(it) } - .toList() - - override suspend fun entry(path: String): Archive.Entry { - val file = File(directory, path) - - if (!directory.isParentOf(file) || !file.isFile) - throw Exception("No file entry at path $path.") - - return Entry(file) - } - - override suspend fun close() {} -} - -internal class ExplodedArchiveFactory : ArchiveFactory { - - override suspend fun open(file: File, password: String?): Archive = withContext(Dispatchers.IO) { - file.takeIf { tryOr(false) { it.isDirectory } } - ?.let { ExplodedArchive(it) } - ?: throw IllegalArgumentException("[path] must be a directory to be opened as an exploded archive") - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/JavaZip.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/JavaZip.kt deleted file mode 100644 index c0e5901e23..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/JavaZip.kt +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -@file:OptIn(InternalReadiumApi::class) - -package org.readium.r2.shared.util.archive - -import java.io.File -import java.util.zip.ZipEntry -import java.util.zip.ZipFile -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.readium.r2.shared.InternalReadiumApi -import org.readium.r2.shared.extensions.readFully -import org.readium.r2.shared.util.io.CountingInputStream - -@OptIn(InternalReadiumApi::class) -internal class JavaZip(private val archive: ZipFile) : Archive { - - private inner class Entry(private val entry: ZipEntry) : Archive.Entry { - override val path: String get() = entry.name - - override val length: Long? get() = entry.size.takeUnless { it == -1L } - - override val compressedLength: Long? - get() = - if (entry.method == ZipEntry.STORED || entry.method == -1) - null - else - entry.compressedSize.takeUnless { it == -1L } - - override suspend fun read(range: LongRange?): ByteArray = - withContext(Dispatchers.IO) { - if (range == null) - readFully() - else - readRange(range) - } - - private suspend fun readFully(): ByteArray = - archive.getInputStream(entry).use { - it.readFully() - } - - private fun readRange(range: LongRange): ByteArray = - stream(range.first).readRange(range) - - /** - * Reading an entry in chunks (e.g. from the HTTP server) can be really slow if the entry - * is deflated in the archive, because we can't jump to an arbitrary offset in a deflated - * stream. This means that we need to read from the start of the entry for each chunk. - * - * To alleviate this issue, we cache a stream which will be reused as long as the chunks are - * requested in order. - * - * See this issue for more info: https://github.com/readium/r2-shared-kotlin/issues/129 - */ - private fun stream(fromIndex: Long): CountingInputStream { - // Reuse the current stream if it didn't exceed the requested index. - stream - ?.takeIf { it.count <= fromIndex } - ?.let { return it } - - stream?.close() - - return CountingInputStream(archive.getInputStream(entry)) - .also { stream = it } - } - - private var stream: CountingInputStream? = null - - override suspend fun close() { - withContext(Dispatchers.IO) { - stream?.close() - } - } - } - - override suspend fun entries(): List = - archive.entries().toList().filterNot { it.isDirectory }.mapNotNull { Entry(it) } - - override suspend fun entry(path: String): Archive.Entry { - val entry = archive.getEntry(path) - ?: throw Exception("No file entry at path $path.") - - return Entry(entry) - } - - override suspend fun close() = withContext(Dispatchers.IO) { - archive.close() - } -} - -internal class JavaZipArchiveFactory : ArchiveFactory { - - override suspend fun open(file: File, password: String?): Archive = withContext(Dispatchers.IO) { - JavaZip(ZipFile(file)) - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZip.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt similarity index 53% rename from readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZip.kt rename to readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt index 69a5825b39..7c65e9c511 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZip.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt @@ -9,25 +9,39 @@ package org.readium.r2.shared.util.archive.channel import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.extensions.readFully -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.archive.Archive -import org.readium.r2.shared.util.archive.ArchiveFactory +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.resource.* import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipArchiveEntry import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipFile import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel -import org.readium.r2.shared.util.http.DefaultHttpClient -import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.io.CountingInputStream -internal class ChannelZip( - private val archive: ZipFile -) : Archive { +internal class ChannelZipContainer( + private val archive: ZipFile, + private val fetchName: suspend () -> ResourceTry +) : ZipContainer { - private inner class Entry(private val entry: ZipArchiveEntry) : Archive.Entry { - override val path: String get() = entry.name + private inner class FailureEntry( + override val path: String + ) : ZipContainer.Entry, Resource by FailureResource(Resource.Exception.NotFound()) { - override val length: Long? get() = entry.size.takeUnless { it == -1L } + override val compressedLength: Long? = null + } + + private inner class Entry(private val entry: ZipArchiveEntry) : ZipContainer.Entry { + + override val path: String get() = entry.name.addPrefix("/") + + override suspend fun name(): ResourceTry = + ResourceTry.success(File(path).name) + + override suspend fun length(): ResourceTry = + entry.size.takeUnless { it == -1L } + ?.let { Try.success(it) } + ?: Try.failure(Resource.Exception.Other(UnsupportedOperationException())) override val compressedLength: Long? get() = @@ -36,12 +50,18 @@ internal class ChannelZip( else entry.compressedSize.takeUnless { it == -1L } - override suspend fun read(range: LongRange?): ByteArray = + override suspend fun read(range: LongRange?): ResourceTry = withContext(Dispatchers.IO) { - if (range == null) - readFully() - else - readRange(range) + try { + val bytes = + if (range == null) + readFully() + else + readRange(range) + Try.success(bytes) + } catch (e: Exception) { + Try.failure(Resource.Exception.wrap(e)) + } } private suspend fun readFully(): ByteArray = @@ -85,50 +105,67 @@ internal class ChannelZip( private var stream: CountingInputStream? = null override suspend fun close() { - withContext(Dispatchers.IO) { - stream?.close() + tryOrLog { + withContext(Dispatchers.IO) { + stream?.close() + } } } } - override suspend fun entries(): List = - archive.entries.toList().filterNot { it.isDirectory }.mapNotNull { Entry(it) } + override suspend fun name(): ResourceTry { + return fetchName.invoke() + } - override suspend fun entry(path: String): Archive.Entry { - val entry = archive.getEntry(path) - ?: throw Exception("No file entry at path $path.") + override suspend fun entries(): List = + archive.entries.toList() + .filterNot { it.isDirectory } + .mapNotNull { Entry(it) } - return Entry(entry) + override suspend fun entry(path: String): Container.Entry { + return archive.getEntry(path.removePrefix("/")) + ?.takeUnless { it.isDirectory } + ?.let { Entry(it) } + ?: FailureEntry(path) } - override suspend fun close() = withContext(Dispatchers.IO) { - archive.close() + override suspend fun close() { + withContext(Dispatchers.IO) { + tryOrLog { archive.close() } + } } } /** * An [ArchiveFactory] able to open a ZIP archive served through an HTTP server. - * - * The given [httpClient] is used to perform the HTTP requests. */ -class ChannelZipArchiveFactory( - private val httpClient: HttpClient = DefaultHttpClient() -) : ArchiveFactory { - - override suspend fun open(file: File, password: String?): Archive = withContext(Dispatchers.IO) { - throw Exception("RemoteZipArchiveFactory doesn't support files.") - } +class ChannelZipArchiveFactory : ArchiveFactory { + + override suspend fun create( + resource: Resource, + password: String? + ): Try { + if (password != null) { + return Try.failure(ArchiveFactory.Error.PasswordsNotSupported()) + } - override suspend fun open(url: Url, password: String?): Archive = withContext(Dispatchers.IO) { - val httpChannel = HttpChannel(url.toString(), httpClient) - val channel = wrapBaseChannel(httpChannel) - ChannelZip(ZipFile(channel, true)) + return try { + val resourceChannel = ResourceChannel(resource) + val channel = wrapBaseChannel(resourceChannel) + val zipFile = ZipFile(channel, true) + val channelZip = ChannelZipContainer(zipFile, resource::name) + Try.success(channelZip) + } catch (e: Resource.Exception) { + Try.failure(ArchiveFactory.Error.ResourceReading(e)) + } catch (e: Exception) { + Try.failure(ArchiveFactory.Error.FormatNotSupported(e)) + } } - internal fun openFile(file: File): Archive { + internal fun openFile(file: File): Container { val fileChannel = FileChannelAdapter(file, "r") val channel = wrapBaseChannel(fileChannel) - return ChannelZip(ZipFile(channel)) + return ChannelZipContainer(ZipFile(channel)) { Try.success(file.name) } } private fun wrapBaseChannel(channel: SeekableByteChannel): SeekableByteChannel { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt index b95e4fe87a..deddfda83a 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt @@ -12,9 +12,10 @@ import java.nio.ByteBuffer import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.readSafe import org.readium.r2.shared.extensions.tryOrLog -import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel import org.readium.r2.shared.util.http.HttpClient diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt new file mode 100644 index 0000000000..b6d0fb51d7 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt @@ -0,0 +1,103 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.archive.channel + +import java.io.IOException +import java.nio.ByteBuffer +import kotlinx.coroutines.* +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.archive.channel.jvm.ClosedChannelException +import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException +import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel + +internal class ResourceChannel( + private val resource: Resource +) : SeekableByteChannel { + + private val coroutineScope: CoroutineScope = + MainScope() + + private var isClosed: Boolean = + false + + private var position: Long = + 0 + + override fun close() { + if (isClosed) { + return + } + + isClosed = true + coroutineScope.launch { resource.close() } + } + + override fun isOpen(): Boolean { + return !isClosed + } + + override fun read(dst: ByteBuffer): Int { + return runBlocking { + if (isClosed) { + throw ClosedChannelException() + } + + withContext(Dispatchers.IO) { + val size = resource.length() + .getOrElse { throw IOException("Content length not available.", it) } + + if (position >= size) { + return@withContext - 1 + } + + val available = size - position + val toBeRead = dst.remaining().coerceAtMost(available.toInt()) + check(toBeRead > 0) + val bytes = resource.read(position until position + toBeRead) + .mapFailure { IOException(it) } + .getOrThrow() + check(bytes.size == toBeRead) + dst.put(bytes, 0, toBeRead) + position += toBeRead + return@withContext toBeRead + } + } + } + + override fun write(buffer: ByteBuffer): Int { + throw NonWritableChannelException() + } + + override fun position(): Long { + return position + } + + override fun position(newPosition: Long): SeekableByteChannel { + if (isClosed) { + throw ClosedChannelException() + } + + position = newPosition + return this + } + + override fun size(): Long { + if (isClosed) { + throw ClosedChannelException() + } + + return runBlocking { resource.length() } + .mapFailure { IOException(it) } + .getOrThrow() + } + + override fun truncate(size: Long): SeekableByteChannel { + throw NonWritableChannelException() + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt index 639e9cea20..fcfdfc62d4 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt @@ -14,12 +14,12 @@ import java.net.URL import kotlin.time.Duration import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.error.tryRecover import org.readium.r2.shared.util.http.HttpRequest.Method import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.mediatype.sniffMediaType -import org.readium.r2.shared.util.tryRecover +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber /** @@ -32,7 +32,7 @@ import timber.log.Timber * @param readTimeout Timeout used when reading the input stream. A null timeout is interpreted * as the default value, while a timeout of zero as an infinite timeout. */ -class DefaultHttpClient constructor( +class DefaultHttpClient( private val userAgent: String? = null, private val additionalHeaders: Map = mapOf(), private val connectTimeout: Duration? = null, @@ -112,6 +112,9 @@ class DefaultHttpClient constructor( suspend fun onRequestFailed(request: HttpRequest, error: HttpException) {} } + private val mediaTypeRetriever: MediaTypeRetriever = + MediaTypeRetriever() + // We are using Dispatchers.IO but we still get this warning... @Suppress("BlockingMethodInNonBlockingContext", "NAME_SHADOWING") override suspend fun stream(request: HttpRequest): HttpTry { @@ -138,18 +141,29 @@ class DefaultHttpClient constructor( // Reads the full body, since it might contain an error representation such as // JSON Problem Details or OPDS Authentication Document - val body = connection.errorStream.use { it.readBytes() } - val mediaType = connection.sniffMediaType(bytes = { body }) + val body = connection.errorStream?.use { it.readBytes() } + val mediaType = body?.let { + mediaTypeRetriever.retrieve( + connection = connection, + bytes = { it } + ) + } throw HttpException(kind, mediaType, body) } + val mediaType = + mediaTypeRetriever.retrieve( + connection = connection + ) ?: MediaType.BINARY + val response = HttpResponse( request = request, url = connection.url.toString(), statusCode = statusCode, headers = connection.safeHeaders, - mediaType = connection.sniffMediaType() ?: MediaType.BINARY, + mediaType = mediaType ) + callback.onResponseReceived(request, response) if (statusCode in 300..399) { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt index 4f18fbb3ab..ff64416f70 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt @@ -11,8 +11,8 @@ import java.nio.charset.Charset import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.json.JSONObject -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.util.mediatype.MediaType /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt index 66077e5802..ffb7e715dd 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt @@ -14,8 +14,8 @@ import java.util.concurrent.CancellationException import org.json.JSONObject import org.readium.r2.shared.R import org.readium.r2.shared.UserException +import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.tryOrLog -import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType typealias HttpTry = Try diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt new file mode 100644 index 0000000000..996745b6ad --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt @@ -0,0 +1,70 @@ +/* + * Copyright 2021 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.http + +import android.webkit.URLUtil +import org.readium.r2.shared.error.getOrDefault +import org.readium.r2.shared.fetcher.FailureResource +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.resource.Resource +import timber.log.Timber + +/** + * Fetches remote resources through HTTP. + * + * Since this fetcher is used when doing progressive download streaming (e.g. audiobook), the HTTP + * byte range requests are open-ended and reused. This helps to avoid issuing too many requests. + * + * @param client HTTP client used to perform HTTP requests. + * @param baseUrl Base URL from which relative HREF are served. + * @param links A set of links that are known to be available through this fetcher. + */ +class HttpFetcher( + private val client: HttpClient, + private val baseUrl: String? = null, + private val links: List = emptyList(), +) : Fetcher { + + override suspend fun links(): List = links + + override fun get(link: Link): Fetcher.Resource { + val url = link.toUrl(baseUrl) + + return if (url == null || !URLUtil.isNetworkUrl(url)) { + val cause = IllegalArgumentException("Invalid HREF: ${link.href}, produced URL: $url") + Timber.e(cause) + FailureResource(link, error = Resource.Exception.BadRequest(cause = cause)) + } else { + HttpResource(link, url, client) + } + } + + override suspend fun close() {} + + /** Provides access to an external URL. */ + class HttpResource( + private val link: Link, + private val resource: org.readium.r2.shared.util.http.HttpResource + ) : Resource by resource, Fetcher.Resource { + + companion object { + + operator fun invoke( + link: Link, + url: String, + client: HttpClient, + ): HttpResource = + HttpResource(link, HttpResource(client, url)) + } + + override suspend fun link(): Link = + link.copy( + type = resource.mediaType().getOrDefault(link.type) + ) + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt new file mode 100644 index 0000000000..6d6dc4ad35 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt @@ -0,0 +1,144 @@ +package org.readium.r2.shared.util.http + +import java.io.File +import java.io.InputStream +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.extensions.read +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.util.io.CountingInputStream + +/** Provides access to an external URL. */ +class HttpResource( + private val client: HttpClient, + private val url: String, + private val maxSkipBytes: Long = MAX_SKIP_BYTES +) : Resource { + + override suspend fun name(): ResourceTry = + headResponse().map { + it.valuesForHeader("Content-Disposition") + .flatMap { it.split(";") } + .map { it.trim() } + .firstOrNull { it.startsWith("filename=") } + ?.dropWhile { it != '=' } + ?.trim('=', '"') + ?.let { File(it).name } + } + + override suspend fun mediaType(): ResourceTry = + headResponse().map { + it.mediaType.toString() + } + + override suspend fun length(): ResourceTry = + headResponse().flatMap { + val contentLength = it.contentLength + return if (contentLength != null) { + Try.success(contentLength) + } else { + Try.failure(Resource.Exception.Unavailable()) + } + } + + override suspend fun close() {} + + override suspend fun read(range: LongRange?): ResourceTry = withContext(Dispatchers.IO) { + try { + stream(range?.first.takeUnless { it == 0L }).map { stream -> + if (range != null) { + stream.read(range.count().toLong()) + } else { + stream.readBytes() + } + } + } catch (e: HttpException) { + Try.failure(Resource.Exception.wrapHttp(e)) + } catch (e: Exception) { + Try.failure(Resource.Exception.wrap(e)) + } + } + + /** Cached HEAD response to get the expected content length and other metadata. */ + private lateinit var _headResponse: ResourceTry + + private suspend fun headResponse(): ResourceTry { + if (::_headResponse.isInitialized) + return _headResponse + + _headResponse = client.fetch(HttpRequest(url, method = HttpRequest.Method.HEAD)) + .map { it.response } + .mapFailure { Resource.Exception.wrapHttp(it) } + + return _headResponse + } + + /** + * Returns an HTTP stream for the resource, starting at the [from] byte offset. + * + * The stream is cached and reused for next calls, if the next [from] offset is not too far + * and in a forward direction. + */ + private suspend fun stream(from: Long? = null): ResourceTry { + val stream = inputStream + if (from != null && stream != null) { + tryOrLog { + val bytesToSkip = from - (inputStreamStart + stream.count) + if (bytesToSkip in 0 until maxSkipBytes) { + stream.skip(bytesToSkip) + return Try.success(stream) + } + } + } + tryOrLog { inputStream?.close() } + + val request = HttpRequest(url) { + from?.let { setRange(from..-1) } + } + + return client.stream(request) + .flatMap { response -> + if (from != null && response.response.statusCode != 206 + ) { + val exception = Exception("Server seems not to support range requests.") + Try.failure(HttpException.wrap(exception)) + } else { + Try.success(response) + } + } + .map { CountingInputStream(it.body) } + .mapFailure { Resource.Exception.wrapHttp(it) } + .onSuccess { + inputStream = it + inputStreamStart = from ?: 0 + } + } + + private var inputStream: CountingInputStream? = null + private var inputStreamStart = 0L + + private fun Resource.Exception.Companion.wrapHttp(e: HttpException): Resource.Exception = + when (e.kind) { + HttpException.Kind.MalformedRequest, HttpException.Kind.BadRequest -> + Resource.Exception.BadRequest(cause = e) + HttpException.Kind.Timeout, HttpException.Kind.Offline -> + Resource.Exception.Unavailable(e) + HttpException.Kind.Unauthorized, HttpException.Kind.Forbidden -> + Resource.Exception.Forbidden(e) + HttpException.Kind.NotFound -> + Resource.Exception.NotFound(e) + HttpException.Kind.Cancelled -> + Resource.Exception.Unavailable(e) + HttpException.Kind.MalformedResponse, HttpException.Kind.ClientError, HttpException.Kind.ServerError, HttpException.Kind.Other -> + Resource.Exception.Other(e) + } + + companion object { + + private const val MAX_SKIP_BYTES: Long = 8192 + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt new file mode 100644 index 0000000000..0b4042fc89 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.http + +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceFactory +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.isHttp + +class HttpResourceFactory( + private val httpClient: HttpClient +) : ResourceFactory { + + override suspend fun create(url: Url): Try { + if (!url.isHttp()) { + return Try.failure(ResourceFactory.Error.SchemeNotSupported(url.scheme)) + } + + val resource = HttpResource(httpClient, url.toString()) + return Try.success(resource) + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt new file mode 100644 index 0000000000..3d05d51d22 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.http + +import java.net.HttpURLConnection +import org.readium.r2.shared.extensions.extension +import org.readium.r2.shared.resource.DefaultArchiveFactory +import org.readium.r2.shared.util.mediatype.BytesSnifferContextFactory +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever + +/** + * Resolves the format for this [HttpURLConnection], with optional extra file extension and media type + * hints. + */ +suspend fun MediaTypeRetriever.retrieve( + connection: HttpURLConnection, + bytes: (() -> ByteArray)?, + mediaTypes: List, + fileExtensions: List, +): MediaType? { + val allMediaTypes = mediaTypes.toMutableList() + val allFileExtensions = fileExtensions.toMutableList() + + // The value of the `Content-Type` HTTP header. + connection.contentType?.let { + allMediaTypes.add(0, it) + } + + // The URL file extension. + connection.url.extension?.let { + allFileExtensions.add(0, it) + } + + // TODO: The suggested filename extension, part of the HTTP header `Content-Disposition`. + + return if (bytes != null) { + doRetrieve( + { + BytesSnifferContextFactory(DefaultArchiveFactory()) + .createContext(bytes.invoke(), mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) + }, + mediaTypes = allMediaTypes, + fileExtensions = allFileExtensions + ) + } else { + retrieve(mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) + } +} + +/** + * Resolves the format for this [HttpURLConnection], with optional extra file extension and media type + * hints. + */ +suspend fun MediaTypeRetriever.retrieve( + connection: HttpURLConnection, + bytes: (() -> ByteArray)? = null, + mediaType: String? = null, + fileExtension: String? = null +) = retrieve(connection, bytes, listOfNotNull(mediaType), listOfNotNull(fileExtension)) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt index 6c7d3d5d58..4a6afc0242 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt @@ -6,13 +6,23 @@ package org.readium.r2.shared.util.mediatype +import java.io.File import java.net.HttpURLConnection import org.readium.r2.shared.extensions.extension +import org.readium.r2.shared.resource.DefaultArchiveFactory /** * Resolves the format for this [HttpURLConnection], with optional extra file extension and media type * hints. */ +@Deprecated( + "Use the MediaTypeRetriever extension instead.", + replaceWith = ReplaceWith( + "mediaTypeRetriever.retrieve(connection, bytes, mediaTypes, fileExtensions)", + "org.readium.r2.shared.util.http.retrieve" + ), + level = DeprecationLevel.ERROR +) suspend fun HttpURLConnection.sniffMediaType( bytes: (() -> ByteArray)? = null, mediaTypes: List = emptyList(), @@ -34,9 +44,31 @@ suspend fun HttpURLConnection.sniffMediaType( // TODO: The suggested filename extension, part of the HTTP header `Content-Disposition`. + val mediaTypeRetriever = MediaTypeRetriever(sniffers = sniffers) + return if (bytes != null) { - MediaType.ofBytes(bytes, mediaTypes = allMediaTypes, fileExtensions = allFileExtensions, sniffers = sniffers) + mediaTypeRetriever.doRetrieve( + { + BytesSnifferContextFactory(DefaultArchiveFactory()) + .createContext(bytes.invoke(), mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) + }, + mediaTypes = allMediaTypes, + fileExtensions = allFileExtensions + ) } else { - MediaType.of(mediaTypes = allMediaTypes, fileExtensions = allFileExtensions, sniffers = sniffers) + mediaTypeRetriever.retrieve(mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) } } + +/** +* Sniffs the media type of the file. +* +* If unknown, fallback on `MediaType.BINARY`. +*/ +@Deprecated( + "Use MediaTypeRetriever explicitly.", + replaceWith = ReplaceWith("mediaTypeRetriever.retrieve(mediaType = mediaTypeHint)"), + level = DeprecationLevel.ERROR +) +suspend fun File.mediaType(mediaTypeHint: String? = null): MediaType = + MediaTypeRetriever().retrieve(this, mediaType = mediaTypeHint) ?: MediaType.BINARY diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt index 69eb194f93..efea8bbdcb 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt @@ -11,13 +11,9 @@ package org.readium.r2.shared.util.mediatype import android.content.ContentResolver import android.net.Uri -import android.provider.MediaStore -import android.webkit.MimeTypeMap import java.io.File import java.nio.charset.Charset import java.util.* -import org.readium.r2.shared.BuildConfig.DEBUG -import org.readium.r2.shared.extensions.queryProjection import org.readium.r2.shared.extensions.tryOrNull /** @@ -122,8 +118,10 @@ class MediaType( * * Non-significant parameters are also discarded. */ - suspend fun canonicalMediaType(): MediaType = - of(mediaType = toString()) ?: this + @Deprecated("Use MediaTypeRetriever instead", replaceWith = ReplaceWith("mediaTypeRetriever.canonicalMediaType()"), level = DeprecationLevel.ERROR) + suspend fun canonicalMediaType(): MediaType { + TODO() + } /** The string representation of this media type. */ override fun toString(): String { @@ -346,105 +344,120 @@ class MediaType( * Resolves a format from a single file extension and media type hint, without checking the actual * content. */ + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) + @Suppress("UNUSED_PARAMETER") suspend fun of( mediaType: String? = null, fileExtension: String? = null, sniffers: List = MediaType.sniffers ): MediaType? { - if (DEBUG && mediaType?.startsWith("/") == true) { - throw IllegalArgumentException("The provided media type is incorrect: $mediaType. To pass a file path, you must wrap it in a File().") - } - return of(content = null, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension), sniffers = sniffers) + TODO() } /** * Resolves a format from file extension and media type hints, without checking the actual * content. */ + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) + @Suppress("UNUSED_PARAMETER") suspend fun of( mediaTypes: List, fileExtensions: List, sniffers: List = MediaType.sniffers ): MediaType? { - return of(content = null, mediaTypes = mediaTypes, fileExtensions = fileExtensions, sniffers = sniffers) + TODO() } /** * Resolves a format from a local file path. */ + @Suppress("UNUSED_PARAMETER") + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) suspend fun ofFile( file: File, mediaType: String? = null, fileExtension: String? = null, sniffers: List = MediaType.sniffers ): MediaType? { - return ofFile(file, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension), sniffers = sniffers) + TODO() } /** * Resolves a format from a local file path. */ + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) + @Suppress("UNUSED_PARAMETER") suspend fun ofFile( file: File, mediaTypes: List, fileExtensions: List, sniffers: List = MediaType.sniffers ): MediaType? { - return of(content = SnifferFileContent(file), mediaTypes = mediaTypes, fileExtensions = listOf(file.extension) + fileExtensions, sniffers = sniffers) + TODO() } /** * Resolves a format from a local file path. */ + @Suppress("UNUSED_PARAMETER") + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) suspend fun ofFile( path: String, mediaType: String? = null, fileExtension: String? = null, sniffers: List = MediaType.sniffers ): MediaType? { - return ofFile(File(path), mediaType = mediaType, fileExtension = fileExtension, sniffers = sniffers) + TODO() } /** * Resolves a format from a local file path. */ + @Suppress("UNUSED_PARAMETER") + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) suspend fun ofFile( path: String, mediaTypes: List, fileExtensions: List, sniffers: List = MediaType.sniffers ): MediaType? { - return ofFile(File(path), mediaTypes = mediaTypes, fileExtensions = fileExtensions, sniffers = sniffers) + TODO() } /** * Resolves a format from bytes, e.g. from an HTTP response. */ + @Suppress("UNUSED_PARAMETER") + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) suspend fun ofBytes( bytes: () -> ByteArray, mediaType: String? = null, fileExtension: String? = null, sniffers: List = MediaType.sniffers ): MediaType? { - return ofBytes(bytes, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension), sniffers = sniffers) + TODO() } /** * Resolves a format from bytes, e.g. from an HTTP response. */ + @Suppress("UNUSED_PARAMETER") + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) suspend fun ofBytes( bytes: () -> ByteArray, mediaTypes: List, fileExtensions: List, sniffers: List = MediaType.sniffers ): MediaType? { - return of(content = SnifferBytesContent(bytes), mediaTypes = mediaTypes, fileExtensions = fileExtensions, sniffers = sniffers) + TODO() } /** * Resolves a format from a content URI and a [ContentResolver]. * Accepts the following URI schemes: content, android.resource, file. */ + @Suppress("UNUSED_PARAMETER") + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) suspend fun ofUri( uri: Uri, contentResolver: ContentResolver, @@ -452,13 +465,15 @@ class MediaType( fileExtension: String? = null, sniffers: List = MediaType.sniffers ): MediaType? { - return ofUri(uri, contentResolver, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension), sniffers = sniffers) + TODO() } /** * Resolves a format from a content URI and a [ContentResolver]. * Accepts the following URI schemes: content, android.resource, file. */ + @Suppress("UNUSED_PARAMETER") + @Deprecated(message = "Use MediaTypeRetriever instead", level = DeprecationLevel.ERROR) suspend fun ofUri( uri: Uri, contentResolver: ContentResolver, @@ -466,87 +481,7 @@ class MediaType( fileExtensions: List, sniffers: List = MediaType.sniffers ): MediaType? { - val allMediaTypes = mediaTypes.toMutableList() - val allFileExtensions = fileExtensions.toMutableList() - - MimeTypeMap.getFileExtensionFromUrl(uri.toString()).ifEmpty { null }?.let { - allFileExtensions.add(0, it) - } - - if (uri.scheme == ContentResolver.SCHEME_CONTENT) { - contentResolver.getType(uri) - ?.takeUnless { MediaType.BINARY.matches(it) } - ?.let { allMediaTypes.add(0, it) } - - contentResolver.queryProjection(uri, MediaStore.MediaColumns.DISPLAY_NAME)?.let { filename -> - allFileExtensions.add(0, File(filename).extension) - } - } - - val content = SnifferUriContent(uri = uri, contentResolver = contentResolver) - return of(content = content, mediaTypes = allMediaTypes, fileExtensions = allFileExtensions, sniffers = sniffers) - } - - /** - * Resolves a media type from a sniffer context. - * - * Sniffing a media type is done in two rounds, because we want to give an opportunity to all - * sniffers to return a [MediaType] quickly before inspecting the content itself: - * - Light Sniffing checks only the provided file extension or media type hints. - * - Heavy Sniffing reads the bytes to perform more advanced sniffing. - */ - private suspend fun of( - content: SnifferContent?, - mediaTypes: List, - fileExtensions: List, - sniffers: List - ): MediaType? { - // Light sniffing with only media type hints - if (mediaTypes.isNotEmpty()) { - val context = SnifferContext(mediaTypes = mediaTypes) - for (sniffer in sniffers) { - val mediaType = sniffer(context) - if (mediaType != null) { - return mediaType - } - } - } - - // Light sniffing with both media type hints and file extensions - if (fileExtensions.isNotEmpty()) { - val context = SnifferContext(mediaTypes = mediaTypes, fileExtensions = fileExtensions) - for (sniffer in sniffers) { - val mediaType = sniffer(context) - if (mediaType != null) { - return mediaType - } - } - } - - // Heavy sniffing - if (content != null) { - val context = SnifferContext(content = content, mediaTypes = mediaTypes, fileExtensions = fileExtensions) - for (sniffer in sniffers) { - val mediaType = sniffer(context) - if (mediaType != null) { - return mediaType - } - } - } - - // Falls back on the system-wide registered media types using [MimeTypeMap]. - // Note: This is done after the heavy sniffing of the provided [sniffers], because - // otherwise it will detect JSON, XML or ZIP formats before we have a chance of sniffing - // their content (for example, for RWPM). - val context = SnifferContext(content = content, mediaTypes = mediaTypes, fileExtensions = fileExtensions) - Sniffers.system(context)?.let { return it } - - // If nothing else worked, we try to parse the first valid media type hint. - for (mediaType in mediaTypes) { - parse(mediaType)?.let { return it } - } - - return null + TODO() } /* Deprecated */ diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt new file mode 100644 index 0000000000..881714e077 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt @@ -0,0 +1,246 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.mediatype + +import android.content.ContentResolver +import android.net.Uri +import android.provider.MediaStore +import java.io.File +import org.readium.r2.shared.BuildConfig +import org.readium.r2.shared.extensions.queryProjection +import org.readium.r2.shared.resource.* +import org.readium.r2.shared.util.Either +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.toUrl + +class MediaTypeRetriever( + resourceFactory: ResourceFactory = FileResourceFactory(), + containerFactory: ContainerFactory = DirectoryContainerFactory(), + archiveFactory: ArchiveFactory = DefaultArchiveFactory(), + private val contentResolver: ContentResolver? = null, + private val sniffers: List = Sniffers.all, +) { + private val urlSnifferContextFactory: UrlSnifferContextFactory = + UrlSnifferContextFactory(resourceFactory, containerFactory, archiveFactory) + + private val bytesSnifferContextFactory: BytesSnifferContextFactory = + BytesSnifferContextFactory(archiveFactory) + + suspend fun canonicalMediaType(mediaType: MediaType): MediaType = + retrieve(mediaType = mediaType.toString()) ?: mediaType + + /** + * Resolves a media type from a single file extension and media type hint, without checking the actual + * content. + */ + suspend fun retrieve( + mediaType: String? = null, + fileExtension: String? = null, + ): MediaType? { + if (BuildConfig.DEBUG && mediaType?.startsWith("/") == true) { + throw IllegalArgumentException("The provided media type is incorrect: $mediaType. To pass a file path, you must wrap it in a File().") + } + return retrieve(mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) + } + + /** + * Resolves a media type from file extension and media type hints without checking the actual + * content. + */ + suspend fun retrieve( + mediaTypes: List, + fileExtensions: List + ): MediaType? { + return doRetrieve(null, mediaTypes, fileExtensions) + } + + /** + * Resolves a media type from a local file. + */ + suspend fun retrieve( + file: File, + mediaType: String? = null, + fileExtension: String? = null, + ): MediaType? { + return retrieve(file, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) + } + + /** + * Resolves a media type from a local file. + */ + suspend fun retrieve( + file: File, + mediaTypes: List, + fileExtensions: List, + ): MediaType? { + return retrieve(content = Either.Right(file.toUrl()), mediaTypes = mediaTypes, fileExtensions = listOf(file.extension) + fileExtensions) + } + + /** + * Resolves a media type from bytes, e.g. from an HTTP response. + */ + suspend fun retrieve( + bytes: () -> ByteArray, + mediaType: String? = null, + fileExtension: String? = null, + ): MediaType? { + return retrieve(bytes, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) + } + + /** + * Resolves a media type from bytes, e.g. from an HTTP response. + */ + suspend fun retrieve( + bytes: () -> ByteArray, + mediaTypes: List, + fileExtensions: List, + ): MediaType? { + return retrieve(content = Either.Left(bytes), mediaTypes = mediaTypes, fileExtensions = fileExtensions) + } + + /** + * Resolves a media type from a Uri. + */ + suspend fun retrieve( + uri: Uri, + mediaType: String? = null, + fileExtension: String? = null, + ): MediaType? { + return retrieve(uri, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) + } + + /** + * Resolves a media type from a Uri. + */ + suspend fun retrieve( + uri: Uri, + mediaTypes: List, + fileExtensions: List, + ): MediaType? { + val url = uri.toUrl() ?: return null + return retrieve(content = Either.Right(url), mediaTypes = mediaTypes, fileExtensions = fileExtensions) + } + + /** + * Resolves a media type from a sniffer context. + * + * Sniffing a media type is done in two rounds, because we want to give an opportunity to all + * sniffers to return a [MediaType] quickly before inspecting the content itself: + * - Light Sniffing checks only the provided file extension or media type hints. + * - Heavy Sniffing reads the bytes to perform more advanced sniffing. + */ + private suspend fun retrieve( + content: Either<() -> ByteArray, Url>?, + mediaTypes: List, + fileExtensions: List + ): MediaType? { + val fullContext = suspend { + when (content) { + is Either.Left -> + bytesSnifferContextFactory.createContext( + content.value.invoke(), + mediaTypes, + fileExtensions + ) + is Either.Right -> + urlSnifferContextFactory.createContext( + content.value, + mediaTypes, + fileExtensions + ) + null -> null + } + } + + doRetrieve(fullContext, mediaTypes, fileExtensions)?.let { return it } + + // Falls back on the [contentResolver] in case of content Uri. + // Note: This is done after the heavy sniffing of the provided [sniffers], because + // otherwise it will detect JSON, XML or ZIP formats before we have a chance of sniffing + // their content (for example, for RWPM). + + val url = (content as? Either.Right)?.value + ?: return null + + val allMediaTypes = mediaTypes.toMutableList() + val allFileExtensions = fileExtensions.toMutableList() + + if (url.scheme == ContentResolver.SCHEME_CONTENT && contentResolver != null) { + contentResolver.getType(url.uri) + ?.takeUnless { MediaType.BINARY.matches(it) } + ?.let { allMediaTypes.add(0, it) } + + contentResolver.queryProjection(url.uri, MediaStore.MediaColumns.DISPLAY_NAME)?.let { filename -> + allFileExtensions.add(0, File(filename).extension) + } + } + + return doRetrieve(fullContext, allMediaTypes, allFileExtensions) + } + + /** + * Resolves a media type from a sniffer context. + * + * Sniffing a media type is done in two rounds, because we want to give an opportunity to all + * sniffers to return a [MediaType] quickly before inspecting the content itself: + * - Light Sniffing checks only the provided file extension or media type hints. + * - Heavy Sniffing reads the bytes to perform more advanced sniffing. + */ + internal suspend fun doRetrieve( + fullContext: (suspend () -> SnifferContext?)?, + mediaTypes: List, + fileExtensions: List + ): MediaType? { + // Light sniffing with only media type hints + if (mediaTypes.isNotEmpty()) { + val context = HintSnifferContext(mediaTypes = mediaTypes) + for (sniffer in sniffers) { + val mediaType = sniffer(context) + if (mediaType != null) { + return mediaType + } + } + } + + // Light sniffing with both media type hints and file extensions + if (fileExtensions.isNotEmpty()) { + val context = HintSnifferContext(mediaTypes = mediaTypes, fileExtensions = fileExtensions) + for (sniffer in sniffers) { + val mediaType = sniffer(context) + if (mediaType != null) { + return mediaType + } + } + } + + // Heavy sniffing + val context = fullContext?.invoke() + + if (context != null) { + for (sniffer in sniffers) { + val mediaType = sniffer(context) + if (mediaType != null) { + return mediaType + } + } + } + + // Falls back on the system-wide registered media types using [MimeTypeMap]. + // Note: This is done after the heavy sniffing of the provided [sniffers], because + // otherwise it will detect JSON, XML or ZIP formats before we have a chance of sniffing + // their content (for example, for RWPM). + val systemContext = context ?: HintSnifferContext(mediaTypes, fileExtensions) + Sniffers.system(systemContext)?.let { return it } + + // If nothing else worked, we try to parse the first valid media type hint. + for (mediaType in mediaTypes) { + MediaType.parse(mediaType)?.let { return it } + } + + return null + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt index ae58444d95..1ca69f1ac6 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt @@ -33,8 +33,8 @@ object Sniffers { * The sniffers order is important, because some formats are subsets of other formats. */ val all: List = listOf( - ::xhtml, ::html, ::opds, ::lcpLicense, ::bitmap, ::webpub, ::w3cWPUB, ::epub, ::lpf, ::archive, - ::pdf, ::json + ::xhtml, ::html, ::opds, ::lcpLicense, ::bitmap, ::webpubManifest, ::webpub, ::w3cWPUB, + ::epub, ::lpf, ::archive, ::pdf, ::json ) /** @@ -46,6 +46,11 @@ object Sniffers { if (context.hasFileExtension("xht", "xhtml") || context.hasMediaType("application/xhtml+xml")) { return MediaType.XHTML } + + if (context !is ResourceSnifferContext) { + return null + } + context.contentAsXml()?.let { if (it.name.lowercase(Locale.ROOT) == "html" && it.namespace.lowercase(Locale.ROOT).contains("xhtml")) { return MediaType.XHTML @@ -59,6 +64,11 @@ object Sniffers { if (context.hasFileExtension("htm", "html") || context.hasMediaType("text/html")) { return MediaType.HTML } + + if (context !is ResourceSnifferContext) { + return null + } + // [contentAsXml] will fail if the HTML is not a proper XML document, hence the doctype check. if ( context.contentAsXml()?.name?.lowercase(Locale.ROOT) == "html" || @@ -78,6 +88,25 @@ object Sniffers { if (context.hasMediaType("application/atom+xml;profile=opds-catalog")) { return MediaType.OPDS1 } + + // OPDS 2 + if (context.hasMediaType("application/opds+json")) { + return MediaType.OPDS2 + } + if (context.hasMediaType("application/opds-publication+json")) { + return MediaType.OPDS2_PUBLICATION + } + + // OPDS Authentication Document. + if (context.hasMediaType("application/opds-authentication+json") || context.hasMediaType("application/vnd.opds.authentication.v1.0+json")) { + return MediaType.OPDS_AUTHENTICATION + } + + if (context !is ResourceSnifferContext) { + return null + } + + // OPDS 1 context.contentAsXml()?.let { xml -> if (xml.namespace == "http://www.w3.org/2005/Atom") { if (xml.name == "feed") { @@ -89,12 +118,6 @@ object Sniffers { } // OPDS 2 - if (context.hasMediaType("application/opds+json")) { - return MediaType.OPDS2 - } - if (context.hasMediaType("application/opds-publication+json")) { - return MediaType.OPDS2_PUBLICATION - } context.contentAsRwpm()?.let { rwpm -> if (rwpm.linkWithRel("self")?.mediaType?.matches("application/opds+json") == true) { return MediaType.OPDS2 @@ -105,9 +128,6 @@ object Sniffers { } // OPDS Authentication Document. - if (context.hasMediaType("application/opds-authentication+json") || context.hasMediaType("application/vnd.opds.authentication.v1.0+json")) { - return MediaType.OPDS_AUTHENTICATION - } if (context.containsJsonKeys("id", "title", "authentication")) { return MediaType.OPDS_AUTHENTICATION } @@ -120,6 +140,11 @@ object Sniffers { if (context.hasFileExtension("lcpl") || context.hasMediaType("application/vnd.readium.lcp.license.v1.0+json")) { return MediaType.LCP_LICENSE_DOCUMENT } + + if (context !is ResourceSnifferContext) { + return null + } + if (context.containsJsonKeys("id", "issued", "provider", "encryption")) { return MediaType.LCP_LICENSE_DOCUMENT } @@ -156,28 +181,54 @@ object Sniffers { return null } + /** Sniffs a Readium Web Manifest. */ + suspend fun webpubManifest(context: SnifferContext): MediaType? { + if (context.hasMediaType("application/audiobook+json")) { + return MediaType.READIUM_AUDIOBOOK_MANIFEST + } + + if (context.hasMediaType("application/divina+json")) { + return MediaType.DIVINA_MANIFEST + } + + if (context.hasMediaType("application/webpub+json")) { + return MediaType.READIUM_WEBPUB_MANIFEST + } + + if (context !is ResourceSnifferContext) { + return null + } + + val manifest: Manifest = + context.contentAsRwpm() ?: return null + + if (manifest.conformsTo(Publication.Profile.AUDIOBOOK)) { + return MediaType.READIUM_AUDIOBOOK_MANIFEST + } + + if (manifest.conformsTo(Publication.Profile.DIVINA)) { + return MediaType.DIVINA_MANIFEST + } + if (manifest.linkWithRel("self")?.mediaType?.matches("application/webpub+json") == true) { + return MediaType.READIUM_WEBPUB_MANIFEST + } + + return null + } + /** Sniffs a Readium Web Publication, protected or not by LCP. */ suspend fun webpub(context: SnifferContext): MediaType? { if (context.hasFileExtension("audiobook") || context.hasMediaType("application/audiobook+zip")) { return MediaType.READIUM_AUDIOBOOK } - if (context.hasMediaType("application/audiobook+json")) { - return MediaType.READIUM_AUDIOBOOK_MANIFEST - } if (context.hasFileExtension("divina") || context.hasMediaType("application/divina+zip")) { return MediaType.DIVINA } - if (context.hasMediaType("application/divina+json")) { - return MediaType.DIVINA_MANIFEST - } if (context.hasFileExtension("webpub") || context.hasMediaType("application/webpub+zip")) { return MediaType.READIUM_WEBPUB } - if (context.hasMediaType("application/webpub+json")) { - return MediaType.READIUM_WEBPUB_MANIFEST - } if (context.hasFileExtension("lcpa") || context.hasMediaType("application/audiobook+lcp")) { return MediaType.LCP_PROTECTED_AUDIOBOOK @@ -186,17 +237,15 @@ object Sniffers { return MediaType.LCP_PROTECTED_PDF } - // Reads a RWPM, either from a manifest.json file, or from a manifest.json archive entry, if - // the file is an archive. - var isManifest = true + if (context !is ContainerSnifferContext) { + return null + } + + // Reads a RWPM from a manifest.json archive entry. val manifest: Manifest? = try { - // manifest.json - context.contentAsRwpm() - // Archive package - ?: context.readArchiveEntryAt("manifest.json") - ?.let { Manifest.fromJSON(JSONObject(String(it))) } - ?.also { isManifest = false } + context.readArchiveEntryAt("manifest.json") + ?.let { Manifest.fromJSON(JSONObject(String(it))) } } catch (e: Exception) { null } @@ -205,17 +254,16 @@ object Sniffers { val isLcpProtected = context.containsArchiveEntryAt("license.lcpl") if (manifest.conformsTo(Publication.Profile.AUDIOBOOK)) { - return if (isManifest) MediaType.READIUM_AUDIOBOOK_MANIFEST - else (if (isLcpProtected) MediaType.LCP_PROTECTED_AUDIOBOOK else MediaType.READIUM_AUDIOBOOK) + return if (isLcpProtected) MediaType.LCP_PROTECTED_AUDIOBOOK else MediaType.READIUM_AUDIOBOOK } if (manifest.conformsTo(Publication.Profile.DIVINA)) { - return if (isManifest) MediaType.DIVINA_MANIFEST else MediaType.DIVINA + return MediaType.DIVINA } if (isLcpProtected && manifest.conformsTo(Publication.Profile.PDF)) { return MediaType.LCP_PROTECTED_PDF } if (manifest.linkWithRel("self")?.mediaType?.matches("application/webpub+json") == true) { - return if (isManifest) MediaType.READIUM_WEBPUB_MANIFEST else MediaType.READIUM_WEBPUB + return MediaType.READIUM_WEBPUB } } @@ -224,6 +272,10 @@ object Sniffers { /** Sniffs a W3C Web Publication Manifest. */ suspend fun w3cWPUB(context: SnifferContext): MediaType? { + if (context !is ResourceSnifferContext) { + return null + } + // Somehow, [JSONObject] can't access JSON-LD keys such as `@context`. val content = context.contentAsString() ?: "" if (content.contains("@context") && content.contains("https://www.w3.org/ns/wp-context")) { @@ -243,6 +295,10 @@ object Sniffers { return MediaType.EPUB } + if (context !is ContainerSnifferContext) { + return null + } + val mimetype = context.readArchiveEntryAt("mimetype") ?.let { String(it, charset = Charsets.US_ASCII).trim() } if (mimetype == "application/epub+zip") { @@ -263,6 +319,11 @@ object Sniffers { if (context.hasFileExtension("lpf") || context.hasMediaType("application/lpf+zip")) { return MediaType.LPF } + + if (context !is ContainerSnifferContext) { + return null + } + if (context.containsArchiveEntryAt("index.html")) { return MediaType.LPF } @@ -313,22 +374,24 @@ object Sniffers { return MediaType.ZAB } - if (context.contentAsArchive() != null) { - fun isIgnored(file: File): Boolean = - file.name.startsWith(".") || file.name == "Thumbs.db" + if (context !is ContainerSnifferContext) { + return null + } - suspend fun archiveContainsOnlyExtensions(fileExtensions: List): Boolean = - context.archiveEntriesAllSatisfy { entry -> - val file = File(entry.path) - isIgnored(file) || fileExtensions.contains(file.extension.lowercase(Locale.ROOT)) - } + fun isIgnored(file: File): Boolean = + file.name.startsWith(".") || file.name == "Thumbs.db" - if (archiveContainsOnlyExtensions(CBZ_EXTENSIONS)) { - return MediaType.CBZ - } - if (archiveContainsOnlyExtensions(ZAB_EXTENSIONS)) { - return MediaType.ZAB + suspend fun archiveContainsOnlyExtensions(fileExtensions: List): Boolean = + context.archiveEntriesAllSatisfy { entry -> + val file = File(entry.path) + isIgnored(file) || fileExtensions.contains(file.extension.lowercase(Locale.ROOT)) } + + if (archiveContainsOnlyExtensions(CBZ_EXTENSIONS)) { + return MediaType.CBZ + } + if (archiveContainsOnlyExtensions(ZAB_EXTENSIONS)) { + return MediaType.ZAB } return null @@ -343,6 +406,11 @@ object Sniffers { if (context.hasFileExtension("pdf") || context.hasMediaType("application/pdf")) { return MediaType.PDF } + + if (context !is ResourceSnifferContext) { + return null + } + if (context.read(0L until 5L)?.toString(Charsets.UTF_8) == "%PDF-") { return MediaType.PDF } @@ -355,9 +423,11 @@ object Sniffers { if (context.hasMediaType("application/problem+json")) { return MediaType.JSON_PROBLEM_DETAILS } - if (context.hasMediaType("application/json")) { - return MediaType.JSON + + if (context !is ResourceSnifferContext) { + return null } + if (context.contentAsJson() != null) { return MediaType.JSON } @@ -396,8 +466,12 @@ object Sniffers { return sniffExtension(extension) ?: continue } + if (context !is ResourceSnifferContext) { + return null + } + return withContext(Dispatchers.IO) { - context.stream() + context.contentAsStream() ?.let { URLConnection.guessContentTypeFromStream(it) } ?.let { sniffType(it) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt deleted file mode 100644 index a1e62eb3f7..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContent.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.util.mediatype - -import android.content.ContentResolver -import android.net.Uri -import java.io.ByteArrayInputStream -import java.io.File -import java.io.InputStream -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.readium.r2.shared.extensions.tryOrNull -import timber.log.Timber - -/** Provides an access to a file's content to sniff its format. */ -internal interface SnifferContent { - - /** Reads the whole content as raw bytes. */ - suspend fun read(): ByteArray? - - /** - * Raw bytes stream of the content. - * - * A byte stream can be useful when sniffers only need to read a few bytes at the beginning of - * the file. - */ - suspend fun stream(): InputStream? -} - -/** Used to sniff a local file. */ -internal class SnifferFileContent(val file: File) : SnifferContent { - - override suspend fun read(): ByteArray? = withContext(Dispatchers.IO) { - try { - // We only read files smaller than 5MB to avoid an [OutOfMemoryError]. - if (file.length() > 5 * 1000 * 1000) { - null - } else { - file.readBytes() - } - } catch (e: Exception) { - Timber.e(e) - null - } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. - Timber.e(e) - null - } - } - - override suspend fun stream(): InputStream? = - try { - file.inputStream().buffered() - } catch (e: Exception) { - Timber.e(e) - null - } -} - -/** Used to sniff a bytes array. */ -internal class SnifferBytesContent(val getBytes: () -> ByteArray) : SnifferContent { - - private lateinit var _bytes: ByteArray - - private suspend fun bytes(): ByteArray { - if (!this::_bytes.isInitialized) { - withContext(Dispatchers.IO) { - _bytes = getBytes() - } - } - return _bytes - } - - override suspend fun read(): ByteArray? = - tryOrNull { bytes() } - - override suspend fun stream(): InputStream? = - tryOrNull { ByteArrayInputStream(bytes()) } -} - -/** Used to sniff a content URI. */ -internal class SnifferUriContent(val uri: Uri, val contentResolver: ContentResolver) : SnifferContent { - - override suspend fun read(): ByteArray? = withContext(Dispatchers.IO) { - try { - stream()?.readBytes() - } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. - Timber.e(e) - null - } - } - - override suspend fun stream(): InputStream? = withContext(Dispatchers.IO) { - try { - contentResolver.openInputStream(uri) - } catch (e: Exception) { - Timber.e(e) - null - } - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt index 6d3dafae0c..2d0bed7eee 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt @@ -6,37 +6,24 @@ package org.readium.r2.shared.util.mediatype +import java.io.File import java.io.InputStream import java.nio.charset.Charset import java.util.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.json.JSONObject -import org.readium.r2.shared.extensions.readFully -import org.readium.r2.shared.extensions.readRange -import org.readium.r2.shared.extensions.tryOr -import org.readium.r2.shared.extensions.tryOrNull +import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.parser.xml.ElementNode -import org.readium.r2.shared.parser.xml.XmlParser import org.readium.r2.shared.publication.Manifest -import org.readium.r2.shared.util.archive.Archive -import org.readium.r2.shared.util.archive.DefaultArchiveFactory +import org.readium.r2.shared.resource.* +import org.readium.r2.shared.util.Url import timber.log.Timber -/** - * A companion type of [Sniffer] holding the type hints (file extensions, media types) and - * providing an access to the file content. - * - * @param content Underlying content holder. - * @param mediaTypes Media type hints. - * @param fileExtensions File extension hints. - */ -class SnifferContext internal constructor( - private val content: SnifferContent? = null, +sealed class SnifferContext( mediaTypes: List = emptyList(), fileExtensions: List = emptyList() ) { - /** Media type hints. */ val mediaTypes: List = mediaTypes .mapNotNull { MediaType.parse(it) } @@ -45,12 +32,9 @@ class SnifferContext internal constructor( val fileExtensions: List = fileExtensions .map { it.lowercase(Locale.ROOT) } - // Metadata - /** Finds the first [Charset] declared in the media types' `charset` parameter. */ - val charset: Charset? by lazy { - this.mediaTypes.mapNotNull { it.charset }.firstOrNull() - } + val charset: Charset? get() = + this.mediaTypes.firstNotNullOfOrNull { it.charset } /** Returns whether this context has any of the given file extensions, ignoring case. */ fun hasFileExtension(vararg fileExtensions: String): Boolean { @@ -79,7 +63,35 @@ class SnifferContext internal constructor( return false } - // Content + abstract suspend fun release() +} + +class HintSnifferContext( + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList() +) : SnifferContext(mediaTypes, fileExtensions) { + + override suspend fun release() {} +} + +sealed class ContentAwareSnifferContext( + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList() +) : SnifferContext(mediaTypes, fileExtensions) + +/** + * A companion type of [Sniffer] holding the type hints (file extensions, media types) and + * providing an access to the file content. + * + * @param resource Underlying content holder. + * @param mediaTypes Media type hints. + * @param fileExtensions File extension hints. + */ +class ResourceSnifferContext internal constructor( + val resource: Resource, + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList() +) : ContentAwareSnifferContext(mediaTypes, fileExtensions) { /** * Content as plain text. @@ -91,7 +103,9 @@ class SnifferContext internal constructor( try { if (!loadedContentAsString) { loadedContentAsString = true - _contentAsString = content?.read()?.toString(charset ?: Charset.defaultCharset()) + _contentAsString = resource + .readAsString(charset ?: Charset.defaultCharset()) + .getOrNull() } _contentAsString } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. @@ -108,7 +122,7 @@ class SnifferContext internal constructor( loadedContentAsXml = true _contentAsXml = withContext(Dispatchers.IO) { try { - stream()?.let { XmlParser().parse(it) } + resource.readAsXml().getOrNull() } catch (e: Exception) { null } @@ -121,26 +135,6 @@ class SnifferContext internal constructor( private var loadedContentAsXml: Boolean = false private var _contentAsXml: ElementNode? = null - /** - * Content as an Archive instance. - * Warning: Archive is only supported for a local file, for now. - */ - suspend fun contentAsArchive(): Archive? { - if (!loadedContentAsArchive) { - loadedContentAsArchive = true - _contentAsArchive = withContext(Dispatchers.IO) { - (content as? SnifferFileContent)?.let { - tryOrNull { DefaultArchiveFactory().open(it.file, password = null) } - } - } - } - - return _contentAsArchive - } - - private var loadedContentAsArchive: Boolean = false - private var _contentAsArchive: Archive? = null - /** * Content parsed from JSON. */ @@ -161,7 +155,8 @@ class SnifferContext internal constructor( * A byte stream can be useful when sniffers only need to read a few bytes at the beginning of * the file. */ - suspend fun stream(): InputStream? = content?.stream() + suspend fun contentAsStream(): InputStream? = + ResourceInputStream(resource) /** * Reads all the bytes or the given [range]. @@ -170,10 +165,7 @@ class SnifferContext internal constructor( * See https://en.wikipedia.org/wiki/List_of_file_signatures */ suspend fun read(range: LongRange? = null): ByteArray? = - tryOrNull { - if (range != null) stream()?.readRange(range) - else stream()?.readFully() - } + resource.read(range).getOrNull() /** * Returns whether the content is a JSON object containing all of the given root keys. @@ -183,31 +175,138 @@ class SnifferContext internal constructor( return json.keys().asSequence().toSet().containsAll(keys.toList()) } + override suspend fun release() { + resource.close() + } +} + +/** + * A companion type of [Sniffer] holding the type hints (file extensions, media types) and + * providing an access to the file content. + * + * @param resource Underlying content holder. + * @param mediaTypes Media type hints. + * @param fileExtensions File extension hints. + */ +class ContainerSnifferContext internal constructor( + val container: Container, + val isExploded: Boolean, + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList() +) : ContentAwareSnifferContext(mediaTypes, fileExtensions) { + /** * Returns whether an Archive entry exists in this file. */ internal suspend fun containsArchiveEntryAt(path: String): Boolean = - tryOrNull { contentAsArchive()?.entry(path) } != null + container.entry(path).read(0 until 16L).isSuccess /** * Returns the Archive entry data at the given [path] in this file. */ internal suspend fun readArchiveEntryAt(path: String): ByteArray? { - val archive = contentAsArchive() ?: return null + val archive = container return withContext(Dispatchers.IO) { - tryOrNull { - val entry = archive.entry(path) - val bytes = entry.read() - entry.close() - bytes - } + val entry = archive.entry(path) + val bytes = entry.read().getOrNull() + entry.close() + bytes } } /** * Returns whether all the Archive entry paths satisfy the given `predicate`. */ - internal suspend fun archiveEntriesAllSatisfy(predicate: (Archive.Entry) -> Boolean): Boolean = - tryOr(false) { contentAsArchive()?.entries()?.all(predicate) == true } + internal suspend fun archiveEntriesAllSatisfy(predicate: (Container.Entry) -> Boolean): Boolean = + container.entries() + ?.all(predicate) + ?: false + + override suspend fun release() { + container.close() + } +} + +internal class UrlSnifferContextFactory( + private val resourceFactory: ResourceFactory, + private val containerFactory: ContainerFactory, + private val archiveFactory: ArchiveFactory, +) { + + suspend fun createContext( + url: Url, + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList() + ): ContentAwareSnifferContext? { + val resource = resourceFactory + .create(url) + .getOrElse { + when (it) { + is ResourceFactory.Error.NotAResource -> + return tryCreateContainerContext( + url = url, + mediaTypes = mediaTypes, + fileExtensions = fileExtensions + ) + else -> return null + } + } + + return archiveFactory.create(resource, password = null) + .fold( + { + ContainerSnifferContext( + container = it, + isExploded = false, + mediaTypes = mediaTypes, + fileExtensions = fileExtensions + ) + }, + { + ResourceSnifferContext( + resource = resource, + mediaTypes = mediaTypes + + listOfNotNull(resource.mediaType().getOrNull()), + fileExtensions = fileExtensions + + listOfNotNull(resource.name().getOrNull()?.let { File(it).extension }) + ) + } + ) + } + + private suspend fun tryCreateContainerContext( + url: Url, + mediaTypes: List, + fileExtensions: List + ): ContentAwareSnifferContext? { + val container = containerFactory.create(url) + .getOrNull() + ?: return null + + return ContainerSnifferContext( + container = container, + isExploded = true, + mediaTypes = mediaTypes, + fileExtensions = fileExtensions + ) + } +} + +internal class BytesSnifferContextFactory( + private val archiveFactory: ArchiveFactory +) { + + suspend fun createContext( + bytes: ByteArray, + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList(), + ): ContentAwareSnifferContext? { + val resource: Resource = BytesResource(bytes) + return archiveFactory.create(resource, password = null) + .fold( + { ContainerSnifferContext(it, false, mediaTypes, fileExtensions) }, + { ResourceSnifferContext(resource, mediaTypes, fileExtensions) } + ) + } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt index f4b63e8f5b..217bc7acdd 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt @@ -14,7 +14,7 @@ import android.graphics.Bitmap import java.io.File import kotlin.reflect.KClass import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.PublicationServicesHolder @@ -33,7 +33,7 @@ interface PdfDocumentFactory { suspend fun open(file: File, password: String?): T /** Opens a PDF from a Fetcher resource. */ - suspend fun open(resource: Resource, password: String?): T + suspend fun open(resource: Fetcher.Resource, password: String?): T } /** @@ -62,7 +62,7 @@ private class CachingPdfDocumentFactory( } } - override suspend fun open(resource: Resource, password: String?): T = + override suspend fun open(resource: Fetcher.Resource, password: String?): T = cache.transaction { getOrPut(resource.link().href) { factory.open(resource, password) diff --git a/readium/shared/src/main/res/values/strings.xml b/readium/shared/src/main/res/values/strings.xml index e838cb7b01..561be95fe9 100644 --- a/readium/shared/src/main/res/values/strings.xml +++ b/readium/shared/src/main/res/values/strings.xml @@ -6,7 +6,7 @@ --> - Format not supported + Format not supported File not found The file is corrupted and can\'t be opened You are not allowed to open this publication @@ -22,7 +22,7 @@ The resource is currently unavailable, please try again later The Internet connection appears to be offline The resource is too large to be read on this device - The request was cancelled + An expected error occurred. A service error occurred The provided request was not valid diff --git a/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt b/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt index be8667a9e5..4c6515de1f 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt @@ -18,8 +18,8 @@ import org.junit.Assert.assertEquals import org.readium.r2.shared.extensions.toListTest import org.readium.r2.shared.extensions.toMapTest import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.use /** @@ -58,6 +58,6 @@ internal fun Resource.lengthBlocking() = runBlocking { length() } internal fun Fetcher.lengthBlocking(href: String) = runBlocking { get(Link(href = href)).use { it.lengthBlocking() } } -internal fun Resource.linkBlocking() = runBlocking { link() } +internal fun Fetcher.Resource.linkBlocking() = runBlocking { link() } internal fun Fetcher.linkBlocking(href: String) = runBlocking { get(Link(href = href)).use { it.linkBlocking() } } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/BufferingResourceTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/BufferingResourceTest.kt index 0b5e4f1c40..8e67b0872c 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/BufferingResourceTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/BufferingResourceTest.kt @@ -12,17 +12,17 @@ class BufferingResourceTest { @Test fun `get file`() { - assertEquals(sut().file, file) + assertEquals(file, sut().file) } @Test fun `get link`() = runBlocking { - assertEquals(sut().link(), link) + assertEquals(link, sut().link()) } @Test fun `get length`() = runBlocking { - assertEquals(sut().length().getOrNull(), 161291) + assertEquals(161291, sut().length().getOrNull()) } @Test diff --git a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ArchiveFetcherTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ContainerFetcherTest.kt similarity index 91% rename from readium/shared/src/test/java/org/readium/r2/shared/fetcher/ArchiveFetcherTest.kt rename to readium/shared/src/test/java/org/readium/r2/shared/fetcher/ContainerFetcherTest.kt index 5714daafd5..21f36b7a9e 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ArchiveFetcherTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ContainerFetcherTest.kt @@ -7,6 +7,7 @@ package org.readium.r2.shared.fetcher import android.webkit.MimeTypeMap +import java.io.File import java.nio.charset.StandardCharsets import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -16,23 +17,33 @@ import org.json.JSONObject import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.assertJSONEquals +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.lengthBlocking import org.readium.r2.shared.linkBlocking import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Properties import org.readium.r2.shared.readBlocking +import org.readium.r2.shared.resource.DefaultArchiveFactory +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.readAsString +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.robolectric.RobolectricTestRunner import org.robolectric.Shadows @RunWith(RobolectricTestRunner::class) -class ArchiveFetcherTest { +class ContainerFetcherTest { private val fetcher: Fetcher init { - val epub = ArchiveFetcherTest::class.java.getResource("epub.epub") + val epub = ContainerFetcherTest::class.java.getResource("epub.epub") assertNotNull(epub) - val zipFetcher = runBlocking { ArchiveFetcher.fromPath(epub.path) } + val archive = runBlocking { + DefaultArchiveFactory() + .open(File(epub.path)) + .getOrNull()!! + } + val zipFetcher = ContainerFetcher(archive, MediaTypeRetriever()) assertNotNull(zipFetcher) fetcher = zipFetcher } @@ -52,9 +63,6 @@ class ArchiveFetcherTest { "isEntryCompressed" to isCompressed ) ) - if (isCompressed) { - props["compressedLength"] = entryLength - } return Link( href = href, @@ -147,7 +155,6 @@ class ArchiveFetcherTest { assertJSONEquals( JSONObject( mapOf( - "compressedLength" to 595L, "archive" to mapOf( "entryLength" to 595L, "isEntryCompressed" to true diff --git a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt index 324f610fe7..bc3e48f3f9 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt @@ -19,9 +19,12 @@ import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.junit.runner.RunWith +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.lengthBlocking import org.readium.r2.shared.publication.Link import org.readium.r2.shared.readBlocking +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.robolectric.RobolectricTestRunner import org.robolectric.Shadows @@ -35,7 +38,10 @@ class FileFetcherTest { assertNotNull(text) val directory = FileFetcherTest::class.java.getResource("directory") assertNotNull(directory) - fetcher = FileFetcher(mapOf("/file_href" to File(text.path), "/dir_href" to File(directory.path))) + fetcher = FileFetcher( + mapOf("/file_href" to File(text.path), "/dir_href" to File(directory.path)), + MediaTypeRetriever() + ) } @Test diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt index 98defeea8b..0d307774a9 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt @@ -17,13 +17,14 @@ import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.Fixtures import org.readium.r2.shared.fetcher.EmptyFetcher -import org.readium.r2.shared.fetcher.Resource +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.StringResource import org.readium.r2.shared.publication.Publication.Profile import org.readium.r2.shared.publication.services.DefaultLocatorService import org.readium.r2.shared.publication.services.PositionsService import org.readium.r2.shared.publication.services.positions import org.readium.r2.shared.publication.services.positionsByReadingOrder +import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Ref import org.robolectric.RobolectricTestRunner @@ -408,7 +409,7 @@ class PublicationTest { @Test fun `get method passes on href parameters to services`() { val service = object : Publication.Service { - override fun get(link: Link): Resource? { + override fun get(link: Link): Fetcher.Resource? { assertFalse(link.templated) assertEquals("param1=a¶m2=b", link.href.substringAfter("?")) return StringResource(link, "test passed") diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt new file mode 100644 index 0000000000..5021f70a9e --- /dev/null +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.util.mediatype.MediaType +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class AdeptFallbackContentProtectionTest { + + @Test + fun `Sniff no content protection`() { + assertFalse(supports(mediaType = MediaType.EPUB, resources = emptyMap())) + } + + @Test + fun `Sniff EPUB with empty encryption xml`() { + assertFalse( + supports( + mediaType = MediaType.EPUB, + resources = mapOf( + "/META-INF/encryption.xml" to """""" + ) + ) + ) + } + + @Test + fun `Sniff Adobe ADEPT`() { + assertTrue( + supports( + mediaType = MediaType.EPUB, + resources = mapOf( + "/META-INF/encryption.xml" to """ + + + + urn:uuid:2c43729c-b985-4531-8e86-ae75ce5e5da9 + + + + + + """ + ) + ) + ) + } + + @Test + fun `Sniff Adobe ADEPT from rights xml`() { + assertTrue( + supports( + mediaType = MediaType.EPUB, + resources = mapOf( + "/META-INF/encryption.xml" to """""", + "/META-INF/rights.xml" to """""" + ) + ) + ) + } + + private fun supports(mediaType: MediaType, resources: Map): Boolean = runBlocking { + AdeptFallbackContentProtection().supports( + Asset.Container( + name = "fake name", + mediaType = mediaType, + exploded = false, + container = TestContainer(resources) + ) + ) + } +} diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt new file mode 100644 index 0000000000..31d3fe3d88 --- /dev/null +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.util.mediatype.MediaType +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class LcpFallbackContentProtectionTest { + + @Test + fun `Sniff no content protection`() { + assertFalse(supports(mediaType = MediaType.EPUB, resources = emptyMap())) + } + + @Test + fun `Sniff EPUB with empty encryption xml`() { + assertFalse( + supports( + mediaType = MediaType.EPUB, + resources = mapOf( + "/META-INF/encryption.xml" to """""" + ) + ) + ) + } + + @Test + fun `Sniff LCP protected Readium package`() { + assertTrue( + supports( + mediaType = MediaType.READIUM_WEBPUB, + resources = mapOf( + "/license.lcpl" to "{}" + ) + ) + ) + } + + @Test + fun `Sniff LCP protected EPUB`() { + assertTrue( + supports( + mediaType = MediaType.EPUB, + resources = mapOf( + "/META-INF/license.lcpl" to "{}" + ) + ) + ) + } + + @Test + fun `Sniff LCP protected EPUB missing the license`() { + assertTrue( + supports( + mediaType = MediaType.EPUB, + resources = mapOf( + "/META-INF/encryption.xml" to """ + + + + + + + + + + + + + + + +""" + ) + ) + ) + } + + private fun supports(mediaType: MediaType, resources: Map): Boolean = runBlocking { + LcpFallbackContentProtection().supports( + Asset.Container( + name = "fake name", + mediaType = mediaType, + exploded = false, + container = TestContainer(resources) + ) + ) + } +} diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt new file mode 100644 index 0000000000..28297f66dc --- /dev/null +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication.protection + +import java.io.File +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.StringResource + +class TestContainer(resources: Map = emptyMap()) : Container { + + private val entries: Map = + resources.mapValues { Entry(it.key, StringResource(it.value)) } + + override suspend fun name(): ResourceTry = + Try.success(null) + + override suspend fun entries(): Iterable = + entries.values + + override suspend fun entry(path: String): Container.Entry = + entries[path] ?: NotFoundEntry(path) + + override suspend fun close() {} + + private class NotFoundEntry( + override val path: String + ) : Container.Entry { + + override suspend fun name(): ResourceTry = + ResourceTry.success(File(path).name) + + override suspend fun length(): ResourceTry = + Try.failure(Resource.Exception.NotFound()) + + override suspend fun read(range: LongRange?): ResourceTry = + Try.failure(Resource.Exception.NotFound()) + + override suspend fun close() { + } + } + + private class Entry( + override val path: String, + private val resource: StringResource + ) : Resource by resource, Container.Entry +} diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt index 222565778c..b2e97029dd 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt @@ -23,6 +23,7 @@ import org.readium.r2.shared.fetcher.FileFetcher import org.readium.r2.shared.linkBlocking import org.readium.r2.shared.publication.* import org.readium.r2.shared.readBlocking +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -51,7 +52,7 @@ class CoverServiceTest { Link(href = coverPath, rels = setOf("cover")) ) ), - fetcher = FileFetcher(coverPath, File(coverPath)) + fetcher = FileFetcher(coverPath, File(coverPath), MediaTypeRetriever()) ) } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt index e07fae86ce..c7bce03ca8 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt @@ -20,6 +20,7 @@ import org.readium.r2.shared.extensions.optNullableInt import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.readAsString import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ResourceInputStreamTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/resource/ResourceInputStreamTest.kt similarity index 81% rename from readium/shared/src/test/java/org/readium/r2/shared/fetcher/ResourceInputStreamTest.kt rename to readium/shared/src/test/java/org/readium/r2/shared/resource/ResourceInputStreamTest.kt index 7495ed7b0a..eeaefbe70f 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ResourceInputStreamTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/resource/ResourceInputStreamTest.kt @@ -1,4 +1,4 @@ -package org.readium.r2.shared.fetcher +package org.readium.r2.shared.resource import java.io.ByteArrayOutputStream import java.io.File @@ -6,6 +6,9 @@ import kotlin.test.assertNotNull import kotlin.test.assertTrue import kotlinx.coroutines.runBlocking import org.junit.Test +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.fetcher.FileFetcher +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever class ResourceInputStreamTest { @@ -17,7 +20,7 @@ class ResourceInputStreamTest { val resource = ResourceInputStreamTest::class.java.getResource("epub.epub") assertNotNull(resource) fileContent = resource.openStream().readBytes() - val fileFetcher = runBlocking { FileFetcher("/epub.epub", File(resource.path)) } + val fileFetcher = runBlocking { FileFetcher("/epub.epub", File(resource.path), MediaTypeRetriever()) } assertNotNull(fileFetcher) fetcher = fileFetcher } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/util/archive/ArchiveTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/resource/ZipContainerTest.kt similarity index 51% rename from readium/shared/src/test/java/org/readium/r2/shared/util/archive/ArchiveTest.kt rename to readium/shared/src/test/java/org/readium/r2/shared/resource/ZipContainerTest.kt index 2d1d181666..a87b7b5684 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/util/archive/ArchiveTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/resource/ZipContainerTest.kt @@ -7,7 +7,7 @@ * LICENSE file present in the project repository where this source code is maintained. */ -package org.readium.r2.shared.util.archive +package org.readium.r2.shared.resource import java.io.File import java.nio.charset.StandardCharsets @@ -19,26 +19,38 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.util.archive.channel.ChannelZipArchiveFactory @RunWith(Parameterized::class) -class ArchiveTest(val archive: Archive) { +class ZipContainerTest(val container: Container) { companion object { @Parameterized.Parameters @JvmStatic - fun archives(): List { - val epubZip = ArchiveTest::class.java.getResource("epub.epub") + fun archives(): List { + val epubZip = ZipContainerTest::class.java.getResource("epub.epub") assertNotNull(epubZip) - val zipArchive = runBlocking { DefaultArchiveFactory().open(File(epubZip.path), password = null) } + val zipArchive = runBlocking { + DefaultArchiveFactory() + .create(FileResource(File(epubZip.path)), password = null) + .getOrNull() + } assertNotNull(zipArchive) - val apacheZipArchive = runBlocking { ChannelZipArchiveFactory().openFile(File(epubZip.path)) } + val apacheZipArchive = runBlocking { + ChannelZipArchiveFactory() + .openFile(File(epubZip.path)) + } assertNotNull(apacheZipArchive) - val epubExploded = ArchiveTest::class.java.getResource("epub") + val epubExploded = ZipContainerTest::class.java.getResource("epub") assertNotNull(epubExploded) - val explodedArchive = runBlocking { DefaultArchiveFactory().open(File(epubExploded.path), password = null) } + val explodedArchive = runBlocking { + DirectoryContainerFactory() + .create(File(epubExploded.path)) + .getOrNull() + } assertNotNull(explodedArchive) return listOf(zipArchive, apacheZipArchive, explodedArchive) @@ -47,56 +59,56 @@ class ArchiveTest(val archive: Archive) { @Test fun `Entry list is correct`() { - assertThat(runBlocking { archive.entries().map { it.path } }) + assertThat(runBlocking { container.entries()?.map { it.path }.orEmpty() }) .contains( - "mimetype", - "EPUB/cover.xhtml", - "EPUB/css/epub.css", - "EPUB/css/nav.css", - "EPUB/images/cover.png", - "EPUB/nav.xhtml", - "EPUB/package.opf", - "EPUB/s04.xhtml", - "EPUB/toc.ncx", - "META-INF/container.xml" + "/mimetype", + "/EPUB/cover.xhtml", + "/EPUB/css/epub.css", + "/EPUB/css/nav.css", + "/EPUB/images/cover.png", + "/EPUB/nav.xhtml", + "/EPUB/package.opf", + "/EPUB/s04.xhtml", + "/EPUB/toc.ncx", + "/META-INF/container.xml" ) } @Test - fun `Attempting to get a missing entry throws`() { - assertFails { runBlocking { archive.entry("unknown") } } + fun `Attempting to read a missing entry throws`() { + assertFails { runBlocking { container.entry("unknown").read().getOrThrow() } } } @Test fun `Fully reading an entry works well`() { - val bytes = runBlocking { archive.entry("mimetype").read() } + val bytes = runBlocking { container.entry("mimetype").read().getOrThrow() } assertEquals("application/epub+zip", bytes.toString(StandardCharsets.UTF_8)) } @Test fun `Reading a range of an entry works well`() { - val bytes = runBlocking { archive.entry("mimetype").read(0..10L) } + val bytes = runBlocking { container.entry("mimetype").read(0..10L).getOrThrow() } assertEquals("application", bytes.toString(StandardCharsets.UTF_8)) assertEquals(11, bytes.size) } @Test fun `Out of range indexes are clamped to the available length`() { - val bytes = runBlocking { archive.entry("mimetype").read(-5..60L) } + val bytes = runBlocking { container.entry("mimetype").read(-5..60L).getOrThrow() } assertEquals("application/epub+zip", bytes.toString(StandardCharsets.UTF_8)) assertEquals(20, bytes.size) } @Test fun `Decreasing ranges are understood as empty ones`() { - val bytes = runBlocking { archive.entry("mimetype").read(60..20L) } + val bytes = runBlocking { container.entry("mimetype").read(60..20L).getOrThrow() } assertEquals("", bytes.toString(StandardCharsets.UTF_8)) assertEquals(0, bytes.size) } @Test fun `Computing size works well`() { - val size = runBlocking { archive.entry("mimetype").length } + val size = runBlocking { container.entry("mimetype").length().getOrThrow() } assertEquals(20L, size) } } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeRetrieverTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeRetrieverTest.kt new file mode 100644 index 0000000000..1fd2905f6a --- /dev/null +++ b/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeRetrieverTest.kt @@ -0,0 +1,26 @@ +package org.readium.r2.shared.util.mediatype + +import kotlin.test.assertEquals +import kotlinx.coroutines.runBlocking +import org.junit.Test + +class MediaTypeRetrieverTest { + + private val mediaTypeRetriever = MediaTypeRetriever() + + @Test + fun `canonicalize media type`() = runBlocking { + assertEquals( + MediaType.parse("text/html", fileExtension = "html")!!, + mediaTypeRetriever.canonicalMediaType(MediaType.parse("text/html;charset=utf-8")!!) + ) + /*assertEquals( + MediaType.parse("application/atom+xml;profile=opds-catalog")!!, + mediaTypeRetriever.canonicalMediaType(MediaType.parse("application/atom+xml;profile=opds-catalog;charset=utf-8")!!) + ) + assertEquals( + MediaType.parse("application/unknown;charset=utf-8")!!, + mediaTypeRetriever.canonicalMediaType(MediaType.parse("application/unknown;charset=utf-8")!!.canonicalMediaType()) + )*/ + } +} diff --git a/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeTest.kt index fcc7315892..e08d0f6d19 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/MediaTypeTest.kt @@ -1,7 +1,6 @@ package org.readium.r2.shared.util.mediatype import kotlin.test.* -import kotlinx.coroutines.runBlocking import org.junit.Test class MediaTypeTest { @@ -116,13 +115,6 @@ class MediaTypeTest { assertEquals("UNKNOWN", MediaType.parse("text/html;charset=unknown")?.parameters?.get("charset")) } - @Test - fun `canonicalize media type`() = runBlocking { - assertEquals(MediaType.parse("text/html", fileExtension = "html")!!, MediaType.parse("text/html;charset=utf-8")!!.canonicalMediaType()) - assertEquals(MediaType.parse("application/atom+xml;profile=opds-catalog")!!, MediaType.parse("application/atom+xml;profile=opds-catalog;charset=utf-8")!!.canonicalMediaType()) - assertEquals(MediaType.parse("application/unknown;charset=utf-8")!!, MediaType.parse("application/unknown;charset=utf-8")!!.canonicalMediaType()) - } - @Test fun equality() { assertEquals(MediaType.parse("application/atom+xml")!!, MediaType.parse("application/atom+xml")!!) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/SnifferTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/SnifferTest.kt index f58c0c4a78..48efee5aa5 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/SnifferTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/SnifferTest.kt @@ -15,279 +15,280 @@ class SnifferTest { val fixtures = Fixtures("format") + private val mediaTypeRetriever: MediaTypeRetriever = + MediaTypeRetriever() + @Test fun `sniff ignores extension case`() = runBlocking { - assertEquals(MediaType.EPUB, MediaType.of(fileExtension = "EPUB")) + assertEquals(MediaType.EPUB, mediaTypeRetriever.retrieve(fileExtension = "EPUB")) } @Test fun `sniff ignores media type case`() = runBlocking { - assertEquals(MediaType.EPUB, MediaType.of(mediaType = "APPLICATION/EPUB+ZIP")) + assertEquals(MediaType.EPUB, mediaTypeRetriever.retrieve(mediaType = "APPLICATION/EPUB+ZIP")) } @Test fun `sniff ignores media type extra parameters`() = runBlocking { - assertEquals(MediaType.EPUB, MediaType.of(mediaType = "application/epub+zip;param=value")) + assertEquals(MediaType.EPUB, mediaTypeRetriever.retrieve(mediaType = "application/epub+zip;param=value")) } @Test fun `sniff from metadata`() = runBlocking { - assertNull(MediaType.of(fileExtension = null)) - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.of(fileExtension = "audiobook")) - assertNull(MediaType.of(mediaType = null)) - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.of(mediaType = "application/audiobook+zip")) - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.of(mediaType = "application/audiobook+zip")) - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.of(mediaType = "application/audiobook+zip", fileExtension = "audiobook")) - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.of(mediaTypes = listOf("application/audiobook+zip"), fileExtensions = listOf("audiobook"))) + assertNull(mediaTypeRetriever.retrieve(fileExtension = null)) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(fileExtension = "audiobook")) + assertNull(mediaTypeRetriever.retrieve(mediaType = null)) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(mediaType = "application/audiobook+zip")) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(mediaType = "application/audiobook+zip")) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(mediaType = "application/audiobook+zip", fileExtension = "audiobook")) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(mediaTypes = listOf("application/audiobook+zip"), fileExtensions = listOf("audiobook"))) } @Test fun `sniff from a file`() = runBlocking { - assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.ofFile(fixtures.fileAt("audiobook.json"))) + assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, mediaTypeRetriever.retrieve(fixtures.fileAt("audiobook.json"))) } @Test fun `sniff from bytes`() = runBlocking { - assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.ofBytes({ fixtures.fileAt("audiobook.json").readBytes() })) + assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, mediaTypeRetriever.retrieve({ fixtures.fileAt("audiobook.json").readBytes() })) } @Test fun `sniff unknown format`() = runBlocking { - assertNull(MediaType.of(mediaType = "invalid")) - assertNull(MediaType.ofFile(fixtures.fileAt("unknown"))) + assertNull(mediaTypeRetriever.retrieve(mediaType = "invalid")) + assertNull(mediaTypeRetriever.retrieve(fixtures.fileAt("unknown"))) } @Test fun `sniff falls back on parsing the given media type if it's valid`() = runBlocking { val expected = MediaType.parse("fruit/grapes")!! - assertEquals(expected, MediaType.of(mediaType = "fruit/grapes")) - assertEquals(expected, MediaType.of(mediaType = "fruit/grapes")) - assertEquals(expected, MediaType.of(mediaTypes = listOf("invalid", "fruit/grapes"), fileExtensions = emptyList())) - assertEquals(expected, MediaType.of(mediaTypes = listOf("fruit/grapes", "vegetable/brocoli"), fileExtensions = emptyList())) + assertEquals(expected, mediaTypeRetriever.retrieve(mediaType = "fruit/grapes")) + assertEquals(expected, mediaTypeRetriever.retrieve(mediaType = "fruit/grapes")) + assertEquals(expected, mediaTypeRetriever.retrieve(mediaTypes = listOf("invalid", "fruit/grapes"), fileExtensions = emptyList())) + assertEquals(expected, mediaTypeRetriever.retrieve(mediaTypes = listOf("fruit/grapes", "vegetable/brocoli"), fileExtensions = emptyList())) } @Test fun `sniff audiobook`() = runBlocking { - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.of(fileExtension = "audiobook")) - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.of(mediaType = "application/audiobook+zip")) - assertEquals(MediaType.READIUM_AUDIOBOOK, MediaType.ofFile(fixtures.fileAt("audiobook-package.unknown"))) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(fileExtension = "audiobook")) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(mediaType = "application/audiobook+zip")) + assertEquals(MediaType.READIUM_AUDIOBOOK, mediaTypeRetriever.retrieve(fixtures.fileAt("audiobook-package.unknown"))) } @Test fun `sniff audiobook manifest`() = runBlocking { - assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.of(mediaType = "application/audiobook+json")) - assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.ofFile(fixtures.fileAt("audiobook.json"))) - assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.ofFile(fixtures.fileAt("audiobook-wrongtype.json"))) + assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, mediaTypeRetriever.retrieve(mediaType = "application/audiobook+json")) + assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, mediaTypeRetriever.retrieve(fixtures.fileAt("audiobook.json"))) + assertEquals(MediaType.READIUM_AUDIOBOOK_MANIFEST, mediaTypeRetriever.retrieve(fixtures.fileAt("audiobook-wrongtype.json"))) } @Test fun `sniff BMP`() = runBlocking { - assertEquals(MediaType.BMP, MediaType.of(fileExtension = "bmp")) - assertEquals(MediaType.BMP, MediaType.of(fileExtension = "dib")) - assertEquals(MediaType.BMP, MediaType.of(mediaType = "image/bmp")) - assertEquals(MediaType.BMP, MediaType.of(mediaType = "image/x-bmp")) + assertEquals(MediaType.BMP, mediaTypeRetriever.retrieve(fileExtension = "bmp")) + assertEquals(MediaType.BMP, mediaTypeRetriever.retrieve(fileExtension = "dib")) + assertEquals(MediaType.BMP, mediaTypeRetriever.retrieve(mediaType = "image/bmp")) + assertEquals(MediaType.BMP, mediaTypeRetriever.retrieve(mediaType = "image/x-bmp")) } @Test fun `sniff CBZ`() = runBlocking { - assertEquals(MediaType.CBZ, MediaType.of(fileExtension = "cbz")) - assertEquals(MediaType.CBZ, MediaType.of(mediaType = "application/vnd.comicbook+zip")) - assertEquals(MediaType.CBZ, MediaType.of(mediaType = "application/x-cbz")) - assertEquals(MediaType.CBZ, MediaType.of(mediaType = "application/x-cbr")) - assertEquals(MediaType.CBZ, MediaType.ofFile(fixtures.fileAt("cbz.unknown"))) + assertEquals(MediaType.CBZ, mediaTypeRetriever.retrieve(fileExtension = "cbz")) + assertEquals(MediaType.CBZ, mediaTypeRetriever.retrieve(mediaType = "application/vnd.comicbook+zip")) + assertEquals(MediaType.CBZ, mediaTypeRetriever.retrieve(mediaType = "application/x-cbz")) + assertEquals(MediaType.CBZ, mediaTypeRetriever.retrieve(mediaType = "application/x-cbr")) + assertEquals(MediaType.CBZ, mediaTypeRetriever.retrieve(fixtures.fileAt("cbz.unknown"))) } @Test fun `sniff DiViNa`() = runBlocking { - assertEquals(MediaType.DIVINA, MediaType.of(fileExtension = "divina")) - assertEquals(MediaType.DIVINA, MediaType.of(mediaType = "application/divina+zip")) - assertEquals(MediaType.DIVINA, MediaType.ofFile(fixtures.fileAt("divina-package.unknown"))) + assertEquals(MediaType.DIVINA, mediaTypeRetriever.retrieve(fileExtension = "divina")) + assertEquals(MediaType.DIVINA, mediaTypeRetriever.retrieve(mediaType = "application/divina+zip")) + assertEquals(MediaType.DIVINA, mediaTypeRetriever.retrieve(fixtures.fileAt("divina-package.unknown"))) } @Test fun `sniff DiViNa manifest`() = runBlocking { - assertEquals(MediaType.DIVINA_MANIFEST, MediaType.of(mediaType = "application/divina+json")) - assertEquals(MediaType.DIVINA_MANIFEST, MediaType.ofFile(fixtures.fileAt("divina.json"))) + assertEquals(MediaType.DIVINA_MANIFEST, mediaTypeRetriever.retrieve(mediaType = "application/divina+json")) + assertEquals(MediaType.DIVINA_MANIFEST, mediaTypeRetriever.retrieve(fixtures.fileAt("divina.json"))) } @Test fun `sniff EPUB`() = runBlocking { - assertEquals(MediaType.EPUB, MediaType.of(fileExtension = "epub")) - assertEquals(MediaType.EPUB, MediaType.of(mediaType = "application/epub+zip")) - assertEquals(MediaType.EPUB, MediaType.ofFile(fixtures.fileAt("epub.unknown"))) + assertEquals(MediaType.EPUB, mediaTypeRetriever.retrieve(fileExtension = "epub")) + assertEquals(MediaType.EPUB, mediaTypeRetriever.retrieve(mediaType = "application/epub+zip")) + assertEquals(MediaType.EPUB, mediaTypeRetriever.retrieve(fixtures.fileAt("epub.unknown"))) } @Test fun `sniff AVIF`() = runBlocking { - assertEquals(MediaType.AVIF, MediaType.of(fileExtension = "avif")) - assertEquals(MediaType.AVIF, MediaType.of(mediaType = "image/avif")) + assertEquals(MediaType.AVIF, mediaTypeRetriever.retrieve(fileExtension = "avif")) + assertEquals(MediaType.AVIF, mediaTypeRetriever.retrieve(mediaType = "image/avif")) } @Test fun `sniff GIF`() = runBlocking { - assertEquals(MediaType.GIF, MediaType.of(fileExtension = "gif")) - assertEquals(MediaType.GIF, MediaType.of(mediaType = "image/gif")) + assertEquals(MediaType.GIF, mediaTypeRetriever.retrieve(fileExtension = "gif")) + assertEquals(MediaType.GIF, mediaTypeRetriever.retrieve(mediaType = "image/gif")) } @Test fun `sniff HTML`() = runBlocking { - assertEquals(MediaType.HTML, MediaType.of(fileExtension = "htm")) - assertEquals(MediaType.HTML, MediaType.of(fileExtension = "html")) - assertEquals(MediaType.HTML, MediaType.of(mediaType = "text/html")) - assertEquals(MediaType.HTML, MediaType.ofFile(fixtures.fileAt("html.unknown"))) - assertEquals(MediaType.HTML, MediaType.ofFile(fixtures.fileAt("html-doctype-case.unknown"))) + assertEquals(MediaType.HTML, mediaTypeRetriever.retrieve(fileExtension = "htm")) + assertEquals(MediaType.HTML, mediaTypeRetriever.retrieve(fileExtension = "html")) + assertEquals(MediaType.HTML, mediaTypeRetriever.retrieve(mediaType = "text/html")) + assertEquals(MediaType.HTML, mediaTypeRetriever.retrieve(fixtures.fileAt("html.unknown"))) + assertEquals(MediaType.HTML, mediaTypeRetriever.retrieve(fixtures.fileAt("html-doctype-case.unknown"))) } @Test fun `sniff XHTML`() = runBlocking { - assertEquals(MediaType.XHTML, MediaType.of(fileExtension = "xht")) - assertEquals(MediaType.XHTML, MediaType.of(fileExtension = "xhtml")) - assertEquals(MediaType.XHTML, MediaType.of(mediaType = "application/xhtml+xml")) - assertEquals(MediaType.XHTML, MediaType.ofFile(fixtures.fileAt("xhtml.unknown"))) + assertEquals(MediaType.XHTML, mediaTypeRetriever.retrieve(fileExtension = "xht")) + assertEquals(MediaType.XHTML, mediaTypeRetriever.retrieve(fileExtension = "xhtml")) + assertEquals(MediaType.XHTML, mediaTypeRetriever.retrieve(mediaType = "application/xhtml+xml")) + assertEquals(MediaType.XHTML, mediaTypeRetriever.retrieve(fixtures.fileAt("xhtml.unknown"))) } @Test fun `sniff JPEG`() = runBlocking { - assertEquals(MediaType.JPEG, MediaType.of(fileExtension = "jpg")) - assertEquals(MediaType.JPEG, MediaType.of(fileExtension = "jpeg")) - assertEquals(MediaType.JPEG, MediaType.of(fileExtension = "jpe")) - assertEquals(MediaType.JPEG, MediaType.of(fileExtension = "jif")) - assertEquals(MediaType.JPEG, MediaType.of(fileExtension = "jfif")) - assertEquals(MediaType.JPEG, MediaType.of(fileExtension = "jfi")) - assertEquals(MediaType.JPEG, MediaType.of(mediaType = "image/jpeg")) + assertEquals(MediaType.JPEG, mediaTypeRetriever.retrieve(fileExtension = "jpg")) + assertEquals(MediaType.JPEG, mediaTypeRetriever.retrieve(fileExtension = "jpeg")) + assertEquals(MediaType.JPEG, mediaTypeRetriever.retrieve(fileExtension = "jpe")) + assertEquals(MediaType.JPEG, mediaTypeRetriever.retrieve(fileExtension = "jif")) + assertEquals(MediaType.JPEG, mediaTypeRetriever.retrieve(fileExtension = "jfif")) + assertEquals(MediaType.JPEG, mediaTypeRetriever.retrieve(fileExtension = "jfi")) + assertEquals(MediaType.JPEG, mediaTypeRetriever.retrieve(mediaType = "image/jpeg")) } @Test fun `sniff JXL`() = runBlocking { - assertEquals(MediaType.JXL, MediaType.of(fileExtension = "jxl")) - assertEquals(MediaType.JXL, MediaType.of(mediaType = "image/jxl")) + assertEquals(MediaType.JXL, mediaTypeRetriever.retrieve(fileExtension = "jxl")) + assertEquals(MediaType.JXL, mediaTypeRetriever.retrieve(mediaType = "image/jxl")) } @Test fun `sniff OPDS 1 feed`() = runBlocking { - assertEquals(MediaType.OPDS1, MediaType.of(mediaType = "application/atom+xml;profile=opds-catalog")) - assertEquals(MediaType.OPDS1, MediaType.ofFile(fixtures.fileAt("opds1-feed.unknown"))) + assertEquals(MediaType.OPDS1, mediaTypeRetriever.retrieve(mediaType = "application/atom+xml;profile=opds-catalog")) + assertEquals(MediaType.OPDS1, mediaTypeRetriever.retrieve(fixtures.fileAt("opds1-feed.unknown"))) } @Test fun `sniff OPDS 1 entry`() = runBlocking { - assertEquals(MediaType.OPDS1_ENTRY, MediaType.of(mediaType = "application/atom+xml;type=entry;profile=opds-catalog")) - assertEquals(MediaType.OPDS1_ENTRY, MediaType.ofFile(fixtures.fileAt("opds1-entry.unknown"))) + assertEquals(MediaType.OPDS1_ENTRY, mediaTypeRetriever.retrieve(mediaType = "application/atom+xml;type=entry;profile=opds-catalog")) + assertEquals(MediaType.OPDS1_ENTRY, mediaTypeRetriever.retrieve(fixtures.fileAt("opds1-entry.unknown"))) } @Test fun `sniff OPDS 2 feed`() = runBlocking { - assertEquals(MediaType.OPDS2, MediaType.of(mediaType = "application/opds+json")) - assertEquals(MediaType.OPDS2, MediaType.ofFile(fixtures.fileAt("opds2-feed.json"))) + assertEquals(MediaType.OPDS2, mediaTypeRetriever.retrieve(mediaType = "application/opds+json")) + assertEquals(MediaType.OPDS2, mediaTypeRetriever.retrieve(fixtures.fileAt("opds2-feed.json"))) } @Test fun `sniff OPDS 2 publication`() = runBlocking { - assertEquals(MediaType.OPDS2_PUBLICATION, MediaType.of(mediaType = "application/opds-publication+json")) - assertEquals(MediaType.OPDS2_PUBLICATION, MediaType.ofFile(fixtures.fileAt("opds2-publication.json"))) + assertEquals(MediaType.OPDS2_PUBLICATION, mediaTypeRetriever.retrieve(mediaType = "application/opds-publication+json")) + assertEquals(MediaType.OPDS2_PUBLICATION, mediaTypeRetriever.retrieve(fixtures.fileAt("opds2-publication.json"))) } @Test fun `sniff OPDS authentication document`() = runBlocking { - assertEquals(MediaType.OPDS_AUTHENTICATION, MediaType.of(mediaType = "application/opds-authentication+json")) - assertEquals(MediaType.OPDS_AUTHENTICATION, MediaType.of(mediaType = "application/vnd.opds.authentication.v1.0+json")) - assertEquals(MediaType.OPDS_AUTHENTICATION, MediaType.ofFile(fixtures.fileAt("opds-authentication.json"))) + assertEquals(MediaType.OPDS_AUTHENTICATION, mediaTypeRetriever.retrieve(mediaType = "application/opds-authentication+json")) + assertEquals(MediaType.OPDS_AUTHENTICATION, mediaTypeRetriever.retrieve(mediaType = "application/vnd.opds.authentication.v1.0+json")) + assertEquals(MediaType.OPDS_AUTHENTICATION, mediaTypeRetriever.retrieve(fixtures.fileAt("opds-authentication.json"))) } @Test fun `sniff LCP protected audiobook`() = runBlocking { - assertEquals(MediaType.LCP_PROTECTED_AUDIOBOOK, MediaType.of(fileExtension = "lcpa")) - assertEquals(MediaType.LCP_PROTECTED_AUDIOBOOK, MediaType.of(mediaType = "application/audiobook+lcp")) - assertEquals(MediaType.LCP_PROTECTED_AUDIOBOOK, MediaType.ofFile(fixtures.fileAt("audiobook-lcp.unknown"))) + assertEquals(MediaType.LCP_PROTECTED_AUDIOBOOK, mediaTypeRetriever.retrieve(fileExtension = "lcpa")) + assertEquals(MediaType.LCP_PROTECTED_AUDIOBOOK, mediaTypeRetriever.retrieve(mediaType = "application/audiobook+lcp")) + assertEquals(MediaType.LCP_PROTECTED_AUDIOBOOK, mediaTypeRetriever.retrieve(fixtures.fileAt("audiobook-lcp.unknown"))) } @Test fun `sniff LCP protected PDF`() = runBlocking { - assertEquals(MediaType.LCP_PROTECTED_PDF, MediaType.of(fileExtension = "lcpdf")) - assertEquals(MediaType.LCP_PROTECTED_PDF, MediaType.of(mediaType = "application/pdf+lcp")) - assertEquals(MediaType.LCP_PROTECTED_PDF, MediaType.ofFile(fixtures.fileAt("pdf-lcp.unknown"))) + assertEquals(MediaType.LCP_PROTECTED_PDF, mediaTypeRetriever.retrieve(fileExtension = "lcpdf")) + assertEquals(MediaType.LCP_PROTECTED_PDF, mediaTypeRetriever.retrieve(mediaType = "application/pdf+lcp")) + assertEquals(MediaType.LCP_PROTECTED_PDF, mediaTypeRetriever.retrieve(fixtures.fileAt("pdf-lcp.unknown"))) } @Test fun `sniff LCP license document`() = runBlocking { - assertEquals(MediaType.LCP_LICENSE_DOCUMENT, MediaType.of(fileExtension = "lcpl")) - assertEquals(MediaType.LCP_LICENSE_DOCUMENT, MediaType.of(mediaType = "application/vnd.readium.lcp.license.v1.0+json")) - assertEquals(MediaType.LCP_LICENSE_DOCUMENT, MediaType.ofFile(fixtures.fileAt("lcpl.unknown"))) + assertEquals(MediaType.LCP_LICENSE_DOCUMENT, mediaTypeRetriever.retrieve(fileExtension = "lcpl")) + assertEquals(MediaType.LCP_LICENSE_DOCUMENT, mediaTypeRetriever.retrieve(mediaType = "application/vnd.readium.lcp.license.v1.0+json")) + assertEquals(MediaType.LCP_LICENSE_DOCUMENT, mediaTypeRetriever.retrieve(fixtures.fileAt("lcpl.unknown"))) } @Test fun `sniff LPF`() = runBlocking { - assertEquals(MediaType.LPF, MediaType.of(fileExtension = "lpf")) - assertEquals(MediaType.LPF, MediaType.of(mediaType = "application/lpf+zip")) - assertEquals(MediaType.LPF, MediaType.ofFile(fixtures.fileAt("lpf.unknown"))) - assertEquals(MediaType.LPF, MediaType.ofFile(fixtures.fileAt("lpf-index-html.unknown"))) + assertEquals(MediaType.LPF, mediaTypeRetriever.retrieve(fileExtension = "lpf")) + assertEquals(MediaType.LPF, mediaTypeRetriever.retrieve(mediaType = "application/lpf+zip")) + assertEquals(MediaType.LPF, mediaTypeRetriever.retrieve(fixtures.fileAt("lpf.unknown"))) + assertEquals(MediaType.LPF, mediaTypeRetriever.retrieve(fixtures.fileAt("lpf-index-html.unknown"))) } @Test fun `sniff PDF`() = runBlocking { - assertEquals(MediaType.PDF, MediaType.of(fileExtension = "pdf")) - assertEquals(MediaType.PDF, MediaType.of(mediaType = "application/pdf")) - assertEquals(MediaType.PDF, MediaType.ofFile(fixtures.fileAt("pdf.unknown"))) + assertEquals(MediaType.PDF, mediaTypeRetriever.retrieve(fileExtension = "pdf")) + assertEquals(MediaType.PDF, mediaTypeRetriever.retrieve(mediaType = "application/pdf")) + assertEquals(MediaType.PDF, mediaTypeRetriever.retrieve(fixtures.fileAt("pdf.unknown"))) } @Test fun `sniff PNG`() = runBlocking { - assertEquals(MediaType.PNG, MediaType.of(fileExtension = "png")) - assertEquals(MediaType.PNG, MediaType.of(mediaType = "image/png")) + assertEquals(MediaType.PNG, mediaTypeRetriever.retrieve(fileExtension = "png")) + assertEquals(MediaType.PNG, mediaTypeRetriever.retrieve(mediaType = "image/png")) } @Test fun `sniff TIFF`() = runBlocking { - assertEquals(MediaType.TIFF, MediaType.of(fileExtension = "tiff")) - assertEquals(MediaType.TIFF, MediaType.of(fileExtension = "tif")) - assertEquals(MediaType.TIFF, MediaType.of(mediaType = "image/tiff")) - assertEquals(MediaType.TIFF, MediaType.of(mediaType = "image/tiff-fx")) + assertEquals(MediaType.TIFF, mediaTypeRetriever.retrieve(fileExtension = "tiff")) + assertEquals(MediaType.TIFF, mediaTypeRetriever.retrieve(fileExtension = "tif")) + assertEquals(MediaType.TIFF, mediaTypeRetriever.retrieve(mediaType = "image/tiff")) + assertEquals(MediaType.TIFF, mediaTypeRetriever.retrieve(mediaType = "image/tiff-fx")) } @Test fun `sniff WebP`() = runBlocking { - assertEquals(MediaType.WEBP, MediaType.of(fileExtension = "webp")) - assertEquals(MediaType.WEBP, MediaType.of(mediaType = "image/webp")) + assertEquals(MediaType.WEBP, mediaTypeRetriever.retrieve(fileExtension = "webp")) + assertEquals(MediaType.WEBP, mediaTypeRetriever.retrieve(mediaType = "image/webp")) } @Test fun `sniff WebPub`() = runBlocking { - assertEquals(MediaType.READIUM_WEBPUB, MediaType.of(fileExtension = "webpub")) - assertEquals(MediaType.READIUM_WEBPUB, MediaType.of(mediaType = "application/webpub+zip")) - assertEquals(MediaType.READIUM_WEBPUB, MediaType.ofFile(fixtures.fileAt("webpub-package.unknown"))) + assertEquals(MediaType.READIUM_WEBPUB, mediaTypeRetriever.retrieve(fileExtension = "webpub")) + assertEquals(MediaType.READIUM_WEBPUB, mediaTypeRetriever.retrieve(mediaType = "application/webpub+zip")) + assertEquals(MediaType.READIUM_WEBPUB, mediaTypeRetriever.retrieve(fixtures.fileAt("webpub-package.unknown"))) } @Test fun `sniff WebPub manifest`() = runBlocking { - assertEquals(MediaType.READIUM_WEBPUB_MANIFEST, MediaType.of(mediaType = "application/webpub+json")) - assertEquals(MediaType.READIUM_WEBPUB_MANIFEST, MediaType.ofFile(fixtures.fileAt("webpub.json"))) + assertEquals(MediaType.READIUM_WEBPUB_MANIFEST, mediaTypeRetriever.retrieve(mediaType = "application/webpub+json")) + assertEquals(MediaType.READIUM_WEBPUB_MANIFEST, mediaTypeRetriever.retrieve(fixtures.fileAt("webpub.json"))) } @Test fun `sniff W3C WPUB manifest`() = runBlocking { - assertEquals(MediaType.W3C_WPUB_MANIFEST, MediaType.ofFile(fixtures.fileAt("w3c-wpub.json"))) + assertEquals(MediaType.W3C_WPUB_MANIFEST, mediaTypeRetriever.retrieve(fixtures.fileAt("w3c-wpub.json"))) } @Test fun `sniff ZAB`() = runBlocking { - assertEquals(MediaType.ZAB, MediaType.of(fileExtension = "zab")) - assertEquals(MediaType.ZAB, MediaType.ofFile(fixtures.fileAt("zab.unknown"))) + assertEquals(MediaType.ZAB, mediaTypeRetriever.retrieve(fileExtension = "zab")) + assertEquals(MediaType.ZAB, mediaTypeRetriever.retrieve(fixtures.fileAt("zab.unknown"))) } @Test fun `sniff JSON`() = runBlocking { - assertEquals(MediaType.JSON, MediaType.of(mediaType = "application/json")) - assertEquals(MediaType.JSON, MediaType.of(mediaType = "application/json; charset=utf-8")) - assertEquals(MediaType.JSON, MediaType.ofFile(fixtures.fileAt("any.json"))) + assertEquals(MediaType.JSON, mediaTypeRetriever.retrieve(fixtures.fileAt("any.json"))) } @Test fun `sniff JSON problem details`() = runBlocking { - assertEquals(MediaType.JSON_PROBLEM_DETAILS, MediaType.of(mediaType = "application/problem+json")) - assertEquals(MediaType.JSON_PROBLEM_DETAILS, MediaType.of(mediaType = "application/problem+json; charset=utf-8")) + assertEquals(MediaType.JSON_PROBLEM_DETAILS, mediaTypeRetriever.retrieve(mediaType = "application/problem+json")) + assertEquals(MediaType.JSON_PROBLEM_DETAILS, mediaTypeRetriever.retrieve(mediaType = "application/problem+json; charset=utf-8")) // The sniffing of a JSON document should not take precedence over the JSON problem details. - assertEquals(MediaType.JSON_PROBLEM_DETAILS, MediaType.ofBytes({ """{"title": "Message"}""".toByteArray() }, mediaType = "application/problem+json")) + assertEquals(MediaType.JSON_PROBLEM_DETAILS, mediaTypeRetriever.retrieve({ """{"title": "Message"}""".toByteArray() }, mediaType = "application/problem+json")) } @Test @@ -298,8 +299,8 @@ class SnifferTest { name = "XLSX", fileExtension = "xlsx" )!! - assertEquals(xlsx, MediaType.of(mediaTypes = emptyList(), fileExtensions = listOf("foobar", "xlsx"))) - assertEquals(xlsx, MediaType.of(mediaTypes = listOf("applicaton/foobar", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"), fileExtensions = emptyList())) + assertEquals(xlsx, mediaTypeRetriever.retrieve(mediaTypes = emptyList(), fileExtensions = listOf("foobar", "xlsx"))) + assertEquals(xlsx, mediaTypeRetriever.retrieve(mediaTypes = listOf("applicaton/foobar", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"), fileExtensions = emptyList())) } @Test @@ -310,6 +311,6 @@ class SnifferTest { name = "PNG", fileExtension = "png" )!! - assertEquals(png, MediaType.ofFile(fixtures.fileAt("png.unknown"))) + assertEquals(png, mediaTypeRetriever.retrieve(fixtures.fileAt("png.unknown"))) } } diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub.epub b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub.epub similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub.epub rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub.epub diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/cover.xhtml b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/cover.xhtml similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/cover.xhtml rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/cover.xhtml diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/css/epub.css b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/css/epub.css similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/css/epub.css rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/css/epub.css diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/css/nav.css b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/css/nav.css similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/css/nav.css rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/css/nav.css diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/images/cover.png b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/images/cover.png similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/images/cover.png rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/images/cover.png diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/nav.xhtml b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/nav.xhtml similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/nav.xhtml rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/nav.xhtml diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/package.opf b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/package.opf similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/package.opf rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/package.opf diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/s04.xhtml b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/s04.xhtml similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/s04.xhtml rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/s04.xhtml diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/toc.ncx b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/toc.ncx similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/EPUB/toc.ncx rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/EPUB/toc.ncx diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/META-INF/container.xml b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/META-INF/container.xml similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/META-INF/container.xml rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/META-INF/container.xml diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/mimetype b/readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/mimetype similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/util/archive/epub/mimetype rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/epub/mimetype diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt new file mode 100644 index 0000000000..36136397ef --- /dev/null +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt @@ -0,0 +1,128 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.streamer + +import java.io.File +import java.nio.charset.Charset +import org.json.JSONObject +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.error.* +import org.readium.r2.shared.fetcher.ContainerFetcher +import org.readium.r2.shared.fetcher.ResourceFetcher +import org.readium.r2.shared.fetcher.RoutingFetcher +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Manifest +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.http.HttpFetcher +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.streamer.parser.PublicationParser + +internal class ParserAssetFactory( + private val httpClient: HttpClient, + private val mediaTypeRetriever: MediaTypeRetriever, +) { + + suspend fun createParserAsset( + asset: Asset, + ): Try { + return when (asset) { + is Asset.Container -> + Try.success( + createParserAssetForContainer(asset.container, asset.mediaType, asset.name) + ) + is Asset.Resource -> + createParserAssetForResource(asset.resource, asset.mediaType, asset.name) + } + } + + private fun createParserAssetForContainer( + container: Container, + mediaType: MediaType, + assetName: String + ): PublicationParser.Asset { + val fetcher = ContainerFetcher(container, mediaTypeRetriever) + return PublicationParser.Asset(assetName, mediaType, fetcher) + } + + private suspend fun createParserAssetForResource( + resource: Resource, + mediaType: MediaType, + assetName: String + ): Try = + if (mediaType.isRwpm) { + createParserAssetForManifest(resource, assetName) + } else { + createParserAssetForContent(resource, mediaType, assetName) + } + + private suspend fun createParserAssetForManifest( + resource: Resource, + assetName: String + ): Try { + val manifest = resource.readAsRwpm(packaged = false) + .mapFailure { Publication.OpeningException.ParsingFailed(ThrowableError(it)) } + .getOrElse { return Try.failure(it) } + + val baseUrl = + manifest.linkWithRel("self")?.let { File(it.href).parent } + ?: return Try.failure( + Publication.OpeningException.ParsingFailed( + MessageError("No self link in the manifest.") + ) + ) + + if (!baseUrl.startsWith("http")) { + return Try.failure( + Publication.OpeningException.UnsupportedAsset("Self link doesn't use the HTTP(S) scheme.") + ) + } + + val link = Link( + href = "/manifest.json", + type = MediaType.READIUM_WEBPUB_MANIFEST.toString() + ) + + val fetcher = + RoutingFetcher( + local = ResourceFetcher(link, resource), + remote = HttpFetcher(httpClient, baseUrl) + ) + + return Try.success( + PublicationParser.Asset(assetName, MediaType.READIUM_WEBPUB, fetcher) + ) + } + + private fun createParserAssetForContent( + resource: Resource, + mediaType: MediaType, + assetName: String + ): Try { + val link = Link(href = "/$assetName", type = mediaType.toString()) + val fetcher = ResourceFetcher(link, resource) + + return Try.success( + PublicationParser.Asset(assetName, mediaType, fetcher) + ) + } + + private suspend fun Resource.readAsRwpm(packaged: Boolean): Try = + try { + val bytes = read().getOrThrow() + val string = String(bytes, Charset.defaultCharset()) + val json = JSONObject(string) + val manifest = Manifest.fromJSON(json, packaged = packaged) + ?: throw Exception("Failed to parse the RWPM Manifest") + Try.success(manifest) + } catch (e: Exception) { + Try.failure(e) + } +} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt new file mode 100644 index 0000000000..9d59974ae4 --- /dev/null +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt @@ -0,0 +1,268 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.streamer + +import android.content.Context +import org.readium.r2.shared.PdfSupport +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.protection.AdeptFallbackContentProtection +import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.publication.protection.LcpFallbackContentProtection +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.http.DefaultHttpClient +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.logging.WarningLogger +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.util.pdf.PdfDocumentFactory +import org.readium.r2.streamer.parser.PublicationParser +import org.readium.r2.streamer.parser.audio.AudioParser +import org.readium.r2.streamer.parser.epub.EpubParser +import org.readium.r2.streamer.parser.epub.setLayoutStyle +import org.readium.r2.streamer.parser.image.ImageParser +import org.readium.r2.streamer.parser.pdf.PdfParser +import org.readium.r2.streamer.parser.readium.ReadiumWebPubParser + +internal typealias PublicationTry = Try + +/** + * Opens a Publication using a list of parsers. + * + * The [PublicationFactory] is configured to use Readium's default parsers, which you can bypass using + * [ignoreDefaultParsers]. However, you can provide additional [parsers] which will take precedence + * over the default ones. This can also be used to provide an alternative configuration of a + * default parser. + * + * @param context Application context. + * @param parsers Parsers used to open a publication, in addition to the default parsers. + * @param ignoreDefaultParsers When true, only parsers provided in parsers will be used. + * @param pdfFactory Parses a PDF document, optionally protected by password. + * @param contentProtections Opens DRM-protected publications. + * @param httpClient Service performing HTTP requests. + * @param mediaTypeRetriever Retrieves media types from different sources. + * @param onCreatePublication Called on every parsed [Publication.Builder]. It can be used to modify + * the [Manifest], the root [Fetcher] or the list of service factories of a [Publication]. + */ +@OptIn(PdfSupport::class) +class PublicationFactory constructor( + context: Context, + parsers: List = emptyList(), + ignoreDefaultParsers: Boolean = false, + contentProtections: List = emptyList(), + pdfFactory: PdfDocumentFactory<*>? = null, + httpClient: HttpClient = DefaultHttpClient(), + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), + private val onCreatePublication: Publication.Builder.() -> Unit = {}, +) { + + private val contentProtections: Map = + buildList { + add(LcpFallbackContentProtection(mediaTypeRetriever)) + add(AdeptFallbackContentProtection(mediaTypeRetriever)) + addAll(contentProtections.asReversed()) + }.associateBy(ContentProtection::scheme) + + private val defaultParsers: List = + listOfNotNull( + EpubParser(), + pdfFactory?.let { PdfParser(context, it) }, + ReadiumWebPubParser(context, pdfFactory), + ImageParser(), + AudioParser() + ) + + private val parsers: List = parsers + + if (!ignoreDefaultParsers) defaultParsers else emptyList() + + private val parserAssetFactory: ParserAssetFactory = + ParserAssetFactory(httpClient, mediaTypeRetriever) + + /** + * Opens a [Publication] from the given asset. + * + * If you are opening the publication to render it in a Navigator, you must set [allowUserInteraction] + * to true to prompt the user for its credentials when the publication is protected. However, + * set it to false if you just want to import the [Publication] without reading its content, to + * avoid prompting the user. + * + * When using Content Protections, you can use [sender] to provide a free object which can be + * used to give some context. For example, it could be the source Activity or Fragment which + * would be used to present a credentials dialog. + * + * The [warnings] logger can be used to observe non-fatal parsing warnings, caused by + * publication authoring mistakes. This can be useful to warn users of potential rendering + * issues. + * + * @param asset Digital medium (e.g. a file) used to access the publication. + * @param contentProtectionScheme Scheme of the [ContentProtection] protecting the publication, + * or null if there is none. + * @param credentials Credentials that Content Protections can use to attempt to unlock a + * publication, for example a password. + * @param allowUserInteraction Indicates whether the user can be prompted, for example for its + * credentials. + * @param sender Free object that can be used by reading apps to give some UX context when + * presenting dialogs. + * @param onCreatePublication Transformation which will be applied on the Publication Builder. + * It can be used to modify the [Manifest], the root [Fetcher] or the list of service + * factories of the [Publication]. + * @param warnings Logger used to broadcast non-fatal parsing warnings. + * @return A [Publication] or a [Publication.OpeningException] in case of failure. + */ + suspend fun open( + asset: Asset, + contentProtectionScheme: ContentProtection.Scheme? = null, + credentials: String? = null, + allowUserInteraction: Boolean, + sender: Any? = null, + onCreatePublication: Publication.Builder.() -> Unit = {}, + warnings: WarningLogger? = null + ): PublicationTry { + val compositeOnCreatePublication: Publication.Builder.() -> Unit = { + this@PublicationFactory.onCreatePublication(this) + onCreatePublication(this) + } + + return if (contentProtectionScheme == null) { + openUnprotected( + asset, + compositeOnCreatePublication, + warnings + ) + } else { + openProtected( + asset, + contentProtectionScheme, + credentials, + allowUserInteraction, + sender, + compositeOnCreatePublication, + warnings + ) + } + } + + private suspend fun openUnprotected( + asset: Asset, + onCreatePublication: Publication.Builder.() -> Unit, + warnings: WarningLogger? + ): Try { + val parserAsset = parserAssetFactory.createParserAsset(asset) + .getOrElse { return Try.failure(it) } + return openParserAsset(parserAsset, onCreatePublication, warnings) + } + + private suspend fun openProtected( + asset: Asset, + contentProtectionScheme: ContentProtection.Scheme, + credentials: String?, + allowUserInteraction: Boolean, + sender: Any?, + onCreatePublication: Publication.Builder.() -> Unit, + warnings: WarningLogger? + ): Try { + val protectedAsset = contentProtections[contentProtectionScheme] + ?.open(asset, credentials, allowUserInteraction, sender) + ?.getOrElse { return Try.failure(it) } + ?: return Try.failure(Publication.OpeningException.Forbidden()) + + val parserAsset = PublicationParser.Asset( + protectedAsset.name, + protectedAsset.mediaType, + protectedAsset.fetcher + ) + + val compositeOnCreatePublication: Publication.Builder.() -> Unit = { + protectedAsset.onCreatePublication.invoke(this) + onCreatePublication(this) + } + + return openParserAsset(parserAsset, compositeOnCreatePublication, warnings) + } + + private suspend fun openParserAsset( + publicationAsset: PublicationParser.Asset, + onCreatePublication: Publication.Builder.() -> Unit = {}, + warnings: WarningLogger? = null + ): Try { + val builder = parse(publicationAsset, warnings) + .getOrElse { return Try.failure(wrapParserException(it)) } + + builder.apply(onCreatePublication) + + val publication = builder.build() + .apply { addLegacyProperties(publicationAsset.mediaType) } + return Try.success(publication) + } + + private suspend fun parse( + publicationAsset: PublicationParser.Asset, + warnings: WarningLogger? + ): Try { + for (parser in parsers) { + val result = parser.parse(publicationAsset, warnings) + if ( + result is Try.Success || + result is Try.Failure && result.value !is PublicationParser.Error.FormatNotSupported + ) { + return result + } + } + return Try.failure(PublicationParser.Error.FormatNotSupported()) + } + + private fun wrapParserException(e: PublicationParser.Error): Publication.OpeningException = + when (e) { + is PublicationParser.Error.FormatNotSupported -> + Publication.OpeningException.UnsupportedAsset("Cannot find a parser for this asset") + is PublicationParser.Error.IO -> + when (e.resourceError) { + is Resource.Exception.BadRequest, is Resource.Exception.Other -> + Publication.OpeningException.Unexpected(e) + is Resource.Exception.Forbidden -> + Publication.OpeningException.Forbidden(e) + is Resource.Exception.NotFound -> + Publication.OpeningException.ParsingFailed(e) + is Resource.Exception.OutOfMemory -> + Publication.OpeningException.OutOfMemory(e) + is Resource.Exception.Unavailable, is Resource.Exception.Offline -> + Publication.OpeningException.Unavailable(e) + } + is PublicationParser.Error.OutOfMemory -> + Publication.OpeningException.OutOfMemory(e) + is PublicationParser.Error.ParsingFailed -> + Publication.OpeningException.ParsingFailed(e) + } + + @Suppress("UNCHECKED_CAST") + private suspend fun List.lazyMapFirstNotNullOrNull(transform: suspend (T) -> R): R? { + for (it in this) { + return transform(it) ?: continue + } + return null + } + + private fun Publication.addLegacyProperties(mediaType: MediaType?) { + @Suppress("DEPRECATION") + type = mediaType.toPublicationType() + + if (mediaType == MediaType.EPUB) + setLayoutStyle() + } +} + +internal fun MediaType?.toPublicationType(): Publication.TYPE = + when (this) { + MediaType.READIUM_AUDIOBOOK, MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.LCP_PROTECTED_AUDIOBOOK -> Publication.TYPE.AUDIO + MediaType.DIVINA, MediaType.DIVINA_MANIFEST -> Publication.TYPE.DiViNa + MediaType.CBZ -> Publication.TYPE.CBZ + MediaType.EPUB -> Publication.TYPE.EPUB + else -> Publication.TYPE.WEBPUB + } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt deleted file mode 100644 index d1b3f8f09b..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/Streamer.kt +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Module: r2-streamer-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.streamer - -import android.content.Context -import org.readium.r2.shared.PdfSupport -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.ContentProtection -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.asset.DefaultPublicationAssetFactory -import org.readium.r2.shared.publication.asset.PublicationAsset -import org.readium.r2.shared.publication.asset.PublicationAssetFactory -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.archive.DefaultArchiveFactory -import org.readium.r2.shared.util.flatMap -import org.readium.r2.shared.util.http.DefaultHttpClient -import org.readium.r2.shared.util.logging.WarningLogger -import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.pdf.PdfDocumentFactory -import org.readium.r2.streamer.parser.FallbackContentProtection -import org.readium.r2.streamer.parser.PublicationParser -import org.readium.r2.streamer.parser.audio.AudioParser -import org.readium.r2.streamer.parser.epub.EpubParser -import org.readium.r2.streamer.parser.epub.setLayoutStyle -import org.readium.r2.streamer.parser.image.ImageParser -import org.readium.r2.streamer.parser.pdf.PdfParser -import org.readium.r2.streamer.parser.readium.ReadiumWebPubParser - -internal typealias PublicationTry = Try - -/** - * Opens a Publication using a list of parsers. - * - * The [Streamer] is configured to use Readium's default parsers, which you can bypass using - * [ignoreDefaultParsers]. However, you can provide additional [parsers] which will take precedence - * over the default ones. This can also be used to provide an alternative configuration of a - * default parser. - * - * @param context Application context. - * @param parsers Parsers used to open a publication, in addition to the default parsers. - * @param ignoreDefaultParsers When true, only parsers provided in parsers will be used. - * @param archiveFactory Opens an archive (e.g. ZIP, RAR), optionally protected by credentials. If - * you use the default [PublicationAssetFactory], your [ArchiveFactory] must support the protocols - * you want to open archive publications through. - * @param pdfFactory Parses a PDF document, optionally protected by password. - * @param httpClient Service performing HTTP requests. - * @param publicationAssetFactory Builds publication assets through various protocols. The default one - * supports protocols file, http and https. - * @param onCreatePublication Called on every parsed [Publication.Builder]. It can be used to modify - * the [Manifest], the root [Fetcher] or the list of service factories of a [Publication]. - */ -@OptIn(PdfSupport::class) -class Streamer constructor( - context: Context, - parsers: List = emptyList(), - ignoreDefaultParsers: Boolean = false, - contentProtections: List = emptyList(), - private val archiveFactory: ArchiveFactory = DefaultArchiveFactory(), - private val pdfFactory: PdfDocumentFactory<*>? = null, - private val httpClient: DefaultHttpClient = DefaultHttpClient(), - private val publicationAssetFactory: PublicationAssetFactory = - DefaultPublicationAssetFactory(archiveFactory, httpClient), - private val onCreatePublication: Publication.Builder.() -> Unit = {} -) { - - private val contentProtections: List = - contentProtections + listOf(FallbackContentProtection()) - - /** - * Parses a [Publication] available at [url]. - * - * If you are opening the publication to render it in a Navigator, you must set [allowUserInteraction] - * to true to prompt the user for its credentials when the publication is protected. However, - * set it to false if you just want to import the [Publication] without reading its content, to - * avoid prompting the user. - * - * When using Content Protections, you can use [sender] to provide a free object which can be - * used to give some context. For example, it could be the source Activity or Fragment which - * would be used to present a credentials dialog. - * - * The [warnings] logger can be used to observe non-fatal parsing warnings, caused by - * publication authoring mistakes. This can be useful to warn users of potential rendering - * issues. - * - * @param url Publication url. Supported protocols depend on your [PublicationAssetFactory]. - * @param credentials Credentials that Content Protections can use to attempt to unlock a - * publication, for example a password. - * @param allowUserInteraction Indicates whether the user can be prompted, for example for its - * credentials. - * @param sender Free object that can be used by reading apps to give some UX context when - * presenting dialogs. - * @param onCreatePublication Transformation which will be applied on the Publication Builder. - * It can be used to modify the [Manifest], the root [Fetcher] or the list of service - * factories of the [Publication]. - * @param warnings Logger used to broadcast non-fatal parsing warnings. - * @return Null if the asset was not recognized by any parser, or a - * [Publication.OpeningException] in case of failure. - */ - suspend fun open( - url: Url, - mediaType: MediaType, - credentials: String? = null, - allowUserInteraction: Boolean, - sender: Any? = null, - onCreatePublication: Publication.Builder.() -> Unit = {}, - warnings: WarningLogger? = null - ): PublicationTry = - publicationAssetFactory - .createAsset(url, mediaType) - .flatMap { asset -> open(asset, credentials, allowUserInteraction, sender, onCreatePublication, warnings) } - - /** - * Parses a [Publication] from the given asset. - * - * If you are opening the publication to render it in a Navigator, you must set [allowUserInteraction] - * to true to prompt the user for its credentials when the publication is protected. However, - * set it to false if you just want to import the [Publication] without reading its content, to - * avoid prompting the user. - * - * When using Content Protections, you can use [sender] to provide a free object which can be - * used to give some context. For example, it could be the source Activity or Fragment which - * would be used to present a credentials dialog. - * - * The [warnings] logger can be used to observe non-fatal parsing warnings, caused by - * publication authoring mistakes. This can be useful to warn users of potential rendering - * issues. - * - * @param asset Digital medium (e.g. a file) used to access the publication. - * @param credentials Credentials that Content Protections can use to attempt to unlock a - * publication, for example a password. - * @param allowUserInteraction Indicates whether the user can be prompted, for example for its - * credentials. - * @param sender Free object that can be used by reading apps to give some UX context when - * presenting dialogs. - * @param onCreatePublication Transformation which will be applied on the Publication Builder. - * It can be used to modify the [Manifest], the root [Fetcher] or the list of service - * factories of the [Publication]. - * @param warnings Logger used to broadcast non-fatal parsing warnings. - * @return Null if the asset was not recognized by any parser, or a - * [Publication.OpeningException] in case of failure. - */ - suspend fun open( - asset: PublicationAsset, - credentials: String? = null, - allowUserInteraction: Boolean, - sender: Any? = null, - onCreatePublication: Publication.Builder.() -> Unit = {}, - warnings: WarningLogger? = null - ): PublicationTry = try { - - val protectedAsset = contentProtections - .lazyMapFirstNotNullOrNull { - it.open(asset, credentials, allowUserInteraction, sender) - } - ?.getOrThrow() - - val newAsset = protectedAsset?.asset ?: asset - - val builder = parsers - .lazyMapFirstNotNullOrNull { - try { - it.parse(newAsset, warnings) - } catch (e: Exception) { - throw Publication.OpeningException.ParsingFailed(e) - } - } ?: throw Publication.OpeningException.UnsupportedFormat(Exception("Cannot find a parser for this asset")) - - // Transform from the Content Protection. - protectedAsset?.let { builder.apply(it.onCreatePublication) } - // Transform provided by the reading app during the construction of the Streamer. - builder.apply(this.onCreatePublication) - // Transform provided by the reading app in `Streamer.open()`. - builder.apply(onCreatePublication) - - val publication = builder.build() - .apply { addLegacyProperties(asset.mediaType) } - - Try.success(publication) - } catch (e: Publication.OpeningException) { - Try.failure(e) - } - - private val defaultParsers: List by lazy { - listOfNotNull( - EpubParser(), - pdfFactory?.let { PdfParser(context, it) }, - ReadiumWebPubParser(context, pdfFactory), - ImageParser(), - AudioParser() - ) - } - - private val parsers: List = parsers + - if (!ignoreDefaultParsers) defaultParsers else emptyList() - - @Suppress("UNCHECKED_CAST") - private suspend fun List.lazyMapFirstNotNullOrNull(transform: suspend (T) -> R): R? { - for (it in this) { - return transform(it) ?: continue - } - return null - } - - private fun Publication.addLegacyProperties(mediaType: MediaType?) { - @Suppress("DEPRECATION") - type = mediaType.toPublicationType() - - if (mediaType == MediaType.EPUB) - setLayoutStyle() - } -} - -internal fun MediaType?.toPublicationType(): Publication.TYPE = - when (this) { - MediaType.READIUM_AUDIOBOOK, MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.LCP_PROTECTED_AUDIOBOOK -> Publication.TYPE.AUDIO - MediaType.DIVINA, MediaType.DIVINA_MANIFEST -> Publication.TYPE.DiViNa - MediaType.CBZ -> Publication.TYPE.CBZ - MediaType.EPUB -> Publication.TYPE.EPUB - else -> Publication.TYPE.WEBPUB - } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt index 2402644281..2ee9f6b3ba 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt @@ -27,6 +27,7 @@ import org.readium.r2.shared.drm.DRM * * @func dataInputStream : return the InputStream of content */ +@Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) interface Container { var rootFile: RootFile var drm: DRM? diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt index ca38ad03b4..38cbb4a633 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt @@ -9,29 +9,13 @@ package org.readium.r2.streamer.extensions -import java.io.File import org.json.JSONObject -import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.fetcher.ArchiveFetcher import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.FileFetcher -import org.readium.r2.shared.fetcher.Resource import org.readium.r2.shared.parser.xml.ElementNode -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.util.archive.ArchiveFactory -import org.readium.r2.shared.util.archive.DefaultArchiveFactory +import org.readium.r2.shared.resource.readAsJson +import org.readium.r2.shared.resource.readAsXml import org.readium.r2.shared.util.use -/** Returns the resource data at the given [Link]'s HREF, or throws a [Resource.Exception] */ -@Throws(Resource.Exception::class) -internal suspend fun Fetcher.readBytes(link: Link): ByteArray = - get(link).use { it.read().getOrThrow() } - -/** Returns the resource data at the given [href], or throws a [Resource.Exception] */ -@Throws(Resource.Exception::class) -internal suspend fun Fetcher.readBytes(href: String): ByteArray = - get(href).use { it.read().getOrThrow() } - /** Returns the resource data as an XML Document at the given [href], or null. */ internal suspend fun Fetcher.readAsXmlOrNull(href: String): ElementNode? = get(href).use { it.readAsXml().getOrNull() } @@ -40,21 +24,6 @@ internal suspend fun Fetcher.readAsXmlOrNull(href: String): ElementNode? = internal suspend fun Fetcher.readAsJsonOrNull(href: String): JSONObject? = get(href).use { it.readAsJson().getOrNull() } -/** Creates a [Fetcher] from either an archive file, or an exploded directory. **/ -internal suspend fun Fetcher.Companion.fromArchiveOrDirectory( - path: String, - archiveFactory: ArchiveFactory = DefaultArchiveFactory() -): Fetcher? { - val file = File(path) - val isDirectory = tryOrNull { file.isDirectory } ?: return null - - return if (isDirectory) { - FileFetcher(href = "/", file = file) - } else { - ArchiveFetcher.fromPath(path, archiveFactory) - } -} - internal suspend fun Fetcher.guessTitle(): String? { val firstLink = links().firstOrNull() ?: return null val commonFirstComponent = links().hrefCommonFirstComponent() ?: return null diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt index 359e40a728..902ef763ae 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt @@ -11,16 +11,12 @@ package org.readium.r2.streamer.fetcher import java.io.InputStream import org.readium.r2.shared.publication.Publication -import org.readium.r2.streamer.container.Container -import org.readium.r2.streamer.server.Resources @Suppress("UNUSED_PARAMETER", "unused") @Deprecated("Use [publication.get(link)] to access publication content.", level = DeprecationLevel.ERROR) class Fetcher( var publication: Publication, - var container: Container, private val userPropertiesPath: String?, - customResources: Resources? = null ) { fun data(path: String): ByteArray? = throw NotImplementedError() diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/HtmlInjector.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/HtmlInjector.kt deleted file mode 100644 index 23c67e74cf..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/HtmlInjector.kt +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Aferdita Muriqi, Clément Baumannn, Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -@file:Suppress("DEPRECATION") - -package org.readium.r2.streamer.fetcher - -import java.io.File -import org.json.JSONArray -import org.json.JSONObject -import org.readium.r2.shared.Injectable -import org.readium.r2.shared.ReadiumCSSName -import org.readium.r2.shared.fetcher.LazyResource -import org.readium.r2.shared.fetcher.Resource -import org.readium.r2.shared.fetcher.ResourceTry -import org.readium.r2.shared.fetcher.TransformingResource -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.epub.EpubLayout -import org.readium.r2.shared.publication.epub.layoutOf -import org.readium.r2.shared.publication.presentation.presentation -import org.readium.r2.shared.publication.services.isProtected -import org.readium.r2.streamer.parser.epub.ReadiumCssLayout -import org.readium.r2.streamer.server.Resources -import timber.log.Timber - -internal class HtmlInjector( - val publication: Publication, - val userPropertiesPath: String?, - val customResources: Resources? = null -) { - - fun transform(resource: Resource): Resource = LazyResource { - - val link = resource.link() - if (link.mediaType.isHtml) - inject(resource) - else - resource - } - - private suspend fun inject(resource: Resource): Resource = object : TransformingResource(resource) { - - override suspend fun transform(data: ResourceTry): ResourceTry = - data.map { - val trimmedText = it.toString(link().mediaType.charset ?: Charsets.UTF_8).trim() - val res = if (publication.metadata.presentation.layoutOf(link()) == EpubLayout.REFLOWABLE) - injectReflowableHtml(trimmedText) - else - injectFixedLayoutHtml(trimmedText) - res.toByteArray() - } - } - - private fun injectReflowableHtml(content: String): String { - var resourceHtml = content - // Inject links to css and js files - val head = regexForOpeningHTMLTag("head").find(resourceHtml, 0) - if (head == null) { - Timber.e("No tag found in this resource") - return resourceHtml - } - var beginHeadIndex = head.range.last + 1 - var endHeadIndex = resourceHtml.indexOf("", 0, true) - if (endHeadIndex == -1) - return content - - val layout = ReadiumCssLayout(publication.metadata) - - val endIncludes = mutableListOf() - val beginIncludes = mutableListOf() - beginIncludes.add(getHtmlLink("/assets/readium-css/${layout.readiumCSSPath}ReadiumCSS-before.css")) - - // Fix Readium CSS issue with the positioning of .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n}\n;// CONCATENATED MODULE: ./src/keyboard.js\n//\n// Copyright 2023 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nwindow.addEventListener("keydown", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "down");\n});\nwindow.addEventListener("keyup", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "up");\n});\n\nfunction shouldIgnoreEvent(event) {\n return event.defaultPrevented || nearestInteractiveElement(document.activeElement) != null;\n} // We prevent the default behavior for keyboard events, otherwise the web view\n// might scroll.\n\n\nfunction preventDefault(event) {\n event.stopPropagation();\n event.preventDefault();\n}\n\nfunction sendPressKeyMessage(event, type) {\n if (event.repeat) return;\n var keyEvent = {\n type: type,\n code: event.code,\n characters: String.fromCharCode(event.keyCode),\n alt: event.altKey,\n control: event.ctrlKey,\n shift: event.shiftKey,\n meta: event.metaKey\n };\n Android.onKey(JSON.stringify(keyEvent));\n}\n;// CONCATENATED MODULE: ./src/highlight.js\nfunction highlight_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { highlight_typeof = function _typeof(obj) { return typeof obj; }; } else { highlight_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return highlight_typeof(obj); }\n\nfunction highlight_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = highlight_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction highlight_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return highlight_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return highlight_arrayLikeToArray(o, minLen); }\n\nfunction highlight_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/* eslint-disable */\n//\n// highlight.js\n// r2-navigator-kotlin\n//\n// Organized by Taehyun Kim on 6/27/19 from r2-navigator-js.\n//\n// Copyright 2019 Readium Foundation. All rights reserved.\n// Use of this source code is governed by a BSD-style license which is detailed\n// in the LICENSE file present in the project repository where this source code is maintained.\n//\nvar ROOT_CLASS_REDUCE_MOTION = "r2-reduce-motion";\nvar ROOT_CLASS_NO_FOOTNOTES = "r2-no-popup-foonotes";\nvar POPUP_DIALOG_CLASS = "r2-popup-dialog";\nvar FOOTNOTES_CONTAINER_CLASS = "r2-footnote-container";\nvar FOOTNOTES_CLOSE_BUTTON_CLASS = "r2-footnote-close";\nvar FOOTNOTE_FORCE_SHOW = "r2-footnote-force-show";\nvar TTS_ID_PREVIOUS = "r2-tts-previous";\nvar TTS_ID_NEXT = "r2-tts-next";\nvar TTS_ID_SLIDER = "r2-tts-slider";\nvar TTS_ID_ACTIVE_WORD = "r2-tts-active-word";\nvar TTS_ID_CONTAINER = "r2-tts-txt";\nvar TTS_ID_INFO = "r2-tts-info";\nvar TTS_NAV_BUTTON_CLASS = "r2-tts-button";\nvar TTS_ID_SPEAKING_DOC_ELEMENT = "r2-tts-speaking-el";\nvar TTS_CLASS_INJECTED_SPAN = "r2-tts-speaking-txt";\nvar TTS_CLASS_INJECTED_SUBSPAN = "r2-tts-speaking-word";\nvar TTS_ID_INJECTED_PARENT = "r2-tts-speaking-txt-parent";\nvar ID_HIGHLIGHTS_CONTAINER = "R2_ID_HIGHLIGHTS_CONTAINER";\nvar ID_ANNOTATION_CONTAINER = "R2_ID_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_CONTAINER = "R2_CLASS_HIGHLIGHT_CONTAINER";\nvar CLASS_ANNOTATION_CONTAINER = "R2_CLASS_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_AREA = "R2_CLASS_HIGHLIGHT_AREA";\nvar CLASS_ANNOTATION_AREA = "R2_CLASS_ANNOTATION_AREA";\nvar CLASS_HIGHLIGHT_BOUNDING_AREA = "R2_CLASS_HIGHLIGHT_BOUNDING_AREA";\nvar CLASS_ANNOTATION_BOUNDING_AREA = "R2_CLASS_ANNOTATION_BOUNDING_AREA"; // tslint:disable-next-line:max-line-length\n\nvar _blacklistIdClassForCFI = [POPUP_DIALOG_CLASS, TTS_CLASS_INJECTED_SPAN, TTS_CLASS_INJECTED_SUBSPAN, ID_HIGHLIGHTS_CONTAINER, CLASS_HIGHLIGHT_CONTAINER, CLASS_HIGHLIGHT_AREA, CLASS_HIGHLIGHT_BOUNDING_AREA, "resize-sensor"];\nvar CLASS_PAGINATED = "r2-css-paginated"; //const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");\n\nvar IS_DEV = false;\nvar _highlights = [];\n\nvar _highlightsContainer;\n\nvar _annotationContainer;\n\nvar lastMouseDownX = -1;\nvar lastMouseDownY = -1;\nvar bodyEventListenersSet = false;\nvar USE_SVG = false;\nvar DEFAULT_BACKGROUND_COLOR_OPACITY = 0.3;\nvar ALT_BACKGROUND_COLOR_OPACITY = 0.45; //const DEBUG_VISUALS = false;\n\nvar DEBUG_VISUALS = false;\nvar DEFAULT_BACKGROUND_COLOR = {\n blue: 100,\n green: 50,\n red: 230\n};\nvar ANNOTATION_WIDTH = 15;\n\nfunction resetHighlightBoundingStyle(_win, highlightBounding) {\n if (highlightBounding.getAttribute("class") == CLASS_ANNOTATION_BOUNDING_AREA) {\n return;\n }\n\n highlightBounding.style.outline = "none";\n highlightBounding.style.setProperty("background-color", "transparent", "important");\n}\n\nfunction setHighlightAreaStyle(win, highlightAreas, highlight) {\n var useSVG = !DEBUG_VISUALS && USE_SVG;\n\n var _iterator = highlight_createForOfIteratorHelper(highlightAreas),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var highlightArea = _step.value;\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var opacity = ALT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n}\n\nfunction resetHighlightAreaStyle(win, highlightArea) {\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var id = isSVG ? highlightArea.parentNode && highlightArea.parentNode.parentNode && highlightArea.parentNode.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.parentNode.getAttribute ? highlightArea.parentNode.parentNode.getAttribute("id") : undefined : highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.getAttribute ? highlightArea.parentNode.getAttribute("id") : undefined;\n\n if (id) {\n var highlight = _highlights.find(function (h) {\n return h.id === id;\n });\n\n if (highlight) {\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n }\n}\n\nfunction processTouchEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.changedTouches[0].clientX;\n var y = ev.changedTouches[0].clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect; // _highlights.sort(function(a, b) {\n // console.log(JSON.stringify(a.selectionInfo))\n // return a.selectionInfo.cleanText.length < b.selectionInfo.cleanText.length\n // })\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator2 = highlight_createForOfIteratorHelper(highlightFragments),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var highlightFragment = _step2.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator3 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var highlightBounding = _step3.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i = 0, _allHighlightAreas = allHighlightAreas; _i < _allHighlightAreas.length; _i++) {\n var highlightArea = _allHighlightAreas[_i];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas2 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator4 = highlight_createForOfIteratorHelper(_allHighlightAreas2),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var _highlightArea = _step4.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea) < 0) {\n resetHighlightAreaStyle(win, _highlightArea);\n }\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator5 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step5;\n\n try {\n for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {\n var _highlightBounding = _step5.value;\n\n if (!foundElementHighlightBounding || _highlightBounding !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding);\n }\n }\n } catch (err) {\n _iterator5.e(err);\n } finally {\n _iterator5.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "touchstart" || ev.type === "touchend") {\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight.id,\n size: size\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n console.log(foundHighlight.id.includes("R2_ANNOTATION_"));\n\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n}\n\nfunction processMouseEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.clientX;\n var y = ev.clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect;\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator6 = highlight_createForOfIteratorHelper(highlightFragments),\n _step6;\n\n try {\n for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {\n var highlightFragment = _step6.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator6.e(err);\n } finally {\n _iterator6.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator7 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step7;\n\n try {\n for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {\n var highlightBounding = _step7.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator7.e(err);\n } finally {\n _iterator7.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i2 = 0, _allHighlightAreas3 = allHighlightAreas; _i2 < _allHighlightAreas3.length; _i2++) {\n var highlightArea = _allHighlightAreas3[_i2];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas4 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator8 = highlight_createForOfIteratorHelper(_allHighlightAreas4),\n _step8;\n\n try {\n for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {\n var _highlightArea2 = _step8.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea2) < 0) {\n resetHighlightAreaStyle(win, _highlightArea2);\n }\n }\n } catch (err) {\n _iterator8.e(err);\n } finally {\n _iterator8.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator9 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step9;\n\n try {\n for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {\n var _highlightBounding2 = _step9.value;\n\n if (!foundElementHighlightBounding || _highlightBounding2 !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding2);\n }\n }\n } catch (err) {\n _iterator9.e(err);\n } finally {\n _iterator9.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "mouseup" || ev.type === "touchend") {\n var touchedPosition = {\n screenWidth: window.outerWidth,\n screenHeight: window.innerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight,\n position: touchedPosition\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n }\n }\n}\n\nfunction highlight_rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && highlight_almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && highlight_almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && highlight_almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && highlight_almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction highlight_replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("replaceOverlapingRects rect1 === rect2 ??!");\n }\n\n continue;\n }\n\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret = function () {\n var toAdd = [];\n var toRemove = void 0;\n var toPreserve = void 0;\n var subtractRects1 = highlight_rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n var subtractRects2 = highlight_rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n toPreserve = rect1;\n }\n }\n\n if (IS_DEV) {\n var toCheck = [];\n toCheck.push(toPreserve);\n Array.prototype.push.apply(toCheck, toAdd);\n checkOverlaps(toCheck);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: highlight_replaceOverlapingRects(newRects)\n };\n }();\n\n if (highlight_typeof(_ret) === "object") return _ret.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction checkOverlaps(rects) {\n var stillOverlapingRects = [];\n\n var _iterator10 = highlight_createForOfIteratorHelper(rects),\n _step10;\n\n try {\n for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {\n var rect1 = _step10.value;\n\n var _iterator11 = highlight_createForOfIteratorHelper(rects),\n _step11;\n\n try {\n for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {\n var rect2 = _step11.value;\n\n if (rect1 === rect2) {\n continue;\n }\n\n var has1 = stillOverlapingRects.indexOf(rect1) >= 0;\n var has2 = stillOverlapingRects.indexOf(rect2) >= 0;\n\n if (!has1 || !has2) {\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n if (!has1) {\n stillOverlapingRects.push(rect1);\n }\n\n if (!has2) {\n stillOverlapingRects.push(rect2);\n }\n\n console.log("CLIENT RECT: overlap ---");\n console.log("#1 TOP:".concat(rect1.top, " BOTTOM:").concat(rect1.bottom, " LEFT:").concat(rect1.left, " RIGHT:").concat(rect1.right, " WIDTH:").concat(rect1.width, " HEIGHT:").concat(rect1.height));\n console.log("#2 TOP:".concat(rect2.top, " BOTTOM:").concat(rect2.bottom, " LEFT:").concat(rect2.left, " RIGHT:").concat(rect2.right, " WIDTH:").concat(rect2.width, " HEIGHT:").concat(rect2.height));\n var xOverlap = getRectOverlapX(rect1, rect2);\n console.log("xOverlap: ".concat(xOverlap));\n var yOverlap = getRectOverlapY(rect1, rect2);\n console.log("yOverlap: ".concat(yOverlap));\n }\n }\n }\n } catch (err) {\n _iterator11.e(err);\n } finally {\n _iterator11.f();\n }\n }\n } catch (err) {\n _iterator10.e(err);\n } finally {\n _iterator10.f();\n }\n\n if (stillOverlapingRects.length) {\n console.log("CLIENT RECT: overlaps ".concat(stillOverlapingRects.length));\n }\n}\n\nfunction highlight_removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator12 = highlight_createForOfIteratorHelper(rects),\n _step12;\n\n try {\n for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {\n var rect = _step12.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove tiny");\n }\n\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator13 = highlight_createForOfIteratorHelper(rects),\n _step13;\n\n try {\n for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {\n var possiblyContainingRect = _step13.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (highlight_rectContains(possiblyContainingRect, rect, tolerance)) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove contained");\n }\n\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator13.e(err);\n } finally {\n _iterator13.f();\n }\n }\n } catch (err) {\n _iterator12.e(err);\n } finally {\n _iterator12.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction highlight_almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction highlight_rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n var rect = {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n return rect;\n}\n\nfunction highlight_rectSubtract(rect1, rect2) {\n var rectIntersected = highlight_rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction highlight_rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || highlight_almostEqual(rect.left, x, tolerance)) && (rect.right > x || highlight_almostEqual(rect.right, x, tolerance)) && (rect.top < y || highlight_almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || highlight_almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction highlight_rectContains(rect1, rect2, tolerance) {\n return highlight_rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction highlight_getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction highlight_mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("mergeTouchingRects rect1 === rect2 ??!");\n }\n\n return "continue";\n }\n\n var rectsLineUpVertically = highlight_almostEqual(rect1.top, rect2.top, tolerance) && highlight_almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = highlight_almostEqual(rect1.left, rect2.left, tolerance) && highlight_almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && highlight_rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n if (IS_DEV) {\n console.log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = highlight_getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: highlight_mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret2 = _loop(j);\n\n if (_ret2 === "continue") continue;\n if (highlight_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n\n return rects;\n}\n\nfunction highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var rangeClientRects = range.getClientRects();\n return getClientRectsNoOverlap_(rangeClientRects, doNotMergeHorizontallyAlignedRects);\n}\n\nfunction getClientRectsNoOverlap_(clientRects, doNotMergeHorizontallyAlignedRects) {\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator14 = highlight_createForOfIteratorHelper(clientRects),\n _step14;\n\n try {\n for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {\n var rangeClientRect = _step14.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator14.e(err);\n } finally {\n _iterator14.f();\n }\n\n var mergedRects = highlight_mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = highlight_removeContainedRects(mergedRects, tolerance);\n var newRects = highlight_replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small");\n }\n\n newRects.splice(j, 1);\n } else {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small, but keep otherwise empty!");\n }\n\n break;\n }\n }\n }\n\n if (IS_DEV) {\n checkOverlaps(newRects);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n }\n\n return newRects;\n}\n\nfunction isPaginated(document) {\n return document && document.documentElement && document.documentElement.classList.contains(CLASS_PAGINATED);\n}\n\nfunction getScrollingElement(document) {\n if (document.scrollingElement) {\n return document.scrollingElement;\n }\n\n return document.body;\n}\n\nfunction ensureContainer(win, annotationFlag) {\n var document = win.document;\n\n if (!_highlightsContainer) {\n if (!bodyEventListenersSet) {\n bodyEventListenersSet = true;\n document.body.addEventListener("mousedown", function (ev) {\n lastMouseDownX = ev.clientX;\n lastMouseDownY = ev.clientY;\n }, false);\n document.body.addEventListener("mouseup", function (ev) {\n if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {\n processMouseEvent(win, ev);\n }\n }, false);\n document.body.addEventListener("mousemove", function (ev) {\n processMouseEvent(win, ev);\n }, false);\n document.body.addEventListener("touchend", function touchEnd(e) {\n processTouchEvent(win, e);\n }, false);\n }\n\n _highlightsContainer = document.createElement("div");\n\n _highlightsContainer.setAttribute("id", ID_HIGHLIGHTS_CONTAINER);\n\n _highlightsContainer.style.setProperty("pointer-events", "none");\n\n document.body.append(_highlightsContainer);\n }\n\n return _highlightsContainer;\n}\n\nfunction hideAllhighlights() {\n if (_highlightsContainer) {\n _highlightsContainer.remove();\n\n _highlightsContainer = null;\n }\n}\n\nfunction destroyAllhighlights() {\n hideAllhighlights();\n\n _highlights.splice(0, _highlights.length);\n}\n\nfunction destroyHighlight(id) {\n var i = -1;\n var _document = window.document;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (highlight && i >= 0 && i < _highlights.length) {\n _highlights.splice(i, 1);\n }\n\n var highlightContainer = _document.getElementById(id);\n\n if (highlightContainer) {\n highlightContainer.remove();\n }\n}\n\nfunction isCfiTextNode(node) {\n return node.nodeType !== Node.ELEMENT_NODE;\n}\n\nfunction getChildTextNodeCfiIndex(element, child) {\n var found = -1;\n var textNodeIndex = -1;\n var previousWasElement = false;\n\n for (var i = 0; i < element.childNodes.length; i++) {\n var childNode = element.childNodes[i];\n var isText = isCfiTextNode(childNode);\n\n if (isText || previousWasElement) {\n textNodeIndex += 2;\n }\n\n if (isText) {\n if (childNode === child) {\n found = textNodeIndex;\n break;\n }\n }\n\n previousWasElement = childNode.nodeType === Node.ELEMENT_NODE;\n }\n\n return found;\n}\n\nfunction getCommonAncestorElement(node1, node2) {\n if (node1.nodeType === Node.ELEMENT_NODE && node1 === node2) {\n return node1;\n }\n\n if (node1.nodeType === Node.ELEMENT_NODE && node1.contains(node2)) {\n return node1;\n }\n\n if (node2.nodeType === Node.ELEMENT_NODE && node2.contains(node1)) {\n return node2;\n }\n\n var node1ElementAncestorChain = [];\n var parent = node1.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node1ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var node2ElementAncestorChain = [];\n parent = node2.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node2ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var commonAncestor = node1ElementAncestorChain.find(function (node1ElementAncestor) {\n return node2ElementAncestorChain.indexOf(node1ElementAncestor) >= 0;\n });\n\n if (!commonAncestor) {\n commonAncestor = node2ElementAncestorChain.find(function (node2ElementAncestor) {\n return node1ElementAncestorChain.indexOf(node2ElementAncestor) >= 0;\n });\n }\n\n return commonAncestor;\n}\n\nfunction fullQualifiedSelector(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n return lowerCaseName;\n } //return cssPath(node, justSelector);\n\n\n return cssPath(node, true);\n}\n\nfunction getCurrentSelectionInfo() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n console.log("^^^ SELECTION COLLAPSED.");\n return undefined;\n }\n\n var rawText = selection.toString();\n var cleanText = rawText.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanText.length === 0) {\n console.log("^^^ SELECTION TEXT EMPTY.");\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n console.log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var rangeInfo = convertRange(range, fullQualifiedSelector, computeCFI);\n\n if (!rangeInfo) {\n console.log("^^^ SELECTION RANGE INFO FAIL?!");\n return undefined;\n }\n\n if (IS_DEV && DEBUG_VISUALS) {\n var restoredRange = convertRangeInfo(win.document, rangeInfo);\n\n if (restoredRange) {\n if (restoredRange.startOffset === range.startOffset && restoredRange.endOffset === range.endOffset && restoredRange.startContainer === range.startContainer && restoredRange.endContainer === range.endContainer) {\n console.log("SELECTION RANGE RESTORED OKAY (dev check).");\n } else {\n console.log("SELECTION RANGE RESTORE FAIL (dev check).");\n dumpDebug("SELECTION", selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset, getCssSelector);\n dumpDebug("ORDERED RANGE FROM SELECTION", range.startContainer, range.startOffset, range.endContainer, range.endOffset, getCssSelector);\n dumpDebug("RESTORED RANGE", restoredRange.startContainer, restoredRange.startOffset, restoredRange.endContainer, restoredRange.endOffset, getCssSelector);\n }\n } else {\n console.log("CANNOT RESTORE SELECTION RANGE ??!");\n }\n } else {}\n\n return {\n locations: rangeInfo2Location(rangeInfo),\n text: {\n highlight: rawText\n }\n };\n}\n\nfunction checkBlacklisted(el) {\n var blacklistedId;\n var id = el.getAttribute("id");\n\n if (id && _blacklistIdClassForCFI.indexOf(id) >= 0) {\n console.log("checkBlacklisted ID: " + id);\n blacklistedId = id;\n }\n\n var blacklistedClass;\n\n var _iterator15 = highlight_createForOfIteratorHelper(_blacklistIdClassForCFI),\n _step15;\n\n try {\n for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {\n var item = _step15.value;\n\n if (el.classList.contains(item)) {\n console.log("checkBlacklisted CLASS: " + item);\n blacklistedClass = item;\n break;\n }\n }\n } catch (err) {\n _iterator15.e(err);\n } finally {\n _iterator15.f();\n }\n\n if (blacklistedId || blacklistedClass) {\n return true;\n }\n\n return false;\n}\n\nfunction cssPath(node, optimized) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return "";\n }\n\n var steps = [];\n var contextNode = node;\n\n while (contextNode) {\n var step = _cssPathStep(contextNode, !!optimized, contextNode === node);\n\n if (!step) {\n break; // Error - bail out early.\n }\n\n steps.push(step.value);\n\n if (step.optimized) {\n break;\n }\n\n contextNode = contextNode.parentNode;\n }\n\n steps.reverse();\n return steps.join(" > ");\n} // tslint:disable-next-line:max-line-length\n// https://chromium.googlesource.com/chromium/blink/+/master/Source/devtools/front_end/components/DOMPresentationUtils.js#316\n\n\nfunction _cssPathStep(node, optimized, isTargetNode) {\n function prefixedElementClassNames(nd) {\n var classAttribute = nd.getAttribute("class");\n\n if (!classAttribute) {\n return [];\n }\n\n return classAttribute.split(/\\s+/g).filter(Boolean).map(function (nm) {\n // The prefix is required to store "__proto__" in a object-based map.\n return "$" + nm;\n });\n }\n\n function idSelector(idd) {\n return "#" + escapeIdentifierIfNeeded(idd);\n }\n\n function escapeIdentifierIfNeeded(ident) {\n if (isCSSIdentifier(ident)) {\n return ident;\n }\n\n var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);\n var lastIndex = ident.length - 1;\n return ident.replace(/./g, function (c, ii) {\n return shouldEscapeFirst && ii === 0 || !isCSSIdentChar(c) ? escapeAsciiChar(c, ii === lastIndex) : c;\n });\n }\n\n function escapeAsciiChar(c, isLast) {\n return "\\\\" + toHexByte(c) + (isLast ? "" : " ");\n }\n\n function toHexByte(c) {\n var hexByte = c.charCodeAt(0).toString(16);\n\n if (hexByte.length === 1) {\n hexByte = "0" + hexByte;\n }\n\n return hexByte;\n }\n\n function isCSSIdentChar(c) {\n if (/[a-zA-Z0-9_-]/.test(c)) {\n return true;\n }\n\n return c.charCodeAt(0) >= 0xa0;\n }\n\n function isCSSIdentifier(value) {\n return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n var element = node;\n var id = element.getAttribute("id");\n\n if (optimized) {\n if (id) {\n return {\n optimized: true,\n value: idSelector(id)\n };\n }\n\n if (lowerCaseName === "body" || lowerCaseName === "head" || lowerCaseName === "html") {\n return {\n optimized: true,\n value: lowerCaseName // node.nodeNameInCorrectCase(),\n\n };\n }\n }\n\n var nodeName = lowerCaseName; // node.nodeNameInCorrectCase();\n\n if (id) {\n return {\n optimized: true,\n value: nodeName + idSelector(id)\n };\n }\n\n var parent = node.parentNode;\n\n if (!parent || parent.nodeType === Node.DOCUMENT_NODE) {\n return {\n optimized: true,\n value: nodeName\n };\n }\n\n var prefixedOwnClassNamesArray_ = prefixedElementClassNames(element);\n var prefixedOwnClassNamesArray = []; // .keySet()\n\n prefixedOwnClassNamesArray_.forEach(function (arrItem) {\n if (prefixedOwnClassNamesArray.indexOf(arrItem) < 0) {\n prefixedOwnClassNamesArray.push(arrItem);\n }\n });\n var needsClassNames = false;\n var needsNthChild = false;\n var ownIndex = -1;\n var elementIndex = -1;\n var siblings = parent.children;\n\n var _loop2 = function _loop2(i) {\n var sibling = siblings[i];\n\n if (sibling.nodeType !== Node.ELEMENT_NODE) {\n return "continue";\n }\n\n elementIndex += 1;\n\n if (sibling === node) {\n ownIndex = elementIndex;\n return "continue";\n }\n\n if (needsNthChild) {\n return "continue";\n } // sibling.nodeNameInCorrectCase()\n\n\n var siblingName = sibling.localName && sibling.localName.toLowerCase() || sibling.nodeName.toLowerCase();\n\n if (siblingName !== nodeName) {\n return "continue";\n }\n\n needsClassNames = true;\n var ownClassNames = [];\n prefixedOwnClassNamesArray.forEach(function (arrItem) {\n ownClassNames.push(arrItem);\n });\n var ownClassNameCount = ownClassNames.length;\n\n if (ownClassNameCount === 0) {\n needsNthChild = true;\n return "continue";\n }\n\n var siblingClassNamesArray_ = prefixedElementClassNames(sibling);\n var siblingClassNamesArray = []; // .keySet()\n\n siblingClassNamesArray_.forEach(function (arrItem) {\n if (siblingClassNamesArray.indexOf(arrItem) < 0) {\n siblingClassNamesArray.push(arrItem);\n }\n });\n\n for (var _i3 = 0, _siblingClassNamesArr = siblingClassNamesArray; _i3 < _siblingClassNamesArr.length; _i3++) {\n var siblingClass = _siblingClassNamesArr[_i3];\n var ind = ownClassNames.indexOf(siblingClass);\n\n if (ind < 0) {\n continue;\n }\n\n ownClassNames.splice(ind, 1); // delete ownClassNames[siblingClass];\n\n if (! --ownClassNameCount) {\n needsNthChild = true;\n break;\n }\n }\n };\n\n for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {\n var _ret3 = _loop2(i);\n\n if (_ret3 === "continue") continue;\n }\n\n var result = nodeName;\n\n if (isTargetNode && nodeName === "input" && element.getAttribute("type") && !element.getAttribute("id") && !element.getAttribute("class")) {\n result += \'[type="\' + element.getAttribute("type") + \'"]\';\n }\n\n if (needsNthChild) {\n result += ":nth-child(" + (ownIndex + 1) + ")";\n } else if (needsClassNames) {\n var _iterator16 = highlight_createForOfIteratorHelper(prefixedOwnClassNamesArray),\n _step16;\n\n try {\n for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {\n var prefixedName = _step16.value;\n result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));\n }\n } catch (err) {\n _iterator16.e(err);\n } finally {\n _iterator16.f();\n }\n }\n\n return {\n optimized: false,\n value: result\n };\n}\n\nfunction computeCFI(node) {\n // TODO: handle character position inside text node\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var cfi = "";\n var currentElement = node;\n\n while (currentElement.parentNode && currentElement.parentNode.nodeType === Node.ELEMENT_NODE) {\n var blacklisted = checkBlacklisted(currentElement);\n\n if (!blacklisted) {\n var currentElementParentChildren = currentElement.parentNode.children;\n var currentElementIndex = -1;\n\n for (var i = 0; i < currentElementParentChildren.length; i++) {\n if (currentElement === currentElementParentChildren[i]) {\n currentElementIndex = i;\n break;\n }\n }\n\n if (currentElementIndex >= 0) {\n var cfiIndex = (currentElementIndex + 1) * 2;\n cfi = cfiIndex + (currentElement.id ? "[" + currentElement.id + "]" : "") + (cfi.length ? "/" + cfi : "");\n }\n }\n\n currentElement = currentElement.parentNode;\n }\n\n return "/" + cfi;\n}\n\nfunction _createHighlight(locations, color, pointerInteraction, type) {\n var rangeInfo = location2RangeInfo(locations);\n var uniqueStr = "".concat(rangeInfo.cfi).concat(rangeInfo.startContainerElementCssSelector).concat(rangeInfo.startContainerChildTextNodeIndex).concat(rangeInfo.startOffset).concat(rangeInfo.endContainerElementCssSelector).concat(rangeInfo.endContainerChildTextNodeIndex).concat(rangeInfo.endOffset);\n\n var hash = __webpack_require__(3715);\n\n var sha256Hex = hash.sha256().update(uniqueStr).digest("hex");\n var id;\n\n if (type == ID_HIGHLIGHTS_CONTAINER) {\n id = "R2_HIGHLIGHT_" + sha256Hex;\n } else {\n id = "R2_ANNOTATION_" + sha256Hex;\n }\n\n destroyHighlight(id);\n var highlight = {\n color: color ? color : DEFAULT_BACKGROUND_COLOR,\n id: id,\n pointerInteraction: pointerInteraction,\n rangeInfo: rangeInfo\n };\n\n _highlights.push(highlight);\n\n createHighlightDom(window, highlight, type == ID_ANNOTATION_CONTAINER ? true : false);\n return highlight;\n}\n\nfunction createHighlight(selectionInfo, color, pointerInteraction) {\n return _createHighlight(selectionInfo, color, pointerInteraction, ID_HIGHLIGHTS_CONTAINER);\n}\nfunction createAnnotation(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (i == _highlights.length) return;\n var locations = {\n locations: rangeInfo2Location(highlight.rangeInfo)\n };\n return _createHighlight(locations, highlight.color, true, ID_ANNOTATION_CONTAINER);\n}\n\nfunction createHighlightDom(win, highlight, annotationFlag) {\n var document = win.document;\n var scale = 1 / (win.READIUM2 && win.READIUM2.isFixedLayout ? win.READIUM2.fxlViewportScale : 1);\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var paginated = isPaginated(document);\n var highlightsContainer = ensureContainer(win, annotationFlag);\n var highlightParent = document.createElement("div");\n highlightParent.setAttribute("id", highlight.id);\n highlightParent.setAttribute("class", CLASS_HIGHLIGHT_CONTAINER);\n document.body.style.position = "relative";\n highlightParent.style.setProperty("pointer-events", "none");\n\n if (highlight.pointerInteraction) {\n highlightParent.setAttribute("data-click", "1");\n }\n\n var bodyRect = document.body.getBoundingClientRect();\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var highlightAreaSVGDocFrag;\n var roundedCorner = 3;\n var underlineThickness = 2;\n var strikeThroughLineThickness = 3;\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n var extra = "";\n var rangeAnnotationBoundingClientRect = frameForHighlightAnnotationMarkWithID(win, highlight.id);\n var xOffset;\n var yOffset;\n var annotationOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n annotationOffset = parseInt((rangeAnnotationBoundingClientRect.right - xOffset) / window.innerWidth) + 1;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n annotationOffset = parseInt(rangeAnnotationBoundingClientRect.right / window.innerWidth + 1);\n }\n\n var _iterator17 = highlight_createForOfIteratorHelper(clientRects),\n _step17;\n\n try {\n for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {\n var clientRect = _step17.value;\n\n if (useSVG) {\n var borderThickness = 0;\n\n if (!highlightAreaSVGDocFrag) {\n highlightAreaSVGDocFrag = document.createDocumentFragment();\n }\n\n var highlightAreaSVGRect = document.createElementNS(SVG_XML_NAMESPACE, "rect");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGRect.setAttribute("style", "fill: rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; fill-opacity: ").concat(opacity, " !important; stroke-width: 0;"));\n highlightAreaSVGRect.scale = scale;\n /*\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGRect.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaSVGRect.setAttribute("rx", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("ry", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("x", "".concat((highlightAreaSVGRect.rect.left - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("y", "".concat((highlightAreaSVGRect.rect.top - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("height", "".concat((highlightAreaSVGRect.rect.height + borderThickness * 2) * scale));\n highlightAreaSVGRect.setAttribute("width", "".concat((highlightAreaSVGRect.rect.width + borderThickness * 2) * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGRect);\n\n if (drawUnderline) {\n var highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGLine.setAttribute("style", "stroke-linecap: round; stroke-width: ".concat(underlineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n var lineOffset = highlightAreaSVGLine.rect.width > roundedCorner ? roundedCorner : 0;\n highlightAreaSVGLine.setAttribute("x1", "".concat((highlightAreaSVGLine.rect.left + lineOffset) * scale));\n highlightAreaSVGLine.setAttribute("x2", "".concat((highlightAreaSVGLine.rect.left + highlightAreaSVGLine.rect.width - lineOffset) * scale));\n var y = (highlightAreaSVGLine.rect.top + highlightAreaSVGLine.rect.height - underlineThickness / 2) * scale;\n highlightAreaSVGLine.setAttribute("y1", "".concat(y));\n highlightAreaSVGLine.setAttribute("y2", "".concat(y));\n highlightAreaSVGLine.setAttribute("height", "".concat(highlightAreaSVGLine.rect.height * scale));\n highlightAreaSVGLine.setAttribute("width", "".concat(highlightAreaSVGLine.rect.width * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGLine);\n }\n\n if (drawStrikeThrough) {\n var _highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n _highlightAreaSVGLine.setAttribute("style", "stroke-linecap: butt; stroke-width: ".concat(strikeThroughLineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n\n _highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n _highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n _highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n _highlightAreaSVGLine.setAttribute("x1", "".concat(_highlightAreaSVGLine.rect.left * scale));\n\n _highlightAreaSVGLine.setAttribute("x2", "".concat((_highlightAreaSVGLine.rect.left + _highlightAreaSVGLine.rect.width) * scale));\n\n var _lineOffset = _highlightAreaSVGLine.rect.height / 2;\n\n var _y = (_highlightAreaSVGLine.rect.top + _lineOffset) * scale;\n\n _highlightAreaSVGLine.setAttribute("y1", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("y2", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("height", "".concat(_highlightAreaSVGLine.rect.height * scale));\n\n _highlightAreaSVGLine.setAttribute("width", "".concat(_highlightAreaSVGLine.rect.width * scale));\n\n highlightAreaSVGDocFrag.appendChild(_highlightAreaSVGLine);\n }\n } else {\n var highlightArea = document.createElement("div");\n highlightArea.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n if (DEBUG_VISUALS) {\n var rgb = Math.round(0xffffff * Math.random());\n var r = rgb >> 16;\n var g = rgb >> 8 & 255;\n var b = rgb & 255;\n extra = "outline-color: rgb(".concat(r, ", ").concat(g, ", ").concat(b, "); outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n } else {\n if (drawUnderline) {\n extra += "border-bottom: ".concat(underlineThickness * scale, "px solid rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important");\n }\n }\n\n highlightArea.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n highlightArea.style.setProperty("pointer-events", "none");\n highlightArea.style.position = paginated ? "fixed" : "absolute";\n highlightArea.scale = scale;\n /*\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightArea.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightArea.style.width = "".concat(highlightArea.rect.width * scale, "px");\n highlightArea.style.height = "".concat(highlightArea.rect.height * scale, "px");\n highlightArea.style.left = "".concat(highlightArea.rect.left * scale, "px");\n highlightArea.style.top = "".concat(highlightArea.rect.top * scale, "px");\n highlightParent.append(highlightArea);\n\n if (!DEBUG_VISUALS && drawStrikeThrough) {\n //if (drawStrikeThrough) {\n var highlightAreaLine = document.createElement("div");\n highlightAreaLine.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaLine.setAttribute("style", "background-color: rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important;"));\n highlightAreaLine.style.setProperty("pointer-events", "none");\n highlightAreaLine.style.position = paginated ? "fixed" : "absolute";\n highlightAreaLine.scale = scale;\n /*\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaLine.style.width = "".concat(highlightAreaLine.rect.width * scale, "px");\n highlightAreaLine.style.height = "".concat(strikeThroughLineThickness * scale, "px");\n highlightAreaLine.style.left = "".concat(highlightAreaLine.rect.left * scale, "px");\n highlightAreaLine.style.top = "".concat((highlightAreaLine.rect.top + highlightAreaLine.rect.height / 2 - strikeThroughLineThickness / 2) * scale, "px");\n highlightParent.append(highlightAreaLine);\n }\n }\n\n if (annotationFlag) {\n break;\n }\n }\n } catch (err) {\n _iterator17.e(err);\n } finally {\n _iterator17.f();\n }\n\n if (useSVG && highlightAreaSVGDocFrag) {\n var highlightAreaSVG = document.createElementNS(SVG_XML_NAMESPACE, "svg");\n highlightAreaSVG.setAttribute("pointer-events", "none");\n highlightAreaSVG.style.position = paginated ? "fixed" : "absolute";\n highlightAreaSVG.style.overflow = "visible";\n highlightAreaSVG.style.left = "0";\n highlightAreaSVG.style.top = "0";\n highlightAreaSVG.append(highlightAreaSVGDocFrag);\n highlightParent.append(highlightAreaSVG);\n }\n\n var highlightBounding = document.createElement("div");\n\n if (annotationFlag) {\n highlightBounding.setAttribute("class", CLASS_ANNOTATION_BOUNDING_AREA);\n highlightBounding.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n } else {\n highlightBounding.setAttribute("class", CLASS_HIGHLIGHT_BOUNDING_AREA);\n }\n\n highlightBounding.style.setProperty("pointer-events", "none");\n highlightBounding.style.position = paginated ? "fixed" : "absolute";\n highlightBounding.scale = scale;\n\n if (DEBUG_VISUALS) {\n highlightBounding.setAttribute("style", "outline-color: magenta; outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n }\n\n if (annotationFlag) {\n highlightBounding.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n var rangeBoundingClientRect = range.getBoundingClientRect();\n highlightBounding.rect = {\n height: rangeBoundingClientRect.height,\n left: rangeBoundingClientRect.left - xOffset,\n top: rangeBoundingClientRect.top - yOffset,\n width: rangeBoundingClientRect.width\n };\n }\n\n highlightBounding.style.width = "".concat(highlightBounding.rect.width * scale, "px");\n highlightBounding.style.height = "".concat(highlightBounding.rect.height * scale, "px");\n highlightBounding.style.left = "".concat(highlightBounding.rect.left * scale, "px");\n highlightBounding.style.top = "".concat(highlightBounding.rect.top * scale, "px");\n highlightParent.append(highlightBounding);\n highlightsContainer.append(highlightParent);\n return highlightParent;\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n console.log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n console.log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n console.log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRange(range, getCssSelector, computeElementCFI) {\n var startIsElement = range.startContainer.nodeType === Node.ELEMENT_NODE;\n var startContainerElement = startIsElement ? range.startContainer : range.startContainer.parentNode && range.startContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.startContainer.parentNode : undefined;\n\n if (!startContainerElement) {\n return undefined;\n }\n\n var startContainerChildTextNodeIndex = startIsElement ? -1 : Array.from(startContainerElement.childNodes).indexOf(range.startContainer);\n\n if (startContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var startContainerElementCssSelector = getCssSelector(startContainerElement);\n var endIsElement = range.endContainer.nodeType === Node.ELEMENT_NODE;\n var endContainerElement = endIsElement ? range.endContainer : range.endContainer.parentNode && range.endContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.endContainer.parentNode : undefined;\n\n if (!endContainerElement) {\n return undefined;\n }\n\n var endContainerChildTextNodeIndex = endIsElement ? -1 : Array.from(endContainerElement.childNodes).indexOf(range.endContainer);\n\n if (endContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var endContainerElementCssSelector = getCssSelector(endContainerElement);\n var commonElementAncestor = getCommonAncestorElement(range.startContainer, range.endContainer);\n\n if (!commonElementAncestor) {\n console.log("^^^ NO RANGE COMMON ANCESTOR?!");\n return undefined;\n }\n\n if (range.commonAncestorContainer) {\n var rangeCommonAncestorElement = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? range.commonAncestorContainer : range.commonAncestorContainer.parentNode;\n\n if (rangeCommonAncestorElement && rangeCommonAncestorElement.nodeType === Node.ELEMENT_NODE) {\n if (commonElementAncestor !== rangeCommonAncestorElement) {\n console.log(">>>>>> COMMON ANCESTOR CONTAINER DIFF??!");\n console.log(getCssSelector(commonElementAncestor));\n console.log(getCssSelector(rangeCommonAncestorElement));\n }\n }\n }\n\n var rootElementCfi = computeElementCFI(commonElementAncestor);\n var startElementCfi = computeElementCFI(startContainerElement);\n var endElementCfi = computeElementCFI(endContainerElement);\n var cfi;\n\n if (rootElementCfi && startElementCfi && endElementCfi) {\n var startElementOrTextCfi = startElementCfi;\n\n if (!startIsElement) {\n var startContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(startContainerElement, range.startContainer);\n startElementOrTextCfi = startElementCfi + "/" + startContainerChildTextNodeIndexForCfi + ":" + range.startOffset;\n } else {\n if (range.startOffset >= 0 && range.startOffset < startContainerElement.childNodes.length) {\n var childNode = startContainerElement.childNodes[range.startOffset];\n\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (range.startOffset + 1) * 2;\n } else {\n var cfiTextNodeIndex = getChildTextNodeCfiIndex(startContainerElement, childNode);\n startElementOrTextCfi = startElementCfi + "/" + cfiTextNodeIndex;\n }\n } else {\n var cfiIndexOfLastElement = startContainerElement.childElementCount * 2;\n var lastChildNode = startContainerElement.childNodes[startContainerElement.childNodes.length - 1];\n\n if (lastChildNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 1);\n } else {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 2);\n }\n }\n }\n\n var endElementOrTextCfi = endElementCfi;\n\n if (!endIsElement) {\n var endContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(endContainerElement, range.endContainer);\n endElementOrTextCfi = endElementCfi + "/" + endContainerChildTextNodeIndexForCfi + ":" + range.endOffset;\n } else {\n if (range.endOffset >= 0 && range.endOffset < endContainerElement.childNodes.length) {\n var _childNode = endContainerElement.childNodes[range.endOffset];\n\n if (_childNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (range.endOffset + 1) * 2;\n } else {\n var _cfiTextNodeIndex = getChildTextNodeCfiIndex(endContainerElement, _childNode);\n\n endElementOrTextCfi = endElementCfi + "/" + _cfiTextNodeIndex;\n }\n } else {\n var _cfiIndexOfLastElement = endContainerElement.childElementCount * 2;\n\n var _lastChildNode = endContainerElement.childNodes[endContainerElement.childNodes.length - 1];\n\n if (_lastChildNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 1);\n } else {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 2);\n }\n }\n }\n\n cfi = rootElementCfi + "," + startElementOrTextCfi.replace(rootElementCfi, "") + "," + endElementOrTextCfi.replace(rootElementCfi, "");\n }\n\n return {\n cfi: cfi,\n endContainerChildTextNodeIndex: endContainerChildTextNodeIndex,\n endContainerElementCssSelector: endContainerElementCssSelector,\n endOffset: range.endOffset,\n startContainerChildTextNodeIndex: startContainerChildTextNodeIndex,\n startContainerElementCssSelector: startContainerElementCssSelector,\n startOffset: range.startOffset\n };\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n console.log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n console.log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\n\nfunction frameForHighlightAnnotationMarkWithID(win, id) {\n var clientRects = frameForHighlightWithID(id);\n if (!clientRects) return;\n var topClientRect = clientRects[0];\n var maxHeight = topClientRect.height;\n\n var _iterator18 = highlight_createForOfIteratorHelper(clientRects),\n _step18;\n\n try {\n for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {\n var clientRect = _step18.value;\n if (clientRect.top < topClientRect.top) topClientRect = clientRect;\n if (clientRect.height > maxHeight) maxHeight = clientRect.height;\n }\n } catch (err) {\n _iterator18.e(err);\n } finally {\n _iterator18.f();\n }\n\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var newTop = topClientRect.top;\n\n if (_highlightsContainer) {\n do {\n var boundingAreas = document.getElementsByClassName(CLASS_ANNOTATION_BOUNDING_AREA);\n var found = false; //for (let i = 0, length = boundingAreas.snapshotLength; i < length; ++i) {\n\n for (var i = 0, len = boundingAreas.length | 0; i < len; i = i + 1 | 0) {\n var boundingArea = boundingAreas[i];\n\n if (Math.abs(boundingArea.rect.top - (newTop - yOffset)) < 3) {\n newTop += boundingArea.rect.height;\n found = true;\n break;\n }\n }\n } while (found);\n }\n\n topClientRect.top = newTop;\n topClientRect.height = maxHeight;\n return topClientRect;\n}\n\nfunction highlightWithID(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n return highlight;\n}\n\nfunction frameForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n return clientRects;\n}\n\nfunction rangeInfo2Location(rangeInfo) {\n return {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n partialCfi: rangeInfo.cfi,\n domRange: {\n start: {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n textNodeIndex: rangeInfo.startContainerChildTextNodeIndex,\n offset: rangeInfo.startOffset\n },\n end: {\n cssSelector: rangeInfo.endContainerElementCssSelector,\n textNodeIndex: rangeInfo.endContainerChildTextNodeIndex,\n offset: rangeInfo.endOffset\n }\n }\n };\n}\n\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n cfi: location.partialCfi,\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction rectangleForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRects[0].left,\n width: clientRects[0].width,\n top: clientRects[0].top,\n height: clientRects[0].height\n };\n return size;\n}\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n var clientRect = range.getBoundingClientRect();\n var handleBounds = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRect.left,\n width: clientRect.width,\n top: clientRect.top,\n height: clientRect.height\n };\n return handleBounds;\n } catch (e) {\n return null;\n }\n}\nfunction setScrollMode(flag) {\n if (!flag) {\n document.documentElement.classList.add(CLASS_PAGINATED);\n } else {\n document.documentElement.classList.remove(CLASS_PAGINATED);\n }\n}\n/*\n if (document.addEventListener) { // IE >= 9; other browsers\n document.addEventListener(\'contextmenu\', function(e) {\n //alert("You\'ve tried to open context menu"); //here you draw your own menu\n //e.preventDefault();\n //let getCssSelector = fullQualifiedSelector;\n \n\t\t\tlet str = window.getSelection();\n\t\t\tlet selectionInfo = getCurrentSelectionInfo();\n\t\t\tlet pos = createHighlight(selectionInfo,{red:10,green:50,blue:230},true);\n\t\t\tlet ret2 = createAnnotation(pos.id);\n\t\t\t\n }, false);\n } else { // IE < 9\n document.attachEvent(\'oncontextmenu\', function() {\n alert("You\'ve tried to open context menu");\n window.event.returnValue = false;\n });\n }\n*/\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = selection_getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction selection_getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : selection_createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction selection_createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction selection_convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return selection_createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction selection_location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n}; // Legacy highlights API.\n\nwindow.createAnnotation = createAnnotation;\nwindow.createHighlight = createHighlight;\nwindow.destroyHighlight = destroyHighlight;\nwindow.getCurrentSelectionInfo = getCurrentSelectionInfo;\nwindow.getSelectionRect = getSelectionRect;\nwindow.rectangleForHighlightWithID = rectangleForHighlightWithID;\nwindow.setScrollMode = setScrollMode;\n;// CONCATENATED MODULE: ./src/index-fixed.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for fixed layouts resources.\n\nwindow.readium.isFixedLayout = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFlBQVksRUFBRUEsWUFKQztBQUtmRixFQUFBQSxVQUFVLEVBQUVBLFVBTEc7QUFNZmdCLEVBQUFBLFdBQVcsRUFBRUEsV0FORTtBQU9mTCxFQUFBQSxhQUFhLEVBQUVBLGFBUEE7QUFRZkUsRUFBQUEsV0FBVyxFQUFFQSxXQVJFO0FBU2Z1QixFQUFBQSxnQkFBZ0IsRUFBRUEsZ0JBVEg7QUFVZnJELEVBQUFBLFdBQVcsRUFBRUEsV0FWRTtBQVdmeUQsRUFBQUEsY0FBYyxFQUFFQSxjQVhEO0FBYWY7QUFDQTJnQixFQUFBQSxtQkFBbUIsRUFBRUEsbUJBZE47QUFnQmY7QUFDQU8sRUFBQUEsMkJBQTJCLEVBQUV4YyxpQkFqQmQ7QUFrQmZRLEVBQUFBLGNBQWMsRUFBRUEsY0FsQkQ7QUFvQmY7QUFDQXVFLEVBQUFBLHVCQUF1QixFQUFFQSx1QkFBdUJBO0FBckJqQyxDQUFqQixFQXdCQTs7QUFDQXZQLE1BQU0sQ0FBQzZoQixnQkFBUCxHQUEwQkEsZ0JBQTFCO0FBQ0E3aEIsTUFBTSxDQUFDMmhCLGVBQVAsR0FBeUJBLGVBQXpCO0FBQ0EzaEIsTUFBTSxDQUFDMGEsZ0JBQVAsR0FBMEJBLGdCQUExQjtBQUNBMWEsTUFBTSxDQUFDZ2MsdUJBQVAsR0FBaUNBLHVCQUFqQztBQUNBaGMsTUFBTSxDQUFDK2xCLGdCQUFQLEdBQTBCQSxnQkFBMUI7QUFDQS9sQixNQUFNLENBQUM4bEIsMkJBQVAsR0FBcUNBLDJCQUFyQztBQUNBOWxCLE1BQU0sQ0FBQ2ttQixhQUFQLEdBQXVCQSxhQUF2QixDOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBbG1CLE1BQU0sQ0FBQzhQLE9BQVAsQ0FBZUMsYUFBZixHQUErQixJQUEvQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL21hdGNoLXF1b3RlLmpzP2RkNmEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZS5qcz9mZGVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzLmpzPzQwMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy91dGlscy5qcz8wMjVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvcmVjdC5qcz80ZDVhIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZGVjb3JhdG9yLmpzPzFiMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kb20uanM/Y2JmMCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2dlc3R1cmVzLmpzPzE0YzIiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9rZXlib2FyZC5qcz8xOGUzIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaGlnaGxpZ2h0LmpzPzhkYTgiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9zZWxlY3Rpb24uanM/NTlhYyIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LmpzP2I2MzUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9pbmRleC1maXhlZC5qcz9kOTlmIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhcHByb3hTZWFyY2ggZnJvbSAnYXBwcm94LXN0cmluZy1tYXRjaCc7XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnYXBwcm94LXN0cmluZy1tYXRjaCcpLk1hdGNofSBTdHJpbmdNYXRjaFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgTWF0Y2hcbiAqIEBwcm9wIHtudW1iZXJ9IHN0YXJ0IC0gU3RhcnQgb2Zmc2V0IG9mIG1hdGNoIGluIHRleHRcbiAqIEBwcm9wIHtudW1iZXJ9IGVuZCAtIEVuZCBvZmZzZXQgb2YgbWF0Y2ggaW4gdGV4dFxuICogQHByb3Age251bWJlcn0gc2NvcmUgLVxuICogICBTY29yZSBmb3IgdGhlIG1hdGNoIGJldHdlZW4gMCBhbmQgMS4wLCB3aGVyZSAxLjAgaW5kaWNhdGVzIGEgcGVyZmVjdCBtYXRjaFxuICogICBmb3IgdGhlIHF1b3RlIGFuZCBjb250ZXh0LlxuICovXG5cbi8qKlxuICogRmluZCB0aGUgYmVzdCBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgc3RyYCBpbiBgdGV4dGAgYWxsb3dpbmcgdXAgdG8gYG1heEVycm9yc2AgZXJyb3JzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4RXJyb3JzXG4gKiBAcmV0dXJuIHtTdHJpbmdNYXRjaFtdfVxuICovXG5mdW5jdGlvbiBzZWFyY2godGV4dCwgc3RyLCBtYXhFcnJvcnMpIHtcbiAgLy8gRG8gYSBmYXN0IHNlYXJjaCBmb3IgZXhhY3QgbWF0Y2hlcy4gVGhlIGBhcHByb3gtc3RyaW5nLW1hdGNoYCBsaWJyYXJ5XG4gIC8vIGRvZXNuJ3QgY3VycmVudGx5IGluY29ycG9yYXRlIHRoaXMgb3B0aW1pemF0aW9uIGl0c2VsZi5cbiAgbGV0IG1hdGNoUG9zID0gMDtcbiAgbGV0IGV4YWN0TWF0Y2hlcyA9IFtdO1xuICB3aGlsZSAobWF0Y2hQb3MgIT09IC0xKSB7XG4gICAgbWF0Y2hQb3MgPSB0ZXh0LmluZGV4T2Yoc3RyLCBtYXRjaFBvcyk7XG4gICAgaWYgKG1hdGNoUG9zICE9PSAtMSkge1xuICAgICAgZXhhY3RNYXRjaGVzLnB1c2goe1xuICAgICAgICBzdGFydDogbWF0Y2hQb3MsXG4gICAgICAgIGVuZDogbWF0Y2hQb3MgKyBzdHIubGVuZ3RoLFxuICAgICAgICBlcnJvcnM6IDAsXG4gICAgICB9KTtcbiAgICAgIG1hdGNoUG9zICs9IDE7XG4gICAgfVxuICB9XG4gIGlmIChleGFjdE1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBleGFjdE1hdGNoZXM7XG4gIH1cblxuICAvLyBJZiB0aGVyZSBhcmUgbm8gZXhhY3QgbWF0Y2hlcywgZG8gYSBtb3JlIGV4cGVuc2l2ZSBzZWFyY2ggZm9yIG1hdGNoZXNcbiAgLy8gd2l0aCBlcnJvcnMuXG4gIHJldHVybiBhcHByb3hTZWFyY2godGV4dCwgc3RyLCBtYXhFcnJvcnMpO1xufVxuXG4vKipcbiAqIENvbXB1dGUgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEuMCBmb3IgdGhlIHNpbWlsYXJpdHkgYmV0d2VlbiBgdGV4dGAgYW5kIGBzdHJgLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKi9cbmZ1bmN0aW9uIHRleHRNYXRjaFNjb3JlKHRleHQsIHN0cikge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAtIGBzY29yZU1hdGNoYCB3aWxsIG5ldmVyIHBhc3MgYW4gZW1wdHkgc3RyaW5nICovXG4gIGlmIChzdHIubGVuZ3RoID09PSAwIHx8IHRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIDAuMDtcbiAgfVxuICBjb25zdCBtYXRjaGVzID0gc2VhcmNoKHRleHQsIHN0ciwgc3RyLmxlbmd0aCk7XG5cbiAgLy8gcHJldHRpZXItaWdub3JlXG4gIHJldHVybiAxIC0gKG1hdGNoZXNbMF0uZXJyb3JzIC8gc3RyLmxlbmd0aCk7XG59XG5cbi8qKlxuICogRmluZCB0aGUgYmVzdCBhcHByb3hpbWF0ZSBtYXRjaCBmb3IgYHF1b3RlYCBpbiBgdGV4dGAuXG4gKlxuICogUmV0dXJucyBgbnVsbGAgaWYgbm8gbWF0Y2ggZXhjZWVkaW5nIHRoZSBtaW5pbXVtIHF1YWxpdHkgdGhyZXNob2xkIHdhcyBmb3VuZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIERvY3VtZW50IHRleHQgdG8gc2VhcmNoXG4gKiBAcGFyYW0ge3N0cmluZ30gcXVvdGUgLSBTdHJpbmcgdG8gZmluZCB3aXRoaW4gYHRleHRgXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCAtXG4gKiAgIENvbnRleHQgaW4gd2hpY2ggdGhlIHF1b3RlIG9yaWdpbmFsbHkgYXBwZWFyZWQuIFRoaXMgaXMgdXNlZCB0byBjaG9vc2UgdGhlXG4gKiAgIGJlc3QgbWF0Y2guXG4gKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5wcmVmaXhdIC0gRXhwZWN0ZWQgdGV4dCBiZWZvcmUgdGhlIHF1b3RlXG4gKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5zdWZmaXhdIC0gRXhwZWN0ZWQgdGV4dCBhZnRlciB0aGUgcXVvdGVcbiAqICAgQHBhcmFtIHtudW1iZXJ9IFtjb250ZXh0LmhpbnRdIC0gRXhwZWN0ZWQgb2Zmc2V0IG9mIG1hdGNoIHdpdGhpbiB0ZXh0XG4gKiBAcmV0dXJuIHtNYXRjaHxudWxsfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hRdW90ZSh0ZXh0LCBxdW90ZSwgY29udGV4dCA9IHt9KSB7XG4gIGlmIChxdW90ZS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIENob29zZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIHRvIGFsbG93IGZvciB0aGUgaW5pdGlhbCBzZWFyY2guXG4gIC8vIFRoaXMgY2hvaWNlIGludm9sdmVzIGEgdHJhZGVvZmYgYmV0d2VlbjpcbiAgLy9cbiAgLy8gIC0gUmVjYWxsIChwcm9wb3J0aW9uIG9mIFwiZ29vZFwiIG1hdGNoZXMgZm91bmQpXG4gIC8vICAtIFByZWNpc2lvbiAocHJvcG9ydGlvbiBvZiBtYXRjaGVzIGZvdW5kIHdoaWNoIGFyZSBcImdvb2RcIilcbiAgLy8gIC0gQ29zdCBvZiB0aGUgaW5pdGlhbCBzZWFyY2ggYW5kIG9mIHByb2Nlc3NpbmcgdGhlIGNhbmRpZGF0ZSBtYXRjaGVzIFsxXVxuICAvL1xuICAvLyBbMV0gU3BlY2lmaWNhbGx5LCB0aGUgZXhwZWN0ZWQtdGltZSBjb21wbGV4aXR5IG9mIHRoZSBpbml0aWFsIHNlYXJjaCBpc1xuICAvLyAgICAgYE8oKG1heEVycm9ycyAvIDMyKSAqIHRleHQubGVuZ3RoKWAuIFNlZSBgYXBwcm94LXN0cmluZy1tYXRjaGAgZG9jcy5cbiAgY29uc3QgbWF4RXJyb3JzID0gTWF0aC5taW4oMjU2LCBxdW90ZS5sZW5ndGggLyAyKTtcblxuICAvLyBGaW5kIGNsb3Nlc3QgbWF0Y2hlcyBmb3IgYHF1b3RlYCBpbiBgdGV4dGAgYmFzZWQgb24gZWRpdCBkaXN0YW5jZS5cbiAgY29uc3QgbWF0Y2hlcyA9IHNlYXJjaCh0ZXh0LCBxdW90ZSwgbWF4RXJyb3JzKTtcblxuICBpZiAobWF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGEgc2NvcmUgYmV0d2VlbiAwIGFuZCAxLjAgZm9yIGEgbWF0Y2ggY2FuZGlkYXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ01hdGNofSBtYXRjaFxuICAgKi9cbiAgY29uc3Qgc2NvcmVNYXRjaCA9IG1hdGNoID0+IHtcbiAgICBjb25zdCBxdW90ZVdlaWdodCA9IDUwOyAvLyBTaW1pbGFyaXR5IG9mIG1hdGNoZWQgdGV4dCB0byBxdW90ZS5cbiAgICBjb25zdCBwcmVmaXhXZWlnaHQgPSAyMDsgLy8gU2ltaWxhcml0eSBvZiB0ZXh0IGJlZm9yZSBtYXRjaGVkIHRleHQgdG8gYGNvbnRleHQucHJlZml4YC5cbiAgICBjb25zdCBzdWZmaXhXZWlnaHQgPSAyMDsgLy8gU2ltaWxhcml0eSBvZiB0ZXh0IGFmdGVyIG1hdGNoZWQgdGV4dCB0byBgY29udGV4dC5zdWZmaXhgLlxuICAgIGNvbnN0IHBvc1dlaWdodCA9IDI7IC8vIFByb3hpbWl0eSB0byBleHBlY3RlZCBsb2NhdGlvbi4gVXNlZCBhcyBhIHRpZS1icmVha2VyLlxuXG4gICAgY29uc3QgcXVvdGVTY29yZSA9IDEgLSBtYXRjaC5lcnJvcnMgLyBxdW90ZS5sZW5ndGg7XG5cbiAgICBjb25zdCBwcmVmaXhTY29yZSA9IGNvbnRleHQucHJlZml4XG4gICAgICA/IHRleHRNYXRjaFNjb3JlKFxuICAgICAgICAgIHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgbWF0Y2guc3RhcnQgLSBjb250ZXh0LnByZWZpeC5sZW5ndGgpLCBtYXRjaC5zdGFydCksXG4gICAgICAgICAgY29udGV4dC5wcmVmaXhcbiAgICAgICAgKVxuICAgICAgOiAxLjA7XG4gICAgY29uc3Qgc3VmZml4U2NvcmUgPSBjb250ZXh0LnN1ZmZpeFxuICAgICAgPyB0ZXh0TWF0Y2hTY29yZShcbiAgICAgICAgICB0ZXh0LnNsaWNlKG1hdGNoLmVuZCwgbWF0Y2guZW5kICsgY29udGV4dC5zdWZmaXgubGVuZ3RoKSxcbiAgICAgICAgICBjb250ZXh0LnN1ZmZpeFxuICAgICAgICApXG4gICAgICA6IDEuMDtcblxuICAgIGxldCBwb3NTY29yZSA9IDEuMDtcbiAgICBpZiAodHlwZW9mIGNvbnRleHQuaGludCA9PT0gJ251bWJlcicpIHtcbiAgICAgIGNvbnN0IG9mZnNldCA9IE1hdGguYWJzKG1hdGNoLnN0YXJ0IC0gY29udGV4dC5oaW50KTtcbiAgICAgIHBvc1Njb3JlID0gMS4wIC0gb2Zmc2V0IC8gdGV4dC5sZW5ndGg7XG4gICAgfVxuXG4gICAgY29uc3QgcmF3U2NvcmUgPVxuICAgICAgcXVvdGVXZWlnaHQgKiBxdW90ZVNjb3JlICtcbiAgICAgIHByZWZpeFdlaWdodCAqIHByZWZpeFNjb3JlICtcbiAgICAgIHN1ZmZpeFdlaWdodCAqIHN1ZmZpeFNjb3JlICtcbiAgICAgIHBvc1dlaWdodCAqIHBvc1Njb3JlO1xuICAgIGNvbnN0IG1heFNjb3JlID0gcXVvdGVXZWlnaHQgKyBwcmVmaXhXZWlnaHQgKyBzdWZmaXhXZWlnaHQgKyBwb3NXZWlnaHQ7XG4gICAgY29uc3Qgbm9ybWFsaXplZFNjb3JlID0gcmF3U2NvcmUgLyBtYXhTY29yZTtcblxuICAgIHJldHVybiBub3JtYWxpemVkU2NvcmU7XG4gIH07XG5cbiAgLy8gUmFuayBtYXRjaGVzIGJhc2VkIG9uIHNpbWlsYXJpdHkgb2YgYWN0dWFsIGFuZCBleHBlY3RlZCBzdXJyb3VuZGluZyB0ZXh0XG4gIC8vIGFuZCBhY3R1YWwvZXhwZWN0ZWQgb2Zmc2V0IGluIHRoZSBkb2N1bWVudCB0ZXh0LlxuICBjb25zdCBzY29yZWRNYXRjaGVzID0gbWF0Y2hlcy5tYXAobSA9PiAoe1xuICAgIHN0YXJ0OiBtLnN0YXJ0LFxuICAgIGVuZDogbS5lbmQsXG4gICAgc2NvcmU6IHNjb3JlTWF0Y2gobSksXG4gIH0pKTtcblxuICAvLyBDaG9vc2UgbWF0Y2ggd2l0aCBoaWdoZXN0IHNjb3JlLlxuICBzY29yZWRNYXRjaGVzLnNvcnQoKGEsIGIpID0+IGIuc2NvcmUgLSBhLnNjb3JlKTtcbiAgcmV0dXJuIHNjb3JlZE1hdGNoZXNbMF07XG59XG4iLCIvKipcbiAqIFJldHVybiB0aGUgY29tYmluZWQgbGVuZ3RoIG9mIHRleHQgbm9kZXMgY29udGFpbmVkIGluIGBub2RlYC5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqL1xuZnVuY3Rpb24gbm9kZVRleHRMZW5ndGgobm9kZSkge1xuICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOlxuICAgIGNhc2UgTm9kZS5URVhUX05PREU6XG4gICAgICAvLyBuYi4gYHRleHRDb250ZW50YCBleGNsdWRlcyB0ZXh0IGluIGNvbW1lbnRzIGFuZCBwcm9jZXNzaW5nIGluc3RydWN0aW9uc1xuICAgICAgLy8gd2hlbiBjYWxsZWQgb24gYSBwYXJlbnQgZWxlbWVudCwgc28gd2UgZG9uJ3QgbmVlZCB0byBzdWJ0cmFjdCB0aGF0IGhlcmUuXG5cbiAgICAgIHJldHVybiAvKiogQHR5cGUge3N0cmluZ30gKi8gKG5vZGUudGV4dENvbnRlbnQpLmxlbmd0aDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgdGV4dCBvZiBhbGwgcHJldmlvdXMgc2libGluZ3Mgb2YgYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICovXG5mdW5jdGlvbiBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChub2RlKSB7XG4gIGxldCBzaWJsaW5nID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gIGxldCBsZW5ndGggPSAwO1xuICB3aGlsZSAoc2libGluZykge1xuICAgIGxlbmd0aCArPSBub2RlVGV4dExlbmd0aChzaWJsaW5nKTtcbiAgICBzaWJsaW5nID0gc2libGluZy5wcmV2aW91c1NpYmxpbmc7XG4gIH1cbiAgcmV0dXJuIGxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIG9uZSBvciBtb3JlIGNoYXJhY3RlciBvZmZzZXRzIHdpdGhpbiBhbiBlbGVtZW50IHRvICh0ZXh0IG5vZGUsIHBvc2l0aW9uKVxuICogcGFpcnMuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge251bWJlcltdfSBvZmZzZXRzIC0gT2Zmc2V0cywgd2hpY2ggbXVzdCBiZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyXG4gKiBAcmV0dXJuIHt7IG5vZGU6IFRleHQsIG9mZnNldDogbnVtYmVyIH1bXX1cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZU9mZnNldHMoZWxlbWVudCwgLi4ub2Zmc2V0cykge1xuICBsZXQgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgY29uc3Qgbm9kZUl0ZXIgPSAvKiogQHR5cGUge0RvY3VtZW50fSAqLyAoXG4gICAgZWxlbWVudC5vd25lckRvY3VtZW50XG4gICkuY3JlYXRlTm9kZUl0ZXJhdG9yKGVsZW1lbnQsIE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gIGxldCBjdXJyZW50Tm9kZSA9IG5vZGVJdGVyLm5leHROb2RlKCk7XG4gIGxldCB0ZXh0Tm9kZTtcbiAgbGV0IGxlbmd0aCA9IDA7XG5cbiAgLy8gRmluZCB0aGUgdGV4dCBub2RlIGNvbnRhaW5pbmcgdGhlIGBuZXh0T2Zmc2V0YHRoIGNoYXJhY3RlciBmcm9tIHRoZSBzdGFydFxuICAvLyBvZiBgZWxlbWVudGAuXG4gIHdoaWxlIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgY3VycmVudE5vZGUpIHtcbiAgICB0ZXh0Tm9kZSA9IC8qKiBAdHlwZSB7VGV4dH0gKi8gKGN1cnJlbnROb2RlKTtcbiAgICBpZiAobGVuZ3RoICsgdGV4dE5vZGUuZGF0YS5sZW5ndGggPiBuZXh0T2Zmc2V0KSB7XG4gICAgICByZXN1bHRzLnB1c2goeyBub2RlOiB0ZXh0Tm9kZSwgb2Zmc2V0OiBuZXh0T2Zmc2V0IC0gbGVuZ3RoIH0pO1xuICAgICAgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudE5vZGUgPSBub2RlSXRlci5uZXh0Tm9kZSgpO1xuICAgICAgbGVuZ3RoICs9IHRleHROb2RlLmRhdGEubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJvdW5kYXJ5IGNhc2UuXG4gIHdoaWxlIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgdGV4dE5vZGUgJiYgbGVuZ3RoID09PSBuZXh0T2Zmc2V0KSB7XG4gICAgcmVzdWx0cy5wdXNoKHsgbm9kZTogdGV4dE5vZGUsIG9mZnNldDogdGV4dE5vZGUuZGF0YS5sZW5ndGggfSk7XG4gICAgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgfVxuXG4gIGlmIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT2Zmc2V0IGV4Y2VlZHMgdGV4dCBsZW5ndGgnKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5leHBvcnQgbGV0IFJFU09MVkVfRk9SV0FSRFMgPSAxO1xuZXhwb3J0IGxldCBSRVNPTFZFX0JBQ0tXQVJEUyA9IDI7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBvZmZzZXQgd2l0aGluIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYW4gZWxlbWVudC5cbiAqXG4gKiBUaGlzIHBvc2l0aW9uIGNhbiBiZSByZXNvbHZlZCB0byBhIHNwZWNpZmljIGRlc2NlbmRhbnQgbm9kZSBpbiB0aGUgY3VycmVudFxuICogRE9NIHN1YnRyZWUgb2YgdGhlIGVsZW1lbnQgdXNpbmcgdGhlIGByZXNvbHZlYCBtZXRob2QuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UG9zaXRpb24ge1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgdGhhdCByZWZlcnMgdG8gdGhlIHRleHQgcG9zaXRpb24gYG9mZnNldGAgd2l0aGluXG4gICAqIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYGVsZW1lbnRgLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKi9cbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb2Zmc2V0KSB7XG4gICAgaWYgKG9mZnNldCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT2Zmc2V0IGlzIGludmFsaWQnKTtcbiAgICB9XG5cbiAgICAvKiogRWxlbWVudCB0aGF0IGBvZmZzZXRgIGlzIHJlbGF0aXZlIHRvLiAqL1xuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgICAvKiogQ2hhcmFjdGVyIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgZWxlbWVudCdzIGB0ZXh0Q29udGVudGAuICovXG4gICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGlzIHBvc2l0aW9uIHdpdGggb2Zmc2V0IHJlbGF0aXZlIHRvIGEgZ2l2ZW4gYW5jZXN0b3JcbiAgICogZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSBwYXJlbnQgLSBBbmNlc3RvciBvZiBgdGhpcy5lbGVtZW50YFxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb259XG4gICAqL1xuICByZWxhdGl2ZVRvKHBhcmVudCkge1xuICAgIGlmICghcGFyZW50LmNvbnRhaW5zKHRoaXMuZWxlbWVudCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyZW50IGlzIG5vdCBhbiBhbmNlc3RvciBvZiBjdXJyZW50IGVsZW1lbnQnKTtcbiAgICB9XG5cbiAgICBsZXQgZWwgPSB0aGlzLmVsZW1lbnQ7XG4gICAgbGV0IG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgIHdoaWxlIChlbCAhPT0gcGFyZW50KSB7XG4gICAgICBvZmZzZXQgKz0gcHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgoZWwpO1xuICAgICAgZWwgPSAvKiogQHR5cGUge0VsZW1lbnR9ICovIChlbC5wYXJlbnRFbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbihlbCwgb2Zmc2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBwb3NpdGlvbiB0byBhIHNwZWNpZmljIHRleHQgbm9kZSBhbmQgb2Zmc2V0IHdpdGhpbiB0aGF0IG5vZGUuXG4gICAqXG4gICAqIFRocm93cyBpZiBgdGhpcy5vZmZzZXRgIGV4Y2VlZHMgdGhlIGxlbmd0aCBvZiB0aGUgZWxlbWVudCdzIHRleHQuIEluIHRoZVxuICAgKiBjYXNlIHdoZXJlIHRoZSBlbGVtZW50IGhhcyBubyB0ZXh0IGFuZCBgdGhpcy5vZmZzZXRgIGlzIDAsIHRoZSBgZGlyZWN0aW9uYFxuICAgKiBvcHRpb24gZGV0ZXJtaW5lcyB3aGF0IGhhcHBlbnMuXG4gICAqXG4gICAqIE9mZnNldHMgYXQgdGhlIGJvdW5kYXJ5IGJldHdlZW4gdHdvIG5vZGVzIGFyZSByZXNvbHZlZCB0byB0aGUgc3RhcnQgb2YgdGhlXG4gICAqIG5vZGUgdGhhdCBiZWdpbnMgYXQgdGhlIGJvdW5kYXJ5LlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgQHBhcmFtIHtSRVNPTFZFX0ZPUldBUkRTfFJFU09MVkVfQkFDS1dBUkRTfSBbb3B0aW9ucy5kaXJlY3Rpb25dIC1cbiAgICogICAgIFNwZWNpZmllcyBpbiB3aGljaCBkaXJlY3Rpb24gdG8gc2VhcmNoIGZvciB0aGUgbmVhcmVzdCB0ZXh0IG5vZGUgaWZcbiAgICogICAgIGB0aGlzLm9mZnNldGAgaXMgYDBgIGFuZCBgdGhpcy5lbGVtZW50YCBoYXMgbm8gdGV4dC4gSWYgbm90IHNwZWNpZmllZFxuICAgKiAgICAgYW4gZXJyb3IgaXMgdGhyb3duLlxuICAgKiBAcmV0dXJuIHt7IG5vZGU6IFRleHQsIG9mZnNldDogbnVtYmVyIH19XG4gICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9XG4gICAqL1xuICByZXNvbHZlKG9wdGlvbnMgPSB7fSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZU9mZnNldHModGhpcy5lbGVtZW50LCB0aGlzLm9mZnNldClbMF07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAodGhpcy5vZmZzZXQgPT09IDAgJiYgb3B0aW9ucy5kaXJlY3Rpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB0dyA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIoXG4gICAgICAgICAgdGhpcy5lbGVtZW50LmdldFJvb3ROb2RlKCksXG4gICAgICAgICAgTm9kZUZpbHRlci5TSE9XX1RFWFRcbiAgICAgICAgKTtcbiAgICAgICAgdHcuY3VycmVudE5vZGUgPSB0aGlzLmVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGZvcndhcmRzID0gb3B0aW9ucy5kaXJlY3Rpb24gPT09IFJFU09MVkVfRk9SV0FSRFM7XG4gICAgICAgIGNvbnN0IHRleHQgPSAvKiogQHR5cGUge1RleHR8bnVsbH0gKi8gKFxuICAgICAgICAgIGZvcndhcmRzID8gdHcubmV4dE5vZGUoKSA6IHR3LnByZXZpb3VzTm9kZSgpXG4gICAgICAgICk7XG4gICAgICAgIGlmICghdGV4dCkge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBub2RlOiB0ZXh0LCBvZmZzZXQ6IGZvcndhcmRzID8gMCA6IHRleHQuZGF0YS5sZW5ndGggfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgdGhhdCByZWZlcnMgdG8gdGhlIGBvZmZzZXRgdGggY2hhcmFjdGVyIHdpdGhpblxuICAgKiBgbm9kZWAuXG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tQ2hhck9mZnNldChub2RlLCBvZmZzZXQpIHtcbiAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6XG4gICAgICAgIHJldHVybiBUZXh0UG9zaXRpb24uZnJvbVBvaW50KG5vZGUsIG9mZnNldCk7XG4gICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOlxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbigvKiogQHR5cGUge0VsZW1lbnR9ICovIChub2RlKSwgb2Zmc2V0KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm9kZSBpcyBub3QgYW4gZWxlbWVudCBvciB0ZXh0IG5vZGUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgcmVwcmVzZW50aW5nIHRoZSByYW5nZSBzdGFydCBvciBlbmQgcG9pbnQgKG5vZGUsIG9mZnNldCkuXG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSAtIFRleHQgb3IgRWxlbWVudCBub2RlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgLSBPZmZzZXQgd2l0aGluIHRoZSBub2RlLlxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb259XG4gICAqL1xuICBzdGF0aWMgZnJvbVBvaW50KG5vZGUsIG9mZnNldCkge1xuICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERToge1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiAvKiogQHR5cGUge1RleHR9ICovIChub2RlKS5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGV4dCBub2RlIG9mZnNldCBpcyBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbm9kZS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IG5vZGUgaGFzIG5vIHBhcmVudCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHRoZSBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHBhcmVudCBlbGVtZW50LlxuICAgICAgICBjb25zdCB0ZXh0T2Zmc2V0ID0gcHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgobm9kZSkgKyBvZmZzZXQ7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb24obm9kZS5wYXJlbnRFbGVtZW50LCB0ZXh0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6IHtcbiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hpbGQgbm9kZSBvZmZzZXQgaXMgb3V0IG9mIHJhbmdlJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIHRleHQgbGVuZ3RoIGJlZm9yZSB0aGUgYG9mZnNldGB0aCBjaGlsZCBvZiBlbGVtZW50LlxuICAgICAgICBsZXQgdGV4dE9mZnNldCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2Zmc2V0OyBpKyspIHtcbiAgICAgICAgICB0ZXh0T2Zmc2V0ICs9IG5vZGVUZXh0TGVuZ3RoKG5vZGUuY2hpbGROb2Rlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbigvKiogQHR5cGUge0VsZW1lbnR9ICovIChub2RlKSwgdGV4dE9mZnNldCk7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvaW50IGlzIG5vdCBpbiBhbiBlbGVtZW50IG9yIHRleHQgbm9kZScpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSByZWdpb24gb2YgYSBkb2N1bWVudCBhcyBhIChzdGFydCwgZW5kKSBwYWlyIG9mIGBUZXh0UG9zaXRpb25gIHBvaW50cy5cbiAqXG4gKiBSZXByZXNlbnRpbmcgYSByYW5nZSBpbiB0aGlzIHdheSBhbGxvd3MgZm9yIGNoYW5nZXMgaW4gdGhlIERPTSBjb250ZW50IG9mIHRoZVxuICogcmFuZ2Ugd2hpY2ggZG9uJ3QgYWZmZWN0IGl0cyB0ZXh0IGNvbnRlbnQsIHdpdGhvdXQgYWZmZWN0aW5nIHRoZSB0ZXh0IGNvbnRlbnRcbiAqIG9mIHRoZSByYW5nZSBpdHNlbGYuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UmFuZ2Uge1xuICAvKipcbiAgICogQ29uc3RydWN0IGFuIGltbXV0YWJsZSBgVGV4dFJhbmdlYCBmcm9tIGEgYHN0YXJ0YCBhbmQgYGVuZGAgcG9pbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9ufSBzdGFydFxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvbn0gZW5kXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzdGFydCwgZW5kKSB7XG4gICAgdGhpcy5zdGFydCA9IHN0YXJ0O1xuICAgIHRoaXMuZW5kID0gZW5kO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGNvcHkgb2YgdGhpcyByYW5nZSB3aXRoIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIHJlbGF0aXZlIHRvIGFcbiAgICogZ2l2ZW4gYW5jZXN0b3IuIFNlZSBgVGV4dFBvc2l0aW9uLnJlbGF0aXZlVG9gLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgICovXG4gIHJlbGF0aXZlVG8oZWxlbWVudCkge1xuICAgIHJldHVybiBuZXcgVGV4dFJhbmdlKFxuICAgICAgdGhpcy5zdGFydC5yZWxhdGl2ZVRvKGVsZW1lbnQpLFxuICAgICAgdGhpcy5lbmQucmVsYXRpdmVUbyhlbGVtZW50KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGUgYFRleHRSYW5nZWAgdG8gYSBET00gcmFuZ2UuXG4gICAqXG4gICAqIFRoZSByZXN1bHRpbmcgRE9NIFJhbmdlIHdpbGwgYWx3YXlzIHN0YXJ0IGFuZCBlbmQgaW4gYSBgVGV4dGAgbm9kZS5cbiAgICogSGVuY2UgYFRleHRSYW5nZS5mcm9tUmFuZ2UocmFuZ2UpLnRvUmFuZ2UoKWAgY2FuIGJlIHVzZWQgdG8gXCJzaHJpbmtcIiBhXG4gICAqIHJhbmdlIHRvIHRoZSB0ZXh0IGl0IGNvbnRhaW5zLlxuICAgKlxuICAgKiBNYXkgdGhyb3cgaWYgdGhlIGBzdGFydGAgb3IgYGVuZGAgcG9zaXRpb25zIGNhbm5vdCBiZSByZXNvbHZlZCB0byBhIHJhbmdlLlxuICAgKlxuICAgKiBAcmV0dXJuIHtSYW5nZX1cbiAgICovXG4gIHRvUmFuZ2UoKSB7XG4gICAgbGV0IHN0YXJ0O1xuICAgIGxldCBlbmQ7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXJ0LmVsZW1lbnQgPT09IHRoaXMuZW5kLmVsZW1lbnQgJiZcbiAgICAgIHRoaXMuc3RhcnQub2Zmc2V0IDw9IHRoaXMuZW5kLm9mZnNldFxuICAgICkge1xuICAgICAgLy8gRmFzdCBwYXRoIGZvciBzdGFydCBhbmQgZW5kIHBvaW50cyBpbiBzYW1lIGVsZW1lbnQuXG4gICAgICBbc3RhcnQsIGVuZF0gPSByZXNvbHZlT2Zmc2V0cyhcbiAgICAgICAgdGhpcy5zdGFydC5lbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXJ0Lm9mZnNldCxcbiAgICAgICAgdGhpcy5lbmQub2Zmc2V0XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGFydCA9IHRoaXMuc3RhcnQucmVzb2x2ZSh7IGRpcmVjdGlvbjogUkVTT0xWRV9GT1JXQVJEUyB9KTtcbiAgICAgIGVuZCA9IHRoaXMuZW5kLnJlc29sdmUoeyBkaXJlY3Rpb246IFJFU09MVkVfQkFDS1dBUkRTIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnQubm9kZSwgc3RhcnQub2Zmc2V0KTtcbiAgICByYW5nZS5zZXRFbmQoZW5kLm5vZGUsIGVuZC5vZmZzZXQpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGV4aXN0aW5nIERPTSBgUmFuZ2VgIHRvIGEgYFRleHRSYW5nZWBcbiAgICpcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICogQHJldHVybiB7VGV4dFJhbmdlfVxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyYW5nZSkge1xuICAgIGNvbnN0IHN0YXJ0ID0gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXRcbiAgICApO1xuICAgIGNvbnN0IGVuZCA9IFRleHRQb3NpdGlvbi5mcm9tUG9pbnQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpO1xuICAgIHJldHVybiBuZXcgVGV4dFJhbmdlKHN0YXJ0LCBlbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGBUZXh0UmFuZ2VgIGZyb20gdGhlIGBzdGFydGB0aCB0byBgZW5kYHRoIGNoYXJhY3RlcnMgaW4gYHJvb3RgLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRcbiAgICovXG4gIHN0YXRpYyBmcm9tT2Zmc2V0cyhyb290LCBzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2UoXG4gICAgICBuZXcgVGV4dFBvc2l0aW9uKHJvb3QsIHN0YXJ0KSxcbiAgICAgIG5ldyBUZXh0UG9zaXRpb24ocm9vdCwgZW5kKVxuICAgICk7XG4gIH1cbn1cbiIsIi8qKlxuICogVGhpcyBtb2R1bGUgZXhwb3J0cyBhIHNldCBvZiBjbGFzc2VzIGZvciBjb252ZXJ0aW5nIGJldHdlZW4gRE9NIGBSYW5nZWBcbiAqIG9iamVjdHMgYW5kIGRpZmZlcmVudCB0eXBlcyBvZiBzZWxlY3RvcnMuIEl0IGlzIG1vc3RseSBhIHRoaW4gd3JhcHBlciBhcm91bmQgYVxuICogc2V0IG9mIGFuY2hvcmluZyBsaWJyYXJpZXMuIEl0IHNlcnZlcyB0d28gbWFpbiBwdXJwb3NlczpcbiAqXG4gKiAgMS4gUHJvdmlkaW5nIGEgY29uc2lzdGVudCBpbnRlcmZhY2UgYWNyb3NzIGRpZmZlcmVudCB0eXBlcyBvZiBhbmNob3JzLlxuICogIDIuIEluc3VsYXRpbmcgdGhlIHJlc3Qgb2YgdGhlIGNvZGUgZnJvbSBBUEkgY2hhbmdlcyBpbiB0aGUgdW5kZXJseWluZyBhbmNob3JpbmdcbiAqICAgICBsaWJyYXJpZXMuXG4gKi9cblxuaW1wb3J0IHsgbWF0Y2hRdW90ZSB9IGZyb20gJy4vbWF0Y2gtcXVvdGUnO1xuaW1wb3J0IHsgVGV4dFJhbmdlLCBUZXh0UG9zaXRpb24gfSBmcm9tICcuL3RleHQtcmFuZ2UnO1xuaW1wb3J0IHsgbm9kZUZyb21YUGF0aCwgeHBhdGhGcm9tTm9kZSB9IGZyb20gJy4veHBhdGgnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uLy4uL3R5cGVzL2FwaScpLlJhbmdlU2VsZWN0b3J9IFJhbmdlU2VsZWN0b3JcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uLy4uL3R5cGVzL2FwaScpLlRleHRQb3NpdGlvblNlbGVjdG9yfSBUZXh0UG9zaXRpb25TZWxlY3RvclxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuVGV4dFF1b3RlU2VsZWN0b3J9IFRleHRRdW90ZVNlbGVjdG9yXG4gKi9cblxuLyoqXG4gKiBDb252ZXJ0cyBiZXR3ZWVuIGBSYW5nZVNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFJhbmdlQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Tm9kZX0gcm9vdCAtIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtICBBIHJhbmdlIGRlc2NyaWJpbmcgdGhlIGFuY2hvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIHJhbmdlKSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLnJhbmdlID0gcmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtOb2RlfSByb290IC0gIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtICBBIHJhbmdlIGRlc2NyaWJpbmcgdGhlIGFuY2hvci5cbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlQW5jaG9yKHJvb3QsIHJhbmdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gYW5jaG9yIGZyb20gYSBzZXJpYWxpemVkIGBSYW5nZVNlbGVjdG9yYCBzZWxlY3Rvci5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290IC0gIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlU2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBzdGF0aWMgZnJvbVNlbGVjdG9yKHJvb3QsIHNlbGVjdG9yKSB7XG4gICAgY29uc3Qgc3RhcnRDb250YWluZXIgPSBub2RlRnJvbVhQYXRoKHNlbGVjdG9yLnN0YXJ0Q29udGFpbmVyLCByb290KTtcbiAgICBpZiAoIXN0YXJ0Q29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIHN0YXJ0Q29udGFpbmVyIFhQYXRoJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZW5kQ29udGFpbmVyID0gbm9kZUZyb21YUGF0aChzZWxlY3Rvci5lbmRDb250YWluZXIsIHJvb3QpO1xuICAgIGlmICghZW5kQ29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIGVuZENvbnRhaW5lciBYUGF0aCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0UG9zID0gVGV4dFBvc2l0aW9uLmZyb21DaGFyT2Zmc2V0KFxuICAgICAgc3RhcnRDb250YWluZXIsXG4gICAgICBzZWxlY3Rvci5zdGFydE9mZnNldFxuICAgICk7XG4gICAgY29uc3QgZW5kUG9zID0gVGV4dFBvc2l0aW9uLmZyb21DaGFyT2Zmc2V0KFxuICAgICAgZW5kQ29udGFpbmVyLFxuICAgICAgc2VsZWN0b3IuZW5kT2Zmc2V0XG4gICAgKTtcblxuICAgIGNvbnN0IHJhbmdlID0gbmV3IFRleHRSYW5nZShzdGFydFBvcywgZW5kUG9zKS50b1JhbmdlKCk7XG4gICAgcmV0dXJuIG5ldyBSYW5nZUFuY2hvcihyb290LCByYW5nZSk7XG4gIH1cblxuICB0b1JhbmdlKCkge1xuICAgIHJldHVybiB0aGlzLnJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1JhbmdlU2VsZWN0b3J9XG4gICAqL1xuICB0b1NlbGVjdG9yKCkge1xuICAgIC8vIFwiU2hyaW5rXCIgdGhlIHJhbmdlIHNvIHRoYXQgaXQgdGlnaHRseSB3cmFwcyBpdHMgdGV4dC4gVGhpcyBlbnN1cmVzIG1vcmVcbiAgICAvLyBwcmVkaWN0YWJsZSBvdXRwdXQgZm9yIGEgZ2l2ZW4gdGV4dCBzZWxlY3Rpb24uXG4gICAgY29uc3Qgbm9ybWFsaXplZFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZSh0aGlzLnJhbmdlKS50b1JhbmdlKCk7XG5cbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKG5vcm1hbGl6ZWRSYW5nZSk7XG4gICAgY29uc3Qgc3RhcnRDb250YWluZXIgPSB4cGF0aEZyb21Ob2RlKHRleHRSYW5nZS5zdGFydC5lbGVtZW50LCB0aGlzLnJvb3QpO1xuICAgIGNvbnN0IGVuZENvbnRhaW5lciA9IHhwYXRoRnJvbU5vZGUodGV4dFJhbmdlLmVuZC5lbGVtZW50LCB0aGlzLnJvb3QpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdSYW5nZVNlbGVjdG9yJyxcbiAgICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgICAgc3RhcnRPZmZzZXQ6IHRleHRSYW5nZS5zdGFydC5vZmZzZXQsXG4gICAgICBlbmRDb250YWluZXIsXG4gICAgICBlbmRPZmZzZXQ6IHRleHRSYW5nZS5lbmQub2Zmc2V0LFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBiZXR3ZWVuIGBUZXh0UG9zaXRpb25TZWxlY3RvcmAgc2VsZWN0b3JzIGFuZCBgUmFuZ2VgIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UG9zaXRpb25BbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydFxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCBzdGFydCwgZW5kKSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5lbmQgPSBlbmQ7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJvb3QsIHJhbmdlKSB7XG4gICAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhyb290KTtcbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbkFuY2hvcihcbiAgICAgIHJvb3QsXG4gICAgICB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0LFxuICAgICAgdGV4dFJhbmdlLmVuZC5vZmZzZXRcbiAgICApO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb25TZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbkFuY2hvcihyb290LCBzZWxlY3Rvci5zdGFydCwgc2VsZWN0b3IuZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb25TZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdUZXh0UG9zaXRpb25TZWxlY3RvcicsXG4gICAgICBzdGFydDogdGhpcy5zdGFydCxcbiAgICAgIGVuZDogdGhpcy5lbmQsXG4gICAgfTtcbiAgfVxuXG4gIHRvUmFuZ2UoKSB7XG4gICAgcmV0dXJuIFRleHRSYW5nZS5mcm9tT2Zmc2V0cyh0aGlzLnJvb3QsIHRoaXMuc3RhcnQsIHRoaXMuZW5kKS50b1JhbmdlKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAdHlwZWRlZiBRdW90ZU1hdGNoT3B0aW9uc1xuICogQHByb3Age251bWJlcn0gW2hpbnRdIC0gRXhwZWN0ZWQgcG9zaXRpb24gb2YgbWF0Y2ggaW4gdGV4dC4gU2VlIGBtYXRjaFF1b3RlYC5cbiAqL1xuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFRleHRRdW90ZVNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRRdW90ZUFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3QgLSBBIHJvb3QgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGFuY2hvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGV4YWN0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gICAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnByZWZpeF1cbiAgICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQuc3VmZml4XVxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgZXhhY3QsIGNvbnRleHQgPSB7fSkge1xuICAgIHRoaXMucm9vdCA9IHJvb3Q7XG4gICAgdGhpcy5leGFjdCA9IGV4YWN0O1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgYFRleHRRdW90ZUFuY2hvcmAgZnJvbSBhIHJhbmdlLlxuICAgKlxuICAgKiBXaWxsIHRocm93IGlmIGByYW5nZWAgZG9lcyBub3QgY29udGFpbiBhbnkgdGV4dCBub2Rlcy5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJvb3QsIHJhbmdlKSB7XG4gICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocm9vdC50ZXh0Q29udGVudCk7XG4gICAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhyb290KTtcblxuICAgIGNvbnN0IHN0YXJ0ID0gdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldDtcbiAgICBjb25zdCBlbmQgPSB0ZXh0UmFuZ2UuZW5kLm9mZnNldDtcblxuICAgIC8vIE51bWJlciBvZiBjaGFyYWN0ZXJzIGFyb3VuZCB0aGUgcXVvdGUgdG8gY2FwdHVyZSBhcyBjb250ZXh0LiBXZSBjdXJyZW50bHlcbiAgICAvLyBhbHdheXMgdXNlIGEgZml4ZWQgYW1vdW50LCBidXQgaXQgd291bGQgYmUgYmV0dGVyIGlmIHRoaXMgY29kZSB3YXMgYXdhcmVcbiAgICAvLyBvZiBsb2dpY2FsIGJvdW5kYXJpZXMgaW4gdGhlIGRvY3VtZW50IChwYXJhZ3JhcGgsIGFydGljbGUgZXRjLikgdG8gYXZvaWRcbiAgICAvLyBjYXB0dXJpbmcgdGV4dCB1bnJlbGF0ZWQgdG8gdGhlIHF1b3RlLlxuICAgIC8vXG4gICAgLy8gSW4gcmVndWxhciBwcm9zZSB0aGUgaWRlYWwgY29udGVudCB3b3VsZCBvZnRlbiBiZSB0aGUgc3Vycm91bmRpbmcgc2VudGVuY2UuXG4gICAgLy8gVGhpcyBpcyBhIG5hdHVyYWwgdW5pdCBvZiBtZWFuaW5nIHdoaWNoIGVuYWJsZXMgZGlzcGxheWluZyBxdW90ZXMgaW5cbiAgICAvLyBjb250ZXh0IGV2ZW4gd2hlbiB0aGUgZG9jdW1lbnQgaXMgbm90IGF2YWlsYWJsZS4gV2UgY291bGQgdXNlIGBJbnRsLlNlZ21lbnRlcmBcbiAgICAvLyBmb3IgdGhpcyB3aGVuIGF2YWlsYWJsZS5cbiAgICBjb25zdCBjb250ZXh0TGVuID0gMzI7XG5cbiAgICByZXR1cm4gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCB0ZXh0LnNsaWNlKHN0YXJ0LCBlbmQpLCB7XG4gICAgICBwcmVmaXg6IHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgc3RhcnQgLSBjb250ZXh0TGVuKSwgc3RhcnQpLFxuICAgICAgc3VmZml4OiB0ZXh0LnNsaWNlKGVuZCwgTWF0aC5taW4odGV4dC5sZW5ndGgsIGVuZCArIGNvbnRleHRMZW4pKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtUZXh0UXVvdGVTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCB7IHByZWZpeCwgc3VmZml4IH0gPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCBzZWxlY3Rvci5leGFjdCwgeyBwcmVmaXgsIHN1ZmZpeCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUZXh0UXVvdGVTZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdUZXh0UXVvdGVTZWxlY3RvcicsXG4gICAgICBleGFjdDogdGhpcy5leGFjdCxcbiAgICAgIHByZWZpeDogdGhpcy5jb250ZXh0LnByZWZpeCxcbiAgICAgIHN1ZmZpeDogdGhpcy5jb250ZXh0LnN1ZmZpeCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVvdGVNYXRjaE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKi9cbiAgdG9SYW5nZShvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy50b1Bvc2l0aW9uQW5jaG9yKG9wdGlvbnMpLnRvUmFuZ2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1b3RlTWF0Y2hPcHRpb25zfSBbb3B0aW9uc11cbiAgICovXG4gIHRvUG9zaXRpb25BbmNob3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAodGhpcy5yb290LnRleHRDb250ZW50KTtcbiAgICBjb25zdCBtYXRjaCA9IG1hdGNoUXVvdGUodGV4dCwgdGhpcy5leGFjdCwge1xuICAgICAgLi4udGhpcy5jb250ZXh0LFxuICAgICAgaGludDogb3B0aW9ucy5oaW50LFxuICAgIH0pO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUXVvdGUgbm90IGZvdW5kJyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKHRoaXMucm9vdCwgbWF0Y2guc3RhcnQsIG1hdGNoLmVuZCk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IFRleHRRdW90ZUFuY2hvciB9IGZyb20gXCIuL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90eXBlc1wiO1xuXG4vLyBDYXRjaCBKUyBlcnJvcnMgdG8gbG9nIHRoZW0gaW4gdGhlIGFwcC5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImVycm9yXCIsXG4gIGZ1bmN0aW9uIChldmVudCkge1xuICAgIEFuZHJvaWQubG9nRXJyb3IoZXZlbnQubWVzc2FnZSwgZXZlbnQuZmlsZW5hbWUsIGV2ZW50LmxpbmVubyk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICBvblZpZXdwb3J0V2lkdGhDaGFuZ2VkKCk7XG4gICAgICBzbmFwQ3VycmVudE9mZnNldCgpO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuYm9keSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG4vKipcbiAqIEhhdmluZyBhbiBvZGQgbnVtYmVyIG9mIGNvbHVtbnMgd2hlbiBkaXNwbGF5aW5nIHR3byBjb2x1bW5zIHBlciBzY3JlZW4gY2F1c2VzIHNuYXBwaW5nIGFuZCBwYWdlXG4gKiB0dXJuaW5nIGlzc3Vlcy4gVG8gZml4IHRoaXMsIHdlIGluc2VydCBhIGJsYW5rIHZpcnR1YWwgY29sdW1uIGF0IHRoZSBlbmQgb2YgdGhlIHJlc291cmNlLlxuICovXG5mdW5jdGlvbiBhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQoKSB7XG4gIGNvbnN0IGlkID0gXCJyZWFkaXVtLXZpcnR1YWwtcGFnZVwiO1xuICB2YXIgdmlydHVhbENvbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSB8fCBnZXRDb2x1bW5Db3VudFBlclNjcmVlbigpICE9IDIpIHtcbiAgICBpZiAodmlydHVhbENvbCkge1xuICAgICAgdmlydHVhbENvbC5yZW1vdmUoKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICAgIHZhciBjb2xDb3VudCA9IGRvY3VtZW50V2lkdGggLyBwYWdlV2lkdGg7XG4gICAgdmFyIGhhc09kZENvbENvdW50ID0gKE1hdGgucm91bmQoY29sQ291bnQgKiAyKSAvIDIpICUgMSA+IDAuMTtcbiAgICBpZiAoaGFzT2RkQ29sQ291bnQpIHtcbiAgICAgIGlmICh2aXJ0dWFsQ29sKSB7XG4gICAgICAgIHZpcnR1YWxDb2wucmVtb3ZlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aXJ0dWFsQ29sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgdmlydHVhbENvbC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBpZCk7XG4gICAgICAgIHZpcnR1YWxDb2wuc3R5bGUuYnJlYWtCZWZvcmUgPSBcImNvbHVtblwiO1xuICAgICAgICB2aXJ0dWFsQ29sLmlubmVySFRNTCA9IFwiJiM4MjAzO1wiOyAvLyB6ZXJvLXdpZHRoIHNwYWNlXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodmlydHVhbENvbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB2YXIgcGFnZVdpZHRoID0gMTtcblxuZnVuY3Rpb24gb25WaWV3cG9ydFdpZHRoQ2hhbmdlZCgpIHtcbiAgLy8gV2UgY2FuJ3QgcmVseSBvbiB3aW5kb3cuaW5uZXJXaWR0aCBmb3IgdGhlIHBhZ2VXaWR0aCBvbiBBbmRyb2lkLCBiZWNhdXNlIGlmIHRoZVxuICAvLyBkZXZpY2UgcGl4ZWwgcmF0aW8gaXMgbm90IGFuIGludGVnZXIsIHdlIGdldCByb3VuZGluZyBpc3N1ZXMgb2Zmc2V0dGluZyB0aGUgcGFnZXMuXG4gIC8vXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vcmVhZGl1bS9yZWFkaXVtLWNzcy9pc3N1ZXMvOTdcbiAgLy8gYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFkaXVtL3IyLW5hdmlnYXRvci1rb3RsaW4vaXNzdWVzLzE0NlxuICB2YXIgd2lkdGggPSBBbmRyb2lkLmdldFZpZXdwb3J0V2lkdGgoKTtcbiAgcGFnZVdpZHRoID0gd2lkdGggLyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgc2V0UHJvcGVydHkoXG4gICAgXCItLVJTX192aWV3cG9ydFdpZHRoXCIsXG4gICAgXCJjYWxjKFwiICsgd2lkdGggKyBcInB4IC8gXCIgKyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyArIFwiKVwiXG4gICk7XG5cbiAgYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2x1bW5Db3VudFBlclNjcmVlbigpIHtcbiAgcmV0dXJuIHBhcnNlSW50KFxuICAgIHdpbmRvd1xuICAgICAgLmdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KVxuICAgICAgLmdldFByb3BlcnR5VmFsdWUoXCJjb2x1bW4tY291bnRcIilcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSB7XG4gIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlO1xuICByZXR1cm4gKFxuICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLVVTRVJfX3ZpZXdcIikudHJpbSgpID09IFwicmVhZGl1bS1zY3JvbGwtb25cIiB8fFxuICAgIC8vIEZJWE1FOiBXaWxsIG5lZWQgdG8gYmUgcmVtb3ZlZCBpbiBSZWFkaXVtIDMuMCwgLS1VU0VSX19zY3JvbGwgd2FzIGluY29ycmVjdC5cbiAgICBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1VU0VSX19zY3JvbGxcIikudHJpbSgpID09IFwicmVhZGl1bS1zY3JvbGwtb25cIlxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSVEwoKSB7XG4gIHJldHVybiBkb2N1bWVudC5ib2R5LmRpci50b0xvd2VyQ2FzZSgpID09IFwicnRsXCI7XG59XG5cbi8vIFNjcm9sbCB0byB0aGUgZ2l2ZW4gVGFnSWQgaW4gZG9jdW1lbnQgYW5kIHNuYXAuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9JZChpZCkge1xuICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHNjcm9sbFRvUmVjdChlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbn1cblxuLy8gUG9zaXRpb24gbXVzdCBiZSBpbiB0aGUgcmFuZ2UgWzAgLSAxXSwgMC0xMDAlLlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvUG9zaXRpb24ocG9zaXRpb24pIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9Qb3NpdGlvbiBcIiArIHBvc2l0aW9uKTtcbiAgaWYgKHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+IDEpIHtcbiAgICB0aHJvdyBcInNjcm9sbFRvUG9zaXRpb24oKSBtdXN0IGJlIGdpdmVuIGEgcG9zaXRpb24gZnJvbSAwLjAgdG8gIDEuMFwiO1xuICB9XG5cbiAgbGV0IG9mZnNldDtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIG9mZnNldCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsSGVpZ2h0ICogcG9zaXRpb247XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSBvZmZzZXQ7XG4gICAgLy8gd2luZG93LnNjcm9sbFRvKDAsIG9mZnNldCk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICAgIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICAgIG9mZnNldCA9IGRvY3VtZW50V2lkdGggKiBwb3NpdGlvbiAqIGZhY3RvcjtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KG9mZnNldCk7XG4gIH1cbn1cblxuLy8gU2Nyb2xscyB0byB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgZ2l2ZW4gdGV4dCBzbmlwcGV0LlxuLy9cbi8vIFRoZSBleHBlY3RlZCB0ZXh0IGFyZ3VtZW50IGlzIGEgTG9jYXRvciBUZXh0IG9iamVjdCwgYXMgZGVmaW5lZCBoZXJlOlxuLy8gaHR0cHM6Ly9yZWFkaXVtLm9yZy9hcmNoaXRlY3R1cmUvbW9kZWxzL2xvY2F0b3JzL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvVGV4dCh0ZXh0KSB7XG4gIGxldCByYW5nZSA9IHJhbmdlRnJvbUxvY2F0b3IoeyB0ZXh0IH0pO1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHNjcm9sbFRvUmFuZ2UocmFuZ2UpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gc2Nyb2xsVG9SYW5nZShyYW5nZSkge1xuICByZXR1cm4gc2Nyb2xsVG9SZWN0KHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbn1cblxuZnVuY3Rpb24gc2Nyb2xsVG9SZWN0KHJlY3QpIHtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID1cbiAgICAgIHJlY3QudG9wICsgd2luZG93LnNjcm9sbFkgLSB3aW5kb3cuaW5uZXJIZWlnaHQgLyAyO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoXG4gICAgICByZWN0LmxlZnQgKyB3aW5kb3cuc2Nyb2xsWFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvU3RhcnQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvU3RhcnRcIik7XG4gIGlmICghaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IDA7XG4gICAgd2luZG93LnNjcm9sbFRvKDAsIDApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb0VuZCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9FbmRcIik7XG4gIGlmICghaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChcbiAgICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGggKiBmYWN0b3JcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQ7XG4gICAgd2luZG93LnNjcm9sbFRvKDAsIGRvY3VtZW50LmJvZHkuc2Nyb2xsSGVpZ2h0KTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIGlzIGFscmVhZHkgYXQgdGhlIGxlZnQtbW9zdCBzY3JvbGwgb2Zmc2V0LlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbExlZnQoKSB7XG4gIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgdmFyIG9mZnNldCA9IHdpbmRvdy5zY3JvbGxYIC0gcGFnZVdpZHRoO1xuICB2YXIgbWluT2Zmc2V0ID0gaXNSVEwoKSA/IC0oZG9jdW1lbnRXaWR0aCAtIHBhZ2VXaWR0aCkgOiAwO1xuICByZXR1cm4gc2Nyb2xsVG9PZmZzZXQoTWF0aC5tYXgob2Zmc2V0LCBtaW5PZmZzZXQpKTtcbn1cblxuLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgcGFnZSBpcyBhbHJlYWR5IGF0IHRoZSByaWdodC1tb3N0IHNjcm9sbCBvZmZzZXQuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsUmlnaHQoKSB7XG4gIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgdmFyIG9mZnNldCA9IHdpbmRvdy5zY3JvbGxYICsgcGFnZVdpZHRoO1xuICB2YXIgbWF4T2Zmc2V0ID0gaXNSVEwoKSA/IDAgOiBkb2N1bWVudFdpZHRoIC0gcGFnZVdpZHRoO1xuICByZXR1cm4gc2Nyb2xsVG9PZmZzZXQoTWF0aC5taW4ob2Zmc2V0LCBtYXhPZmZzZXQpKTtcbn1cblxuLy8gU2Nyb2xscyB0byB0aGUgZ2l2ZW4gbGVmdCBvZmZzZXQuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIHNjcm9sbCBwb3NpdGlvbiBpcyBhbHJlYWR5IGNsb3NlIGVub3VnaCB0byB0aGUgZ2l2ZW4gb2Zmc2V0LlxuZnVuY3Rpb24gc2Nyb2xsVG9PZmZzZXQob2Zmc2V0KSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvT2Zmc2V0IFwiICsgb2Zmc2V0KTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHRocm93IFwiQ2FsbGVkIHNjcm9sbFRvT2Zmc2V0KCkgd2l0aCBzY3JvbGwgbW9kZSBlbmFibGVkLiBUaGlzIGNhbiBvbmx5IGJlIHVzZWQgaW4gcGFnaW5hdGVkIG1vZGUuXCI7XG4gIH1cblxuICB2YXIgY3VycmVudE9mZnNldCA9IHdpbmRvdy5zY3JvbGxYO1xuICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KG9mZnNldCk7XG4gIC8vIEluIHNvbWUgY2FzZSB0aGUgc2Nyb2xsWCBjYW5ub3QgcmVhY2ggdGhlIHBvc2l0aW9uIHJlc3BlY3RpbmcgdG8gaW5uZXJXaWR0aFxuICB2YXIgZGlmZiA9IE1hdGguYWJzKGN1cnJlbnRPZmZzZXQgLSBvZmZzZXQpIC8gcGFnZVdpZHRoO1xuICByZXR1cm4gZGlmZiA+IDAuMDE7XG59XG5cbi8vIFNuYXAgdGhlIG9mZnNldCB0byB0aGUgc2NyZWVuIHdpZHRoIChwYWdlIHdpZHRoKS5cbmZ1bmN0aW9uIHNuYXBPZmZzZXQob2Zmc2V0KSB7XG4gIHZhciB2YWx1ZSA9IG9mZnNldCArIChpc1JUTCgpID8gLTEgOiAxKTtcbiAgcmV0dXJuIHZhbHVlIC0gKHZhbHVlICUgcGFnZVdpZHRoKTtcbn1cblxuLy8gU25hcHMgdGhlIGN1cnJlbnQgb2Zmc2V0IHRvIHRoZSBwYWdlIHdpZHRoLlxuZXhwb3J0IGZ1bmN0aW9uIHNuYXBDdXJyZW50T2Zmc2V0KCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzbmFwQ3VycmVudE9mZnNldFwiKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgY3VycmVudE9mZnNldCA9IHdpbmRvdy5zY3JvbGxYO1xuICAvLyBBZGRzIGhhbGYgYSBwYWdlIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndCBzbmFwIHRvIHRoZSBwcmV2aW91cyBwYWdlLlxuICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgdmFyIGRlbHRhID0gZmFjdG9yICogKHBhZ2VXaWR0aCAvIDIpO1xuICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KGN1cnJlbnRPZmZzZXQgKyBkZWx0YSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByYW5nZUZyb21Mb2NhdG9yKGxvY2F0b3IpIHtcbiAgdHJ5IHtcbiAgICBsZXQgbG9jYXRpb25zID0gbG9jYXRvci5sb2NhdGlvbnM7XG4gICAgbGV0IHRleHQgPSBsb2NhdG9yLnRleHQ7XG4gICAgaWYgKHRleHQgJiYgdGV4dC5oaWdobGlnaHQpIHtcbiAgICAgIHZhciByb290O1xuICAgICAgaWYgKGxvY2F0aW9ucyAmJiBsb2NhdGlvbnMuY3NzU2VsZWN0b3IpIHtcbiAgICAgICAgcm9vdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobG9jYXRpb25zLmNzc1NlbGVjdG9yKTtcbiAgICAgIH1cbiAgICAgIGlmICghcm9vdCkge1xuICAgICAgICByb290ID0gZG9jdW1lbnQuYm9keTtcbiAgICAgIH1cblxuICAgICAgbGV0IGFuY2hvciA9IG5ldyBUZXh0UXVvdGVBbmNob3Iocm9vdCwgdGV4dC5oaWdobGlnaHQsIHtcbiAgICAgICAgcHJlZml4OiB0ZXh0LmJlZm9yZSxcbiAgICAgICAgc3VmZml4OiB0ZXh0LmFmdGVyLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gYW5jaG9yLnRvUmFuZ2UoKTtcbiAgICB9XG5cbiAgICBpZiAobG9jYXRpb25zKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IG51bGw7XG5cbiAgICAgIGlmICghZWxlbWVudCAmJiBsb2NhdGlvbnMuY3NzU2VsZWN0b3IpIHtcbiAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobG9jYXRpb25zLmNzc1NlbGVjdG9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50ICYmIGxvY2F0aW9ucy5mcmFnbWVudHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBodG1sSWQgb2YgbG9jYXRpb25zLmZyYWdtZW50cykge1xuICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChodG1sSWQpO1xuICAgICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgbGV0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnRCZWZvcmUoZWxlbWVudCk7XG4gICAgICAgIHJhbmdlLnNldEVuZEFmdGVyKGVsZW1lbnQpO1xuICAgICAgICByZXR1cm4gcmFuZ2U7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nRXJyb3IoZSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8vIFVzZXIgU2V0dGluZ3MuXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDU1NQcm9wZXJ0aWVzKHByb3BlcnRpZXMpIHtcbiAgZm9yIChjb25zdCBuYW1lIGluIHByb3BlcnRpZXMpIHtcbiAgICBzZXRQcm9wZXJ0eShuYW1lLCBwcm9wZXJ0aWVzW25hbWVdKTtcbiAgfVxufVxuXG4vLyBGb3Igc2V0dGluZyB1c2VyIHNldHRpbmcuXG5leHBvcnQgZnVuY3Rpb24gc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCIpIHtcbiAgICByZW1vdmVQcm9wZXJ0eShrZXkpO1xuICB9IGVsc2Uge1xuICAgIHZhciByb290ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgIC8vIFRoZSBgIWltcG9ydGFudGAgYW5ub3RhdGlvbiBpcyBhZGRlZCB3aXRoIGBzZXRQcm9wZXJ0eSgpYCBiZWNhdXNlIGlmIGl0J3MgcGFydCBvZiB0aGVcbiAgICAvLyBgdmFsdWVgLCBpdCB3aWxsIGJlIGlnbm9yZWQgYnkgdGhlIFdlYiBWaWV3LlxuICAgIHJvb3Quc3R5bGUuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSwgXCJpbXBvcnRhbnRcIik7XG4gIH1cbn1cblxuLy8gRm9yIHJlbW92aW5nIHVzZXIgc2V0dGluZy5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVQcm9wZXJ0eShrZXkpIHtcbiAgdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cbiAgcm9vdC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShrZXkpO1xufVxuXG4vLy8gVG9vbGtpdFxuXG5leHBvcnQgZnVuY3Rpb24gbG9nKCkge1xuICB2YXIgbWVzc2FnZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykuam9pbihcIiBcIik7XG4gIEFuZHJvaWQubG9nKG1lc3NhZ2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9nRXJyb3IobWVzc2FnZSkge1xuICBBbmRyb2lkLmxvZ0Vycm9yKG1lc3NhZ2UsIFwiXCIsIDApO1xufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgbG9nIGFzIGxvZ05hdGl2ZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmNvbnN0IGRlYnVnID0gZmFsc2U7XG5cbi8qKlxuICogQ29udmVydHMgYSBET01SZWN0IGludG8gYSBKU09OIG9iamVjdCB1bmRlcnN0YW5kYWJsZSBieSB0aGUgbmF0aXZlIHNpZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b05hdGl2ZVJlY3QocmVjdCkge1xuICBjb25zdCBwaXhlbFJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gIGNvbnN0IHdpZHRoID0gcmVjdC53aWR0aCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IGhlaWdodCA9IHJlY3QuaGVpZ2h0ICogcGl4ZWxSYXRpbztcbiAgY29uc3QgbGVmdCA9IHJlY3QubGVmdCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IHRvcCA9IHJlY3QudG9wICogcGl4ZWxSYXRpbztcbiAgY29uc3QgcmlnaHQgPSBsZWZ0ICsgd2lkdGg7XG4gIGNvbnN0IGJvdHRvbSA9IHRvcCArIGhlaWdodDtcbiAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCwgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgcmFuZ2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBsZXQgY2xpZW50UmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xuXG4gIGNvbnN0IHRvbGVyYW5jZSA9IDE7XG4gIGNvbnN0IG9yaWdpbmFsUmVjdHMgPSBbXTtcbiAgZm9yIChjb25zdCByYW5nZUNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBvcmlnaW5hbFJlY3RzLnB1c2goe1xuICAgICAgYm90dG9tOiByYW5nZUNsaWVudFJlY3QuYm90dG9tLFxuICAgICAgaGVpZ2h0OiByYW5nZUNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgbGVmdDogcmFuZ2VDbGllbnRSZWN0LmxlZnQsXG4gICAgICByaWdodDogcmFuZ2VDbGllbnRSZWN0LnJpZ2h0LFxuICAgICAgdG9wOiByYW5nZUNsaWVudFJlY3QudG9wLFxuICAgICAgd2lkdGg6IHJhbmdlQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9KTtcbiAgfVxuICBjb25zdCBtZXJnZWRSZWN0cyA9IG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICBvcmlnaW5hbFJlY3RzLFxuICAgIHRvbGVyYW5jZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG4gIGNvbnN0IG5vQ29udGFpbmVkUmVjdHMgPSByZW1vdmVDb250YWluZWRSZWN0cyhtZXJnZWRSZWN0cywgdG9sZXJhbmNlKTtcbiAgY29uc3QgbmV3UmVjdHMgPSByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5vQ29udGFpbmVkUmVjdHMpO1xuICBjb25zdCBtaW5BcmVhID0gMiAqIDI7XG4gIGZvciAobGV0IGogPSBuZXdSZWN0cy5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgIGNvbnN0IHJlY3QgPSBuZXdSZWN0c1tqXTtcbiAgICBjb25zdCBiaWdFbm91Z2ggPSByZWN0LndpZHRoICogcmVjdC5oZWlnaHQgPiBtaW5BcmVhO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBpZiAobmV3UmVjdHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsXCIpO1xuICAgICAgICBuZXdSZWN0cy5zcGxpY2UoaiwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsLCBidXQga2VlcCBvdGhlcndpc2UgZW1wdHkhXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgbG9nKGBDTElFTlQgUkVDVDogcmVkdWNlZCAke29yaWdpbmFsUmVjdHMubGVuZ3RofSAtLT4gJHtuZXdSZWN0cy5sZW5ndGh9YCk7XG4gIHJldHVybiBuZXdSZWN0cztcbn1cblxuZnVuY3Rpb24gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICByZWN0cyxcbiAgdG9sZXJhbmNlLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgbG9nKFwibWVyZ2VUb3VjaGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVjdHNMaW5lVXBWZXJ0aWNhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCByZWN0c0xpbmVVcEhvcml6b250YWxseSA9XG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpO1xuICAgICAgY29uc3QgaG9yaXpvbnRhbEFsbG93ZWQgPSAhZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cztcbiAgICAgIGNvbnN0IGFsaWduZWQgPVxuICAgICAgICAocmVjdHNMaW5lVXBIb3Jpem9udGFsbHkgJiYgaG9yaXpvbnRhbEFsbG93ZWQpIHx8XG4gICAgICAgIChyZWN0c0xpbmVVcFZlcnRpY2FsbHkgJiYgIXJlY3RzTGluZVVwSG9yaXpvbnRhbGx5KTtcbiAgICAgIGNvbnN0IGNhbk1lcmdlID0gYWxpZ25lZCAmJiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKTtcbiAgICAgIGlmIChjYW5NZXJnZSkge1xuICAgICAgICBsb2coXG4gICAgICAgICAgYENMSUVOVCBSRUNUOiBtZXJnaW5nIHR3byBpbnRvIG9uZSwgVkVSVElDQUw6ICR7cmVjdHNMaW5lVXBWZXJ0aWNhbGx5fSBIT1JJWk9OVEFMOiAke3JlY3RzTGluZVVwSG9yaXpvbnRhbGx5fSAoJHtkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzfSlgXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHJlY3QxICYmIHJlY3QgIT09IHJlY3QyO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVwbGFjZW1lbnRDbGllbnRSZWN0ID0gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIG5ld1JlY3RzLnB1c2gocmVwbGFjZW1lbnRDbGllbnRSZWN0KTtcbiAgICAgICAgcmV0dXJuIG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICAgICAgICBuZXdSZWN0cyxcbiAgICAgICAgICB0b2xlcmFuY2UsXG4gICAgICAgICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbGVmdCA9IE1hdGgubWluKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCByaWdodCA9IE1hdGgubWF4KHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IHRvcCA9IE1hdGgubWluKHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgYm90dG9tID0gTWF0aC5tYXgocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbSxcbiAgICBoZWlnaHQ6IGJvdHRvbSAtIHRvcCxcbiAgICBsZWZ0LFxuICAgIHJpZ2h0LFxuICAgIHRvcCxcbiAgICB3aWR0aDogcmlnaHQgLSBsZWZ0LFxuICB9O1xufVxuXG5mdW5jdGlvbiByZW1vdmVDb250YWluZWRSZWN0cyhyZWN0cywgdG9sZXJhbmNlKSB7XG4gIGNvbnN0IHJlY3RzVG9LZWVwID0gbmV3IFNldChyZWN0cyk7XG4gIGZvciAoY29uc3QgcmVjdCBvZiByZWN0cykge1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggPiAxICYmIHJlY3QuaGVpZ2h0ID4gMTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgbG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSB0aW55XCIpO1xuICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcG9zc2libHlDb250YWluaW5nUmVjdCBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QgPT09IHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIXJlY3RzVG9LZWVwLmhhcyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0Q29udGFpbnMocG9zc2libHlDb250YWluaW5nUmVjdCwgcmVjdCwgdG9sZXJhbmNlKSkge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIGNvbnRhaW5lZFwiKTtcbiAgICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20ocmVjdHNUb0tlZXApO1xufVxuXG5mdW5jdGlvbiByZWN0Q29udGFpbnMocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY3RDb250YWluc1BvaW50KHJlY3QsIHgsIHksIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0LmxlZnQgPCB4IHx8IGFsbW9zdEVxdWFsKHJlY3QubGVmdCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5yaWdodCA+IHggfHwgYWxtb3N0RXF1YWwocmVjdC5yaWdodCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC50b3AgPCB5IHx8IGFsbW9zdEVxdWFsKHJlY3QudG9wLCB5LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LmJvdHRvbSA+IHkgfHwgYWxtb3N0RXF1YWwocmVjdC5ib3R0b20sIHksIHRvbGVyYW5jZSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMocmVjdHMpIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgbG9nKFwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyByZWN0MSA9PT0gcmVjdDIgPz8hXCIpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgLTEpKSB7XG4gICAgICAgIGxldCB0b0FkZCA9IFtdO1xuICAgICAgICBsZXQgdG9SZW1vdmU7XG4gICAgICAgIGNvbnN0IHN1YnRyYWN0UmVjdHMxID0gcmVjdFN1YnRyYWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czIgPSByZWN0U3VidHJhY3QocmVjdDIsIHJlY3QxKTtcbiAgICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoIDwgc3VidHJhY3RSZWN0czIubGVuZ3RoKSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMjtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxvZyhgQ0xJRU5UIFJFQ1Q6IG92ZXJsYXAsIGN1dCBvbmUgcmVjdCBpbnRvICR7dG9BZGQubGVuZ3RofWApO1xuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSB0b1JlbW92ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KG5ld1JlY3RzLCB0b0FkZCk7XG4gICAgICAgIHJldHVybiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5ld1JlY3RzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IHJlY3RJbnRlcnNlY3RlZCA9IHJlY3RJbnRlcnNlY3QocmVjdDIsIHJlY3QxKTtcbiAgaWYgKHJlY3RJbnRlcnNlY3RlZC5oZWlnaHQgPT09IDAgfHwgcmVjdEludGVyc2VjdGVkLndpZHRoID09PSAwKSB7XG4gICAgcmV0dXJuIFtyZWN0MV07XG4gIH1cbiAgY29uc3QgcmVjdHMgPSBbXTtcbiAge1xuICAgIGNvbnN0IHJlY3RBID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0MS5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RBLndpZHRoID0gcmVjdEEucmlnaHQgLSByZWN0QS5sZWZ0O1xuICAgIHJlY3RBLmhlaWdodCA9IHJlY3RBLmJvdHRvbSAtIHJlY3RBLnRvcDtcbiAgICBpZiAocmVjdEEuaGVpZ2h0ICE9PSAwICYmIHJlY3RBLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RBKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RCID0ge1xuICAgICAgYm90dG9tOiByZWN0SW50ZXJzZWN0ZWQudG9wLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RCLndpZHRoID0gcmVjdEIucmlnaHQgLSByZWN0Qi5sZWZ0O1xuICAgIHJlY3RCLmhlaWdodCA9IHJlY3RCLmJvdHRvbSAtIHJlY3RCLnRvcDtcbiAgICBpZiAocmVjdEIuaGVpZ2h0ICE9PSAwICYmIHJlY3RCLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RCKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RDID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3RJbnRlcnNlY3RlZC5ib3R0b20sXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RDLndpZHRoID0gcmVjdEMucmlnaHQgLSByZWN0Qy5sZWZ0O1xuICAgIHJlY3RDLmhlaWdodCA9IHJlY3RDLmJvdHRvbSAtIHJlY3RDLnRvcDtcbiAgICBpZiAocmVjdEMuaGVpZ2h0ICE9PSAwICYmIHJlY3RDLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RDKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3REID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICByaWdodDogcmVjdDEucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEQud2lkdGggPSByZWN0RC5yaWdodCAtIHJlY3RELmxlZnQ7XG4gICAgcmVjdEQuaGVpZ2h0ID0gcmVjdEQuYm90dG9tIC0gcmVjdEQudG9wO1xuICAgIGlmIChyZWN0RC5oZWlnaHQgIT09IDAgJiYgcmVjdEQud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RJbnRlcnNlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IG1heExlZnQgPSBNYXRoLm1heChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgbWluUmlnaHQgPSBNYXRoLm1pbihyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCBtYXhUb3AgPSBNYXRoLm1heChyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IG1pbkJvdHRvbSA9IE1hdGgubWluKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgcmV0dXJuIHtcbiAgICBib3R0b206IG1pbkJvdHRvbSxcbiAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIG1pbkJvdHRvbSAtIG1heFRvcCksXG4gICAgbGVmdDogbWF4TGVmdCxcbiAgICByaWdodDogbWluUmlnaHQsXG4gICAgdG9wOiBtYXhUb3AsXG4gICAgd2lkdGg6IE1hdGgubWF4KDAsIG1pblJpZ2h0IC0gbWF4TGVmdCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICAocmVjdDEubGVmdCA8IHJlY3QyLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi5sZWZ0IDwgcmVjdDEucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi5sZWZ0LCByZWN0MS5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QxLnRvcCA8IHJlY3QyLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIudG9wIDwgcmVjdDEuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIudG9wLCByZWN0MS5ib3R0b20sIHRvbGVyYW5jZSkpKVxuICApO1xufVxuXG5mdW5jdGlvbiBhbG1vc3RFcXVhbChhLCBiLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8PSB0b2xlcmFuY2U7XG59XG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgbG9nTmF0aXZlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7XG4gIGdldENsaWVudFJlY3RzTm9PdmVybGFwLFxuICByZWN0Q29udGFpbnNQb2ludCxcbiAgdG9OYXRpdmVSZWN0LFxufSBmcm9tIFwiLi9yZWN0XCI7XG5pbXBvcnQgeyBsb2csIGxvZ0Vycm9yLCByYW5nZUZyb21Mb2NhdG9yIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxubGV0IHN0eWxlcyA9IG5ldyBNYXAoKTtcbmxldCBncm91cHMgPSBuZXcgTWFwKCk7XG52YXIgbGFzdEdyb3VwSWQgPSAwO1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGxpc3Qgb2YgYWRkaXRpb25hbCBzdXBwb3J0ZWQgRGVjb3JhdGlvbiBUZW1wbGF0ZXMuXG4gKlxuICogRWFjaCB0ZW1wbGF0ZSBvYmplY3QgaXMgaW5kZXhlZCBieSB0aGUgc3R5bGUgSUQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclRlbXBsYXRlcyhuZXdTdHlsZXMpIHtcbiAgdmFyIHN0eWxlc2hlZXQgPSBcIlwiO1xuXG4gIGZvciAoY29uc3QgW2lkLCBzdHlsZV0gb2YgT2JqZWN0LmVudHJpZXMobmV3U3R5bGVzKSkge1xuICAgIHN0eWxlcy5zZXQoaWQsIHN0eWxlKTtcbiAgICBpZiAoc3R5bGUuc3R5bGVzaGVldCkge1xuICAgICAgc3R5bGVzaGVldCArPSBzdHlsZS5zdHlsZXNoZWV0ICsgXCJcXG5cIjtcbiAgICB9XG4gIH1cblxuICBpZiAoc3R5bGVzaGVldCkge1xuICAgIGxldCBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG4gICAgc3R5bGVFbGVtZW50LmlubmVySFRNTCA9IHN0eWxlc2hlZXQ7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIERlY29yYXRpb25Hcm91cCBmb3IgdGhlIGdpdmVuIGdyb3VwIG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWNvcmF0aW9ucyhncm91cE5hbWUpIHtcbiAgdmFyIGdyb3VwID0gZ3JvdXBzLmdldChncm91cE5hbWUpO1xuICBpZiAoIWdyb3VwKSB7XG4gICAgbGV0IGlkID0gXCJyMi1kZWNvcmF0aW9uLVwiICsgbGFzdEdyb3VwSWQrKztcbiAgICBncm91cCA9IERlY29yYXRpb25Hcm91cChpZCwgZ3JvdXBOYW1lKTtcbiAgICBncm91cHMuc2V0KGdyb3VwTmFtZSwgZ3JvdXApO1xuICB9XG4gIHJldHVybiBncm91cDtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGNsaWNrIGV2ZW50cyBvbiBhIERlY29yYXRpb24uXG4gKiBSZXR1cm5zIHdoZXRoZXIgYSBkZWNvcmF0aW9uIG1hdGNoZWQgdGhpcyBldmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50KGV2ZW50LCBjbGlja0V2ZW50KSB7XG4gIGlmIChncm91cHMuc2l6ZSA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbmRUYXJnZXQoKSB7XG4gICAgZm9yIChjb25zdCBbZ3JvdXAsIGdyb3VwQ29udGVudF0gb2YgZ3JvdXBzKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZ3JvdXBDb250ZW50Lml0ZW1zLnJldmVyc2UoKSkge1xuICAgICAgICBpZiAoIWl0ZW0uY2xpY2thYmxlRWxlbWVudHMpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgaXRlbS5jbGlja2FibGVFbGVtZW50cykge1xuICAgICAgICAgIGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b0pTT04oKTtcbiAgICAgICAgICBpZiAocmVjdENvbnRhaW5zUG9pbnQocmVjdCwgZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgMSkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGdyb3VwLCBpdGVtLCBlbGVtZW50LCByZWN0IH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHRhcmdldCA9IGZpbmRUYXJnZXQoKTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gQW5kcm9pZC5vbkRlY29yYXRpb25BY3RpdmF0ZWQoXG4gICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgaWQ6IHRhcmdldC5pdGVtLmRlY29yYXRpb24uaWQsXG4gICAgICBncm91cDogdGFyZ2V0Lmdyb3VwLFxuICAgICAgcmVjdDogdG9OYXRpdmVSZWN0KHRhcmdldC5pdGVtLnJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxcbiAgICAgIGNsaWNrOiBjbGlja0V2ZW50LFxuICAgIH0pXG4gICk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIERlY29yYXRpb25Hcm91cCBvYmplY3QgZnJvbSBhIHVuaXF1ZSBIVE1MIElEIGFuZCBpdHMgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIERlY29yYXRpb25Hcm91cChncm91cElkLCBncm91cE5hbWUpIHtcbiAgdmFyIGl0ZW1zID0gW107XG4gIHZhciBsYXN0SXRlbUlkID0gMDtcbiAgdmFyIGNvbnRhaW5lciA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBuZXcgZGVjb3JhdGlvbiB0byB0aGUgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiBhZGQoZGVjb3JhdGlvbikge1xuICAgIGxldCBpZCA9IGdyb3VwSWQgKyBcIi1cIiArIGxhc3RJdGVtSWQrKztcblxuICAgIGxldCByYW5nZSA9IHJhbmdlRnJvbUxvY2F0b3IoZGVjb3JhdGlvbi5sb2NhdG9yKTtcbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICBsb2coXCJDYW4ndCBsb2NhdGUgRE9NIHJhbmdlIGZvciBkZWNvcmF0aW9uXCIsIGRlY29yYXRpb24pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtID0geyBpZCwgZGVjb3JhdGlvbiwgcmFuZ2UgfTtcbiAgICBpdGVtcy5wdXNoKGl0ZW0pO1xuICAgIGxheW91dChpdGVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBkZWNvcmF0aW9uIHdpdGggZ2l2ZW4gSUQgZnJvbSB0aGUgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiByZW1vdmUoZGVjb3JhdGlvbklkKSB7XG4gICAgbGV0IGluZGV4ID0gaXRlbXMuZmluZEluZGV4KChpKSA9PiBpLmRlY29yYXRpb24uaWQgPT09IGRlY29yYXRpb25JZCk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtID0gaXRlbXNbaW5kZXhdO1xuICAgIGl0ZW1zLnNwbGljZShpbmRleCwgMSk7XG4gICAgaXRlbS5jbGlja2FibGVFbGVtZW50cyA9IG51bGw7XG4gICAgaWYgKGl0ZW0uY29udGFpbmVyKSB7XG4gICAgICBpdGVtLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGl0ZW0uY29udGFpbmVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTm90aWZpZXMgdGhhdCB0aGUgZ2l2ZW4gZGVjb3JhdGlvbiB3YXMgbW9kaWZpZWQgYW5kIG5lZWRzIHRvIGJlIHVwZGF0ZWQuXG4gICAqL1xuICBmdW5jdGlvbiB1cGRhdGUoZGVjb3JhdGlvbikge1xuICAgIHJlbW92ZShkZWNvcmF0aW9uLmlkKTtcbiAgICBhZGQoZGVjb3JhdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgZGVjb3JhdGlvbnMgZnJvbSB0aGlzIGdyb3VwLlxuICAgKi9cbiAgZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgY2xlYXJDb250YWluZXIoKTtcbiAgICBpdGVtcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY3JlYXRlcyB0aGUgZGVjb3JhdGlvbiBlbGVtZW50cy5cbiAgICpcbiAgICogVG8gYmUgY2FsbGVkIGFmdGVyIHJlZmxvd2luZyB0aGUgcmVzb3VyY2UsIGZvciBleGFtcGxlLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVxdWVzdExheW91dCgpIHtcbiAgICBjbGVhckNvbnRhaW5lcigpO1xuICAgIGl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IGxheW91dChpdGVtKSk7XG4gIH1cblxuICAvKipcbiAgICogTGF5b3V0cyBhIHNpbmdsZSBEZWNvcmF0aW9uIGl0ZW0uXG4gICAqL1xuICBmdW5jdGlvbiBsYXlvdXQoaXRlbSkge1xuICAgIGxldCBncm91cENvbnRhaW5lciA9IHJlcXVpcmVDb250YWluZXIoKTtcblxuICAgIGxldCBzdHlsZSA9IHN0eWxlcy5nZXQoaXRlbS5kZWNvcmF0aW9uLnN0eWxlKTtcbiAgICBpZiAoIXN0eWxlKSB7XG4gICAgICBsb2dFcnJvcihgVW5rbm93biBkZWNvcmF0aW9uIHN0eWxlOiAke2l0ZW0uZGVjb3JhdGlvbi5zdHlsZX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgaXRlbUNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgaXRlbUNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBpdGVtLmlkKTtcbiAgICBpdGVtQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImRhdGEtc3R5bGVcIiwgaXRlbS5kZWNvcmF0aW9uLnN0eWxlKTtcbiAgICBpdGVtQ29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuXG4gICAgbGV0IHZpZXdwb3J0V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICBsZXQgY29sdW1uQ291bnQgPSBwYXJzZUludChcbiAgICAgIGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKFxuICAgICAgICBcImNvbHVtbi1jb3VudFwiXG4gICAgICApXG4gICAgKTtcbiAgICBsZXQgcGFnZVdpZHRoID0gdmlld3BvcnRXaWR0aCAvIChjb2x1bW5Db3VudCB8fCAxKTtcbiAgICBsZXQgc2Nyb2xsaW5nRWxlbWVudCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQ7XG4gICAgbGV0IHhPZmZzZXQgPSBzY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgbGV0IHlPZmZzZXQgPSBzY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcDtcblxuICAgIGZ1bmN0aW9uIHBvc2l0aW9uRWxlbWVudChlbGVtZW50LCByZWN0LCBib3VuZGluZ1JlY3QpIHtcbiAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG5cbiAgICAgIGlmIChzdHlsZS53aWR0aCA9PT0gXCJ3cmFwXCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke3JlY3Qud2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7cmVjdC5sZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwidmlld3BvcnRcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7dmlld3BvcnRXaWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBsZXQgbGVmdCA9IE1hdGguZmxvb3IocmVjdC5sZWZ0IC8gdmlld3BvcnRXaWR0aCkgKiB2aWV3cG9ydFdpZHRoO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtsZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwiYm91bmRzXCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke2JvdW5kaW5nUmVjdC53aWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtib3VuZGluZ1JlY3QubGVmdCArIHhPZmZzZXR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3JlY3QudG9wICsgeU9mZnNldH1weGA7XG4gICAgICB9IGVsc2UgaWYgKHN0eWxlLndpZHRoID09PSBcInBhZ2VcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7cGFnZVdpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGxldCBsZWZ0ID0gTWF0aC5mbG9vcihyZWN0LmxlZnQgLyBwYWdlV2lkdGgpICogcGFnZVdpZHRoO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtsZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgYm91bmRpbmdSZWN0ID0gaXRlbS5yYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGxldCBlbGVtZW50VGVtcGxhdGU7XG4gICAgdHJ5IHtcbiAgICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtcbiAgICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGl0ZW0uZGVjb3JhdGlvbi5lbGVtZW50LnRyaW0oKTtcbiAgICAgIGVsZW1lbnRUZW1wbGF0ZSA9IHRlbXBsYXRlLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ0Vycm9yKFxuICAgICAgICBgSW52YWxpZCBkZWNvcmF0aW9uIGVsZW1lbnQgXCIke2l0ZW0uZGVjb3JhdGlvbi5lbGVtZW50fVwiOiAke2Vycm9yLm1lc3NhZ2V9YFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc3R5bGUubGF5b3V0ID09PSBcImJveGVzXCIpIHtcbiAgICAgIGxldCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gdHJ1ZTtcbiAgICAgIGxldCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgICAgICBpdGVtLnJhbmdlLFxuICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICApO1xuXG4gICAgICBjbGllbnRSZWN0cyA9IGNsaWVudFJlY3RzLnNvcnQoKHIxLCByMikgPT4ge1xuICAgICAgICBpZiAocjEudG9wIDwgcjIudG9wKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9IGVsc2UgaWYgKHIxLnRvcCA+IHIyLnRvcCkge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZm9yIChsZXQgY2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgICAgICBjb25zdCBsaW5lID0gZWxlbWVudFRlbXBsYXRlLmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgbGluZS5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgICAgcG9zaXRpb25FbGVtZW50KGxpbmUsIGNsaWVudFJlY3QsIGJvdW5kaW5nUmVjdCk7XG4gICAgICAgIGl0ZW1Db250YWluZXIuYXBwZW5kKGxpbmUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc3R5bGUubGF5b3V0ID09PSBcImJvdW5kc1wiKSB7XG4gICAgICBjb25zdCBib3VuZHMgPSBlbGVtZW50VGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgYm91bmRzLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgcG9zaXRpb25FbGVtZW50KGJvdW5kcywgYm91bmRpbmdSZWN0LCBib3VuZGluZ1JlY3QpO1xuXG4gICAgICBpdGVtQ29udGFpbmVyLmFwcGVuZChib3VuZHMpO1xuICAgIH1cblxuICAgIGdyb3VwQ29udGFpbmVyLmFwcGVuZChpdGVtQ29udGFpbmVyKTtcbiAgICBpdGVtLmNvbnRhaW5lciA9IGl0ZW1Db250YWluZXI7XG4gICAgaXRlbS5jbGlja2FibGVFbGVtZW50cyA9IEFycmF5LmZyb20oXG4gICAgICBpdGVtQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1hY3RpdmFibGU9JzEnXVwiKVxuICAgICk7XG4gICAgaWYgKGl0ZW0uY2xpY2thYmxlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gQXJyYXkuZnJvbShpdGVtQ29udGFpbmVyLmNoaWxkcmVuKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZ3JvdXAgY29udGFpbmVyIGVsZW1lbnQsIGFmdGVyIG1ha2luZyBzdXJlIGl0IGV4aXN0cy5cbiAgICovXG4gIGZ1bmN0aW9uIHJlcXVpcmVDb250YWluZXIoKSB7XG4gICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgZ3JvdXBJZCk7XG4gICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKFwiZGF0YS1ncm91cFwiLCBncm91cE5hbWUpO1xuICAgICAgY29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoY29udGFpbmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRhaW5lcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBncm91cCBjb250YWluZXIuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhckNvbnRhaW5lcigpIHtcbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIucmVtb3ZlKCk7XG4gICAgICBjb250YWluZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGFkZCwgcmVtb3ZlLCB1cGRhdGUsIGNsZWFyLCBpdGVtcywgcmVxdWVzdExheW91dCB9O1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBXaWxsIHJlbGF5b3V0IGFsbCB0aGUgZGVjb3JhdGlvbnMgd2hlbiB0aGUgZG9jdW1lbnQgYm9keSBpcyByZXNpemVkLlxuICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgIHZhciBsYXN0U2l6ZSA9IHsgd2lkdGg6IDAsIGhlaWdodDogMCB9O1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgbGFzdFNpemUud2lkdGggPT09IGJvZHkuY2xpZW50V2lkdGggJiZcbiAgICAgICAgbGFzdFNpemUuaGVpZ2h0ID09PSBib2R5LmNsaWVudEhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxhc3RTaXplID0ge1xuICAgICAgICB3aWR0aDogYm9keS5jbGllbnRXaWR0aCxcbiAgICAgICAgaGVpZ2h0OiBib2R5LmNsaWVudEhlaWdodCxcbiAgICAgIH07XG5cbiAgICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICBncm91cC5yZXF1ZXN0TGF5b3V0KCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGJvZHkpO1xuICB9LFxuICBmYWxzZVxuKTtcbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjIgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IGlzU2Nyb2xsTW9kZUVuYWJsZWQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgZ2V0Q3NzU2VsZWN0b3IgfSBmcm9tIFwiY3NzLXNlbGVjdG9yLWdlbmVyYXRvclwiO1xuXG4vLyBTZWUuIGh0dHBzOi8vZ2l0aHViLmNvbS9KYXlQYW5vei9hcmNoaXRlY3R1cmUvdHJlZS90b3VjaC1oYW5kbGluZy9taXNjL3RvdWNoLWhhbmRsaW5nXG5leHBvcnQgZnVuY3Rpb24gbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChlbGVtZW50KSB7XG4gIGlmIChlbGVtZW50ID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2YXIgaW50ZXJhY3RpdmVUYWdzID0gW1xuICAgIFwiYVwiLFxuICAgIFwiYXVkaW9cIixcbiAgICBcImJ1dHRvblwiLFxuICAgIFwiY2FudmFzXCIsXG4gICAgXCJkZXRhaWxzXCIsXG4gICAgXCJpbnB1dFwiLFxuICAgIFwibGFiZWxcIixcbiAgICBcIm9wdGlvblwiLFxuICAgIFwic2VsZWN0XCIsXG4gICAgXCJzdWJtaXRcIixcbiAgICBcInRleHRhcmVhXCIsXG4gICAgXCJ2aWRlb1wiLFxuICBdO1xuICBpZiAoaW50ZXJhY3RpdmVUYWdzLmluZGV4T2YoZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSAhPSAtMSkge1xuICAgIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgfVxuXG4gIC8vIENoZWNrcyB3aGV0aGVyIHRoZSBlbGVtZW50IGlzIGVkaXRhYmxlIGJ5IHRoZSB1c2VyLlxuICBpZiAoXG4gICAgZWxlbWVudC5oYXNBdHRyaWJ1dGUoXCJjb250ZW50ZWRpdGFibGVcIikgJiZcbiAgICBlbGVtZW50LmdldEF0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKS50b0xvd2VyQ2FzZSgpICE9IFwiZmFsc2VcIlxuICApIHtcbiAgICByZXR1cm4gZWxlbWVudC5vdXRlckhUTUw7XG4gIH1cblxuICAvLyBDaGVja3MgcGFyZW50cyByZWN1cnNpdmVseSBiZWNhdXNlIHRoZSB0b3VjaCBtaWdodCBiZSBmb3IgZXhhbXBsZSBvbiBhbiA8ZW0+IGluc2lkZSBhIDxhPi5cbiAgaWYgKGVsZW1lbnQucGFyZW50RWxlbWVudCkge1xuICAgIHJldHVybiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQucGFyZW50RWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRGaXJzdFZpc2libGVMb2NhdG9yKCkge1xuICBjb25zdCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gIHJldHVybiB7XG4gICAgaHJlZjogXCIjXCIsXG4gICAgdHlwZTogXCJhcHBsaWNhdGlvbi94aHRtbCt4bWxcIixcbiAgICBsb2NhdGlvbnM6IHtcbiAgICAgIGNzc1NlbGVjdG9yOiBnZXRDc3NTZWxlY3RvcihlbGVtZW50KSxcbiAgICB9LFxuICAgIHRleHQ6IHtcbiAgICAgIGhpZ2hsaWdodDogZWxlbWVudC50ZXh0Q29udGVudCxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBmaW5kRWxlbWVudChyb290RWxlbWVudCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJvb3RFbGVtZW50LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGQgPSByb290RWxlbWVudC5jaGlsZHJlbltpXTtcbiAgICBpZiAoIXNob3VsZElnbm9yZUVsZW1lbnQoY2hpbGQpICYmIGlzRWxlbWVudFZpc2libGUoY2hpbGQpKSB7XG4gICAgICByZXR1cm4gZmluZEVsZW1lbnQoY2hpbGQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcm9vdEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzRWxlbWVudFZpc2libGUoZWxlbWVudCkge1xuICBpZiAocmVhZGl1bS5pc0ZpeGVkTGF5b3V0KSByZXR1cm4gdHJ1ZTtcblxuICBpZiAoZWxlbWVudCA9PT0gZG9jdW1lbnQuYm9keSB8fCBlbGVtZW50ID09PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoIWRvY3VtZW50IHx8ICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgIWRvY3VtZW50LmJvZHkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHJldHVybiByZWN0LmJvdHRvbSA+IDAgJiYgcmVjdC50b3AgPCB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHJlY3QucmlnaHQgPiAwICYmIHJlY3QubGVmdCA8IHdpbmRvdy5pbm5lcldpZHRoO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNob3VsZElnbm9yZUVsZW1lbnQoZWxlbWVudCkge1xuICBjb25zdCBlbFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgaWYgKGVsU3R5bGUpIHtcbiAgICBjb25zdCBkaXNwbGF5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiZGlzcGxheVwiKTtcbiAgICBpZiAoZGlzcGxheSAhPSBcImJsb2NrXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDYW5ub3QgYmUgcmVsaWVkIHVwb24sIGJlY2F1c2Ugd2ViIGJyb3dzZXIgZW5naW5lIHJlcG9ydHMgaW52aXNpYmxlIHdoZW4gb3V0IG9mIHZpZXcgaW5cbiAgICAvLyBzY3JvbGxlZCBjb2x1bW5zIVxuICAgIC8vIGNvbnN0IHZpc2liaWxpdHkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJ2aXNpYmlsaXR5XCIpO1xuICAgIC8vIGlmICh2aXNpYmlsaXR5ID09PSBcImhpZGRlblwiKSB7XG4gICAgLy8gICAgIHJldHVybiBmYWxzZTtcbiAgICAvLyB9XG4gICAgY29uc3Qgb3BhY2l0eSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIm9wYWNpdHlcIik7XG4gICAgaWYgKG9wYWNpdHkgPT09IFwiMFwiKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcbmltcG9ydCB7IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQgfSBmcm9tIFwiLi9kb21cIjtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIG9uQ2xpY2ssIGZhbHNlKTtcbiAgYmluZERyYWdHZXN0dXJlKGRvY3VtZW50KTtcbn0pO1xuXG5mdW5jdGlvbiBvbkNsaWNrKGV2ZW50KSB7XG4gIGlmICghd2luZG93LmdldFNlbGVjdGlvbigpLmlzQ29sbGFwc2VkKSB7XG4gICAgLy8gVGhlcmUncyBhbiBvbi1nb2luZyBzZWxlY3Rpb24sIHRoZSB0YXAgd2lsbCBkaXNtaXNzIGl0IHNvIHdlIGRvbid0IGZvcndhcmQgaXQuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgbGV0IGNsaWNrRXZlbnQgPSB7XG4gICAgZGVmYXVsdFByZXZlbnRlZDogZXZlbnQuZGVmYXVsdFByZXZlbnRlZCxcbiAgICB4OiBldmVudC5jbGllbnRYICogcGl4ZWxSYXRpbyxcbiAgICB5OiBldmVudC5jbGllbnRZICogcGl4ZWxSYXRpbyxcbiAgICB0YXJnZXRFbGVtZW50OiBldmVudC50YXJnZXQub3V0ZXJIVE1MLFxuICAgIGludGVyYWN0aXZlRWxlbWVudDogbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChldmVudC50YXJnZXQpLFxuICB9O1xuXG4gIGlmIChoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudChldmVudCwgY2xpY2tFdmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBTZW5kIHRoZSB0YXAgZGF0YSBvdmVyIHRoZSBKUyBicmlkZ2UgZXZlbiBpZiBpdCdzIGJlZW4gaGFuZGxlZCB3aXRoaW4gdGhlIHdlYiB2aWV3LCBzbyB0aGF0XG4gIC8vIGl0IGNhbiBiZSBwcmVzZXJ2ZWQgYW5kIHVzZWQgYnkgdGhlIHRvb2xraXQgaWYgbmVlZGVkLlxuICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uVGFwKEpTT04uc3RyaW5naWZ5KGNsaWNrRXZlbnQpKTtcblxuICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJpbmREcmFnR2VzdHVyZShlbGVtZW50KSB7XG4gIC8vIHBhc3NpdmU6IGZhbHNlIGlzIG5lY2Vzc2FyeSB0byBiZSBhYmxlIHRvIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IuXG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIiwgb25TdGFydCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgb25FbmQsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCBvbk1vdmUsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG5cbiAgdmFyIHN0YXRlID0gdW5kZWZpbmVkO1xuICB2YXIgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgY29uc3QgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuXG4gIGZ1bmN0aW9uIG9uU3RhcnQoZXZlbnQpIHtcbiAgICBpc1N0YXJ0aW5nRHJhZyA9IHRydWU7XG5cbiAgICBjb25zdCBzdGFydFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIGNvbnN0IHN0YXJ0WSA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUgPSB7XG4gICAgICBkZWZhdWx0UHJldmVudGVkOiBldmVudC5kZWZhdWx0UHJldmVudGVkLFxuICAgICAgc3RhcnRYOiBzdGFydFgsXG4gICAgICBzdGFydFk6IHN0YXJ0WSxcbiAgICAgIGN1cnJlbnRYOiBzdGFydFgsXG4gICAgICBjdXJyZW50WTogc3RhcnRZLFxuICAgICAgb2Zmc2V0WDogMCxcbiAgICAgIG9mZnNldFk6IDAsXG4gICAgICBpbnRlcmFjdGl2ZUVsZW1lbnQ6IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSxcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gb25Nb3ZlKGV2ZW50KSB7XG4gICAgaWYgKCFzdGF0ZSkgcmV0dXJuO1xuXG4gICAgc3RhdGUuY3VycmVudFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlLmN1cnJlbnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZS5vZmZzZXRYID0gc3RhdGUuY3VycmVudFggLSBzdGF0ZS5zdGFydFg7XG4gICAgc3RhdGUub2Zmc2V0WSA9IHN0YXRlLmN1cnJlbnRZIC0gc3RhdGUuc3RhcnRZO1xuXG4gICAgdmFyIHNob3VsZFByZXZlbnREZWZhdWx0ID0gZmFsc2U7XG4gICAgLy8gV2FpdCBmb3IgYSBtb3ZlbWVudCBvZiBhdCBsZWFzdCA2IHBpeGVscyBiZWZvcmUgcmVwb3J0aW5nIGEgZHJhZy5cbiAgICBpZiAoaXNTdGFydGluZ0RyYWcpIHtcbiAgICAgIGlmIChNYXRoLmFicyhzdGF0ZS5vZmZzZXRYKSA+PSA2IHx8IE1hdGguYWJzKHN0YXRlLm9mZnNldFkpID49IDYpIHtcbiAgICAgICAgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgICAgICAgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ1N0YXJ0KEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdNb3ZlKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25FbmQoZXZlbnQpIHtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG5cbiAgICBjb25zdCBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnRW5kKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHN0YXRlID0gdW5kZWZpbmVkO1xuICB9XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIzIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50IH0gZnJvbSBcIi4vZG9tXCI7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCAoZXZlbnQpID0+IHtcbiAgaWYgKHNob3VsZElnbm9yZUV2ZW50KGV2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcbiAgc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgXCJkb3duXCIpO1xufSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5dXBcIiwgKGV2ZW50KSA9PiB7XG4gIGlmIChzaG91bGRJZ25vcmVFdmVudChldmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwcmV2ZW50RGVmYXVsdChldmVudCk7XG4gIHNlbmRQcmVzc0tleU1lc3NhZ2UoZXZlbnQsIFwidXBcIik7XG59KTtcblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlRXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIChcbiAgICBldmVudC5kZWZhdWx0UHJldmVudGVkIHx8XG4gICAgbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChkb2N1bWVudC5hY3RpdmVFbGVtZW50KSAhPSBudWxsXG4gICk7XG59XG5cbi8vIFdlIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIGtleWJvYXJkIGV2ZW50cywgb3RoZXJ3aXNlIHRoZSB3ZWIgdmlld1xuLy8gbWlnaHQgc2Nyb2xsLlxuZnVuY3Rpb24gcHJldmVudERlZmF1bHQoZXZlbnQpIHtcbiAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59XG5cbmZ1bmN0aW9uIHNlbmRQcmVzc0tleU1lc3NhZ2UoZXZlbnQsIHR5cGUpIHtcbiAgaWYgKGV2ZW50LnJlcGVhdCkgcmV0dXJuO1xuXG4gIGxldCBrZXlFdmVudCA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGNvZGU6IGV2ZW50LmNvZGUsXG4gICAgY2hhcmFjdGVyczogU3RyaW5nLmZyb21DaGFyQ29kZShldmVudC5rZXlDb2RlKSxcbiAgICBhbHQ6IGV2ZW50LmFsdEtleSxcbiAgICBjb250cm9sOiBldmVudC5jdHJsS2V5LFxuICAgIHNoaWZ0OiBldmVudC5zaGlmdEtleSxcbiAgICBtZXRhOiBldmVudC5tZXRhS2V5LFxuICB9O1xuXG4gIEFuZHJvaWQub25LZXkoSlNPTi5zdHJpbmdpZnkoa2V5RXZlbnQpKTtcbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlICovXG4vL1xuLy8gIGhpZ2hsaWdodC5qc1xuLy8gIHIyLW5hdmlnYXRvci1rb3RsaW5cbi8vXG4vLyAgT3JnYW5pemVkIGJ5IFRhZWh5dW4gS2ltIG9uIDYvMjcvMTkgZnJvbSByMi1uYXZpZ2F0b3ItanMuXG4vL1xuLy8gIENvcHlyaWdodCAyMDE5IFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHdoaWNoIGlzIGRldGFpbGVkXG4vLyAgaW4gdGhlIExJQ0VOU0UgZmlsZSBwcmVzZW50IGluIHRoZSBwcm9qZWN0IHJlcG9zaXRvcnkgd2hlcmUgdGhpcyBzb3VyY2UgY29kZSBpcyBtYWludGFpbmVkLlxuLy9cblxuY29uc3QgUk9PVF9DTEFTU19SRURVQ0VfTU9USU9OID0gXCJyMi1yZWR1Y2UtbW90aW9uXCI7XG5jb25zdCBST09UX0NMQVNTX05PX0ZPT1ROT1RFUyA9IFwicjItbm8tcG9wdXAtZm9vbm90ZXNcIjtcbmNvbnN0IFBPUFVQX0RJQUxPR19DTEFTUyA9IFwicjItcG9wdXAtZGlhbG9nXCI7XG5jb25zdCBGT09UTk9URVNfQ09OVEFJTkVSX0NMQVNTID0gXCJyMi1mb290bm90ZS1jb250YWluZXJcIjtcbmNvbnN0IEZPT1ROT1RFU19DTE9TRV9CVVRUT05fQ0xBU1MgPSBcInIyLWZvb3Rub3RlLWNsb3NlXCI7XG5jb25zdCBGT09UTk9URV9GT1JDRV9TSE9XID0gXCJyMi1mb290bm90ZS1mb3JjZS1zaG93XCI7XG5jb25zdCBUVFNfSURfUFJFVklPVVMgPSBcInIyLXR0cy1wcmV2aW91c1wiO1xuY29uc3QgVFRTX0lEX05FWFQgPSBcInIyLXR0cy1uZXh0XCI7XG5jb25zdCBUVFNfSURfU0xJREVSID0gXCJyMi10dHMtc2xpZGVyXCI7XG5jb25zdCBUVFNfSURfQUNUSVZFX1dPUkQgPSBcInIyLXR0cy1hY3RpdmUtd29yZFwiO1xuY29uc3QgVFRTX0lEX0NPTlRBSU5FUiA9IFwicjItdHRzLXR4dFwiO1xuY29uc3QgVFRTX0lEX0lORk8gPSBcInIyLXR0cy1pbmZvXCI7XG5jb25zdCBUVFNfTkFWX0JVVFRPTl9DTEFTUyA9IFwicjItdHRzLWJ1dHRvblwiO1xuY29uc3QgVFRTX0lEX1NQRUFLSU5HX0RPQ19FTEVNRU5UID0gXCJyMi10dHMtc3BlYWtpbmctZWxcIjtcbmNvbnN0IFRUU19DTEFTU19JTkpFQ1RFRF9TUEFOID0gXCJyMi10dHMtc3BlYWtpbmctdHh0XCI7XG5jb25zdCBUVFNfQ0xBU1NfSU5KRUNURURfU1VCU1BBTiA9IFwicjItdHRzLXNwZWFraW5nLXdvcmRcIjtcbmNvbnN0IFRUU19JRF9JTkpFQ1RFRF9QQVJFTlQgPSBcInIyLXR0cy1zcGVha2luZy10eHQtcGFyZW50XCI7XG5jb25zdCBJRF9ISUdITElHSFRTX0NPTlRBSU5FUiA9IFwiUjJfSURfSElHSExJR0hUU19DT05UQUlORVJcIjtcbmNvbnN0IElEX0FOTk9UQVRJT05fQ09OVEFJTkVSID0gXCJSMl9JRF9BTk5PVEFUSU9OX0NPTlRBSU5FUlwiO1xuY29uc3QgQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUiA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUlwiO1xuY29uc3QgQ0xBU1NfQU5OT1RBVElPTl9DT05UQUlORVIgPSBcIlIyX0NMQVNTX0FOTk9UQVRJT05fQ09OVEFJTkVSXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQVJFQSA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0FSRUFcIjtcbmNvbnN0IENMQVNTX0FOTk9UQVRJT05fQVJFQSA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9BUkVBXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSA9IFwiUjJfQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUFcIjtcbmNvbnN0IENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQSA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBXCI7XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG5jb25zdCBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSA9IFtcbiAgUE9QVVBfRElBTE9HX0NMQVNTLFxuICBUVFNfQ0xBU1NfSU5KRUNURURfU1BBTixcbiAgVFRTX0NMQVNTX0lOSkVDVEVEX1NVQlNQQU4sXG4gIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSLFxuICBDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSLFxuICBDTEFTU19ISUdITElHSFRfQVJFQSxcbiAgQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEsXG4gIFwicmVzaXplLXNlbnNvclwiLFxuXTtcbmNvbnN0IENMQVNTX1BBR0lOQVRFRCA9IFwicjItY3NzLXBhZ2luYXRlZFwiO1xuXG4vL2NvbnN0IElTX0RFViA9IChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJkZXZlbG9wbWVudFwiIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcImRldlwiKTtcbmNvbnN0IElTX0RFViA9IGZhbHNlO1xuY29uc3QgX2hpZ2hsaWdodHMgPSBbXTtcblxubGV0IF9oaWdobGlnaHRzQ29udGFpbmVyO1xubGV0IF9hbm5vdGF0aW9uQ29udGFpbmVyO1xubGV0IGxhc3RNb3VzZURvd25YID0gLTE7XG5sZXQgbGFzdE1vdXNlRG93blkgPSAtMTtcbmxldCBib2R5RXZlbnRMaXN0ZW5lcnNTZXQgPSBmYWxzZTtcblxuY29uc3QgVVNFX1NWRyA9IGZhbHNlO1xuY29uc3QgREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkgPSAwLjM7XG5jb25zdCBBTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZID0gMC40NTtcblxuLy9jb25zdCBERUJVR19WSVNVQUxTID0gZmFsc2U7XG5jb25zdCBERUJVR19WSVNVQUxTID0gZmFsc2U7XG5jb25zdCBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IgPSB7XG4gIGJsdWU6IDEwMCxcbiAgZ3JlZW46IDUwLFxuICByZWQ6IDIzMCxcbn07XG5cbmNvbnN0IEFOTk9UQVRJT05fV0lEVEggPSAxNTtcblxuZnVuY3Rpb24gcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKF93aW4sIGhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gIGlmIChcbiAgICBoaWdobGlnaHRCb3VuZGluZy5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSA9PSBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcbiAgKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLm91dGxpbmUgPSBcIm5vbmVcIjtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCIsXG4gICAgXCJ0cmFuc3BhcmVudFwiLFxuICAgIFwiaW1wb3J0YW50XCJcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYXMsIGhpZ2hsaWdodCkge1xuICBjb25zdCB1c2VTVkcgPSAhREVCVUdfVklTVUFMUyAmJiBVU0VfU1ZHO1xuICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgaGlnaGxpZ2h0QXJlYXMpIHtcbiAgICBjb25zdCBpc1NWRyA9IHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhLm5hbWVzcGFjZVVSSSA9PT0gU1ZHX1hNTF9OQU1FU1BBQ0U7XG4gICAgY29uc3Qgb3BhY2l0eSA9IEFMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFk7XG4gICAgaWYgKGlzU1ZHKSB7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImZpbGxcIixcbiAgICAgICAgYHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImZpbGwtb3BhY2l0eVwiLFxuICAgICAgICBgJHtvcGFjaXR5fWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcInN0cm9rZVwiLFxuICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwic3Ryb2tlLW9wYWNpdHlcIixcbiAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIixcbiAgICAgICAgYHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSlgLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpIHtcbiAgY29uc3QgdXNlU1ZHID0gIURFQlVHX1ZJU1VBTFMgJiYgVVNFX1NWRztcbiAgLy9jb25zdCB1c2VTVkcgPSBVU0VfU1ZHO1xuICBjb25zdCBpc1NWRyA9IHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhLm5hbWVzcGFjZVVSSSA9PT0gU1ZHX1hNTF9OQU1FU1BBQ0U7XG4gIGNvbnN0IGlkID0gaXNTVkdcbiAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlXG4gICAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZShcImlkXCIpXG4gICAgICA6IHVuZGVmaW5lZFxuICAgIDogaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlXG4gICAgPyBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKFwiaWRcIilcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKGlkKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCkgPT4ge1xuICAgICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICAgIH0pO1xuICAgIGlmIChoaWdobGlnaHQpIHtcbiAgICAgIGNvbnN0IG9wYWNpdHkgPSBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWTtcbiAgICAgIGlmIChpc1NWRykge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiZmlsbFwiLFxuICAgICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcImZpbGwtb3BhY2l0eVwiLFxuICAgICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJzdHJva2VcIixcbiAgICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiLFxuICAgICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiLFxuICAgICAgICAgIGByZ2JhKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0sICR7b3BhY2l0eX0pYCxcbiAgICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwcm9jZXNzVG91Y2hFdmVudCh3aW4sIGV2KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHggPSBldi5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRYO1xuICBjb25zdCB5ID0gZXYuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WTtcbiAgaWYgKCFfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBwYWdpbmF0ZWQgPSBpc1BhZ2luYXRlZChkb2N1bWVudCk7XG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgbGV0IHhPZmZzZXQ7XG4gIGxldCB5T2Zmc2V0O1xuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0IDogYm9keVJlY3QubGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiBib2R5UmVjdC50b3A7XG4gIH1cbiAgbGV0IGZvdW5kSGlnaGxpZ2h0O1xuICBsZXQgZm91bmRFbGVtZW50O1xuICBsZXQgZm91bmRSZWN0O1xuICAvLyAgICBfaGlnaGxpZ2h0cy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgLy8gICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGEuc2VsZWN0aW9uSW5mbykpXG4gIC8vICAgICAgICByZXR1cm4gYS5zZWxlY3Rpb25JbmZvLmNsZWFuVGV4dC5sZW5ndGggPCBiLnNlbGVjdGlvbkluZm8uY2xlYW5UZXh0Lmxlbmd0aFxuICAvLyAgICB9KVxuICBmb3IgKGxldCBpID0gX2hpZ2hsaWdodHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0c1tpXTtcbiAgICBsZXQgaGlnaGxpZ2h0UGFyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYCR7aGlnaGxpZ2h0LmlkfWApO1xuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBoaWdobGlnaHRQYXJlbnQgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGAjJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgfVxuICAgIGlmICghaGlnaGxpZ2h0UGFyZW50KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbGV0IGhpdCA9IGZhbHNlO1xuICAgIGNvbnN0IGhpZ2hsaWdodEZyYWdtZW50cyA9IGhpZ2hsaWdodFBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnQgb2YgaGlnaGxpZ2h0RnJhZ21lbnRzKSB7XG4gICAgICBjb25zdCB3aXRoUmVjdCA9IGhpZ2hsaWdodEZyYWdtZW50O1xuICAgICAgY29uc3QgbGVmdCA9IHdpdGhSZWN0LnJlY3QubGVmdCArIHhPZmZzZXQ7XG4gICAgICBjb25zdCB0b3AgPSB3aXRoUmVjdC5yZWN0LnRvcCArIHlPZmZzZXQ7XG4gICAgICBmb3VuZFJlY3QgPSB3aXRoUmVjdC5yZWN0O1xuICAgICAgaWYgKFxuICAgICAgICB4ID49IGxlZnQgJiZcbiAgICAgICAgeCA8IGxlZnQgKyB3aXRoUmVjdC5yZWN0LndpZHRoICYmXG4gICAgICAgIHkgPj0gdG9wICYmXG4gICAgICAgIHkgPCB0b3AgKyB3aXRoUmVjdC5yZWN0LmhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIGhpdCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaGl0KSB7XG4gICAgICBmb3VuZEhpZ2hsaWdodCA9IGhpZ2hsaWdodDtcbiAgICAgIGZvdW5kRWxlbWVudCA9IGhpZ2hsaWdodFBhcmVudDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoIWZvdW5kSGlnaGxpZ2h0IHx8ICFmb3VuZEVsZW1lbnQpIHtcbiAgICBjb25zdCBoaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgaGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgfVxuICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmb3VuZEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jbGlja1wiKSkge1xuICAgIGlmIChldi50eXBlID09PSBcIm1vdXNlbW92ZVwiKSB7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICAgIGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLmluZGV4T2YoaGlnaGxpZ2h0QXJlYSkgPCAwKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMsIGZvdW5kSGlnaGxpZ2h0KTtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nID0gZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGFsbEhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIHx8XG4gICAgICAgICAgaGlnaGxpZ2h0Qm91bmRpbmcgIT09IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nXG4gICAgICAgICkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gICAgICAgIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgICAgICAgc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZShcbiAgICAgICAgICAgIHdpbixcbiAgICAgICAgICAgIGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nLFxuICAgICAgICAgICAgZm91bmRIaWdobGlnaHRcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChldi50eXBlID09PSBcInRvdWNoc3RhcnRcIiB8fCBldi50eXBlID09PSBcInRvdWNoZW5kXCIpIHtcbiAgICAgIGNvbnN0IHNpemUgPSB7XG4gICAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cub3V0ZXJIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGZvdW5kUmVjdC5sZWZ0LFxuICAgICAgICB3aWR0aDogZm91bmRSZWN0LndpZHRoLFxuICAgICAgICB0b3A6IGZvdW5kUmVjdC50b3AsXG4gICAgICAgIGhlaWdodDogZm91bmRSZWN0LmhlaWdodCxcbiAgICAgIH07XG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBoaWdobGlnaHQ6IGZvdW5kSGlnaGxpZ2h0LmlkLFxuICAgICAgICBzaXplOiBzaXplLFxuICAgICAgfTtcblxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgIHR5cGVvZiB3aW5kb3cucHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICB3aW5kb3cucHJvY2Vzcy50eXBlID09PSBcInJlbmRlcmVyXCJcbiAgICAgICkge1xuICAgICAgICBlbGVjdHJvbl8xLmlwY1JlbmRlcmVyLnNlbmRUb0hvc3QoUjJfRVZFTlRfSElHSExJR0hUX0NMSUNLLCBwYXlsb2FkKTtcbiAgICAgIH0gZWxzZSBpZiAod2luZG93LndlYmtpdFVSTCkge1xuICAgICAgICBjb25zb2xlLmxvZyhmb3VuZEhpZ2hsaWdodC5pZC5pbmNsdWRlcyhcIlIyX0FOTk9UQVRJT05fXCIpKTtcbiAgICAgICAgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0FOTk9UQVRJT05fXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfSElHSExJR0hUX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHggPSBldi5jbGllbnRYO1xuICBjb25zdCB5ID0gZXYuY2xpZW50WTtcbiAgaWYgKCFfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeE9mZnNldDtcbiAgbGV0IHlPZmZzZXQ7XG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBib2R5UmVjdC5sZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICBsZXQgZm91bmRIaWdobGlnaHQ7XG4gIGxldCBmb3VuZEVsZW1lbnQ7XG4gIGxldCBmb3VuZFJlY3Q7XG4gIGZvciAobGV0IGkgPSBfaGlnaGxpZ2h0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzW2ldO1xuICAgIGxldCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGhpZ2hsaWdodFBhcmVudCA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYCMke2hpZ2hsaWdodC5pZH1gKTtcbiAgICB9XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBsZXQgaGl0ID0gZmFsc2U7XG4gICAgY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnRzID0gaGlnaGxpZ2h0UGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRGcmFnbWVudCBvZiBoaWdobGlnaHRGcmFnbWVudHMpIHtcbiAgICAgIGNvbnN0IHdpdGhSZWN0ID0gaGlnaGxpZ2h0RnJhZ21lbnQ7XG4gICAgICBjb25zdCBsZWZ0ID0gd2l0aFJlY3QucmVjdC5sZWZ0ICsgeE9mZnNldDtcbiAgICAgIGNvbnN0IHRvcCA9IHdpdGhSZWN0LnJlY3QudG9wICsgeU9mZnNldDtcbiAgICAgIGZvdW5kUmVjdCA9IHdpdGhSZWN0LnJlY3Q7XG4gICAgICBpZiAoXG4gICAgICAgIHggPj0gbGVmdCAmJlxuICAgICAgICB4IDwgbGVmdCArIHdpdGhSZWN0LnJlY3Qud2lkdGggJiZcbiAgICAgICAgeSA+PSB0b3AgJiZcbiAgICAgICAgeSA8IHRvcCArIHdpdGhSZWN0LnJlY3QuaGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgaGl0ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChoaXQpIHtcbiAgICAgIGZvdW5kSGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgZm91bmRFbGVtZW50ID0gaGlnaGxpZ2h0UGFyZW50O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFmb3VuZEhpZ2hsaWdodCB8fCAhZm91bmRFbGVtZW50KSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKHdpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICAgIH1cbiAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoZm91bmRFbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtY2xpY2tcIikpIHtcbiAgICBpZiAoZXYudHlwZSA9PT0gXCJtb3VzZW1vdmVcIikge1xuICAgICAgY29uc3QgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBmb3VuZEVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YClcbiAgICAgICk7XG4gICAgICBjb25zdCBhbGxIaWdobGlnaHRBcmVhcyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRBcmVhIG9mIGFsbEhpZ2hsaWdodEFyZWFzKSB7XG4gICAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcy5pbmRleE9mKGhpZ2hsaWdodEFyZWEpIDwgMCkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLCBmb3VuZEhpZ2hsaWdodCk7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyA9IGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEJvdW5kaW5ncyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBoaWdobGlnaHRCb3VuZGluZyBvZiBhbGxIaWdobGlnaHRCb3VuZGluZ3MpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyB8fFxuICAgICAgICAgIGhpZ2hsaWdodEJvdW5kaW5nICE9PSBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZ1xuICAgICAgICApIHtcbiAgICAgICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZykge1xuICAgICAgICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgICAgICAgIHNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUoXG4gICAgICAgICAgICB3aW4sXG4gICAgICAgICAgICBmb3VuZEVsZW1lbnRIaWdobGlnaHRCb3VuZGluZyxcbiAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXYudHlwZSA9PT0gXCJtb3VzZXVwXCIgfHwgZXYudHlwZSA9PT0gXCJ0b3VjaGVuZFwiKSB7XG4gICAgICBjb25zdCB0b3VjaGVkUG9zaXRpb24gPSB7XG4gICAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICAgIGxlZnQ6IGZvdW5kUmVjdC5sZWZ0LFxuICAgICAgICB3aWR0aDogZm91bmRSZWN0LndpZHRoLFxuICAgICAgICB0b3A6IGZvdW5kUmVjdC50b3AsXG4gICAgICAgIGhlaWdodDogZm91bmRSZWN0LmhlaWdodCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGhpZ2hsaWdodDogZm91bmRIaWdobGlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB0b3VjaGVkUG9zaXRpb24sXG4gICAgICB9O1xuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIHdpbmRvdy5wcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHdpbmRvdy5wcm9jZXNzLnR5cGUgPT09IFwicmVuZGVyZXJcIlxuICAgICAgKSB7XG4gICAgICAgIGVsZWN0cm9uXzEuaXBjUmVuZGVyZXIuc2VuZFRvSG9zdChSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0ssIHBheWxvYWQpO1xuICAgICAgfSBlbHNlIGlmICh3aW5kb3cud2Via2l0VVJMKSB7XG4gICAgICAgIGlmIChmb3VuZEhpZ2hsaWdodC5pZC5zZWFyY2goXCJSMl9BTk5PVEFUSU9OX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQoZm91bmRIaWdobGlnaHQuaWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgICAgICAgICAgd2Via2l0Lm1lc3NhZ2VIYW5kbGVycy5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0hJR0hMSUdIVF9cIikgPj0gMCkge1xuICAgICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgICAgICAgICBBbmRyb2lkLmhpZ2hsaWdodEFjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFjdGl2YXRlZC5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgZm91bmRIaWdobGlnaHQuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QxLmxlZnQgPCByZWN0Mi5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIubGVmdCA8IHJlY3QxLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIubGVmdCwgcmVjdDEucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0MS50b3AgPCByZWN0Mi5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLnRvcCA8IHJlY3QxLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLnRvcCwgcmVjdDEuYm90dG9tLCB0b2xlcmFuY2UpKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhyZWN0cykge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIC0xKSkge1xuICAgICAgICBsZXQgdG9BZGQgPSBbXTtcbiAgICAgICAgbGV0IHRvUmVtb3ZlO1xuICAgICAgICBsZXQgdG9QcmVzZXJ2ZTtcbiAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czEgPSByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICB0b1ByZXNlcnZlID0gcmVjdDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czIgPSByZWN0U3VidHJhY3QocmVjdDIsIHJlY3QxKTtcbiAgICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoIDwgc3VidHJhY3RSZWN0czIubGVuZ3RoKSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICAgIHRvUHJlc2VydmUgPSByZWN0MjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMjtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDI7XG4gICAgICAgICAgICB0b1ByZXNlcnZlID0gcmVjdDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zdCB0b0NoZWNrID0gW107XG4gICAgICAgICAgdG9DaGVjay5wdXNoKHRvUHJlc2VydmUpO1xuICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRvQ2hlY2ssIHRvQWRkKTtcbiAgICAgICAgICBjaGVja092ZXJsYXBzKHRvQ2hlY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGBDTElFTlQgUkVDVDogb3ZlcmxhcCwgY3V0IG9uZSByZWN0IGludG8gJHt0b0FkZC5sZW5ndGh9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gdG9SZW1vdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShuZXdSZWN0cywgdG9BZGQpO1xuICAgICAgICByZXR1cm4gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhuZXdSZWN0cyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gY2hlY2tPdmVybGFwcyhyZWN0cykge1xuICBjb25zdCBzdGlsbE92ZXJsYXBpbmdSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJlY3QxIG9mIHJlY3RzKSB7XG4gICAgZm9yIChjb25zdCByZWN0MiBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhhczEgPSBzdGlsbE92ZXJsYXBpbmdSZWN0cy5pbmRleE9mKHJlY3QxKSA+PSAwO1xuICAgICAgY29uc3QgaGFzMiA9IHN0aWxsT3ZlcmxhcGluZ1JlY3RzLmluZGV4T2YocmVjdDIpID49IDA7XG4gICAgICBpZiAoIWhhczEgfHwgIWhhczIpIHtcbiAgICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgICBpZiAoIWhhczEpIHtcbiAgICAgICAgICAgIHN0aWxsT3ZlcmxhcGluZ1JlY3RzLnB1c2gocmVjdDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWhhczIpIHtcbiAgICAgICAgICAgIHN0aWxsT3ZlcmxhcGluZ1JlY3RzLnB1c2gocmVjdDIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiBvdmVybGFwIC0tLVwiKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAjMSBUT1A6JHtyZWN0MS50b3B9IEJPVFRPTToke3JlY3QxLmJvdHRvbX0gTEVGVDoke3JlY3QxLmxlZnR9IFJJR0hUOiR7cmVjdDEucmlnaHR9IFdJRFRIOiR7cmVjdDEud2lkdGh9IEhFSUdIVDoke3JlY3QxLmhlaWdodH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAjMiBUT1A6JHtyZWN0Mi50b3B9IEJPVFRPTToke3JlY3QyLmJvdHRvbX0gTEVGVDoke3JlY3QyLmxlZnR9IFJJR0hUOiR7cmVjdDIucmlnaHR9IFdJRFRIOiR7cmVjdDIud2lkdGh9IEhFSUdIVDoke3JlY3QyLmhlaWdodH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCB4T3ZlcmxhcCA9IGdldFJlY3RPdmVybGFwWChyZWN0MSwgcmVjdDIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGB4T3ZlcmxhcDogJHt4T3ZlcmxhcH1gKTtcbiAgICAgICAgICBjb25zdCB5T3ZlcmxhcCA9IGdldFJlY3RPdmVybGFwWShyZWN0MSwgcmVjdDIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGB5T3ZlcmxhcDogJHt5T3ZlcmxhcH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoc3RpbGxPdmVybGFwaW5nUmVjdHMubGVuZ3RoKSB7XG4gICAgY29uc29sZS5sb2coYENMSUVOVCBSRUNUOiBvdmVybGFwcyAke3N0aWxsT3ZlcmxhcGluZ1JlY3RzLmxlbmd0aH1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVDb250YWluZWRSZWN0cyhyZWN0cywgdG9sZXJhbmNlKSB7XG4gIGNvbnN0IHJlY3RzVG9LZWVwID0gbmV3IFNldChyZWN0cyk7XG4gIGZvciAoY29uc3QgcmVjdCBvZiByZWN0cykge1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggPiAxICYmIHJlY3QuaGVpZ2h0ID4gMTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgdGlueVwiKTtcbiAgICAgIH1cbiAgICAgIHJlY3RzVG9LZWVwLmRlbGV0ZShyZWN0KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHBvc3NpYmx5Q29udGFpbmluZ1JlY3Qgb2YgcmVjdHMpIHtcbiAgICAgIGlmIChyZWN0ID09PSBwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFyZWN0c1RvS2VlcC5oYXMocG9zc2libHlDb250YWluaW5nUmVjdCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocmVjdENvbnRhaW5zKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QsIHJlY3QsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBjb250YWluZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20ocmVjdHNUb0tlZXApO1xufVxuXG5mdW5jdGlvbiBhbG1vc3RFcXVhbChhLCBiLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8PSB0b2xlcmFuY2U7XG59XG5cbmZ1bmN0aW9uIHJlY3RJbnRlcnNlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IG1heExlZnQgPSBNYXRoLm1heChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgbWluUmlnaHQgPSBNYXRoLm1pbihyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCBtYXhUb3AgPSBNYXRoLm1heChyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IG1pbkJvdHRvbSA9IE1hdGgubWluKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgY29uc3QgcmVjdCA9IHtcbiAgICBib3R0b206IG1pbkJvdHRvbSxcbiAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIG1pbkJvdHRvbSAtIG1heFRvcCksXG4gICAgbGVmdDogbWF4TGVmdCxcbiAgICByaWdodDogbWluUmlnaHQsXG4gICAgdG9wOiBtYXhUb3AsXG4gICAgd2lkdGg6IE1hdGgubWF4KDAsIG1pblJpZ2h0IC0gbWF4TGVmdCksXG4gIH07XG4gIHJldHVybiByZWN0O1xufVxuXG5mdW5jdGlvbiByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IHJlY3RJbnRlcnNlY3RlZCA9IHJlY3RJbnRlcnNlY3QocmVjdDIsIHJlY3QxKTtcbiAgaWYgKHJlY3RJbnRlcnNlY3RlZC5oZWlnaHQgPT09IDAgfHwgcmVjdEludGVyc2VjdGVkLndpZHRoID09PSAwKSB7XG4gICAgcmV0dXJuIFtyZWN0MV07XG4gIH1cbiAgY29uc3QgcmVjdHMgPSBbXTtcbiAge1xuICAgIGNvbnN0IHJlY3RBID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0MS5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RBLndpZHRoID0gcmVjdEEucmlnaHQgLSByZWN0QS5sZWZ0O1xuICAgIHJlY3RBLmhlaWdodCA9IHJlY3RBLmJvdHRvbSAtIHJlY3RBLnRvcDtcbiAgICBpZiAocmVjdEEuaGVpZ2h0ICE9PSAwICYmIHJlY3RBLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RBKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RCID0ge1xuICAgICAgYm90dG9tOiByZWN0SW50ZXJzZWN0ZWQudG9wLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RCLndpZHRoID0gcmVjdEIucmlnaHQgLSByZWN0Qi5sZWZ0O1xuICAgIHJlY3RCLmhlaWdodCA9IHJlY3RCLmJvdHRvbSAtIHJlY3RCLnRvcDtcbiAgICBpZiAocmVjdEIuaGVpZ2h0ICE9PSAwICYmIHJlY3RCLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RCKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RDID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3RJbnRlcnNlY3RlZC5ib3R0b20sXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RDLndpZHRoID0gcmVjdEMucmlnaHQgLSByZWN0Qy5sZWZ0O1xuICAgIHJlY3RDLmhlaWdodCA9IHJlY3RDLmJvdHRvbSAtIHJlY3RDLnRvcDtcbiAgICBpZiAocmVjdEMuaGVpZ2h0ICE9PSAwICYmIHJlY3RDLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RDKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3REID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICByaWdodDogcmVjdDEucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEQud2lkdGggPSByZWN0RC5yaWdodCAtIHJlY3RELmxlZnQ7XG4gICAgcmVjdEQuaGVpZ2h0ID0gcmVjdEQuYm90dG9tIC0gcmVjdEQudG9wO1xuICAgIGlmIChyZWN0RC5oZWlnaHQgIT09IDAgJiYgcmVjdEQud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWluc1BvaW50KHJlY3QsIHgsIHksIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0LmxlZnQgPCB4IHx8IGFsbW9zdEVxdWFsKHJlY3QubGVmdCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5yaWdodCA+IHggfHwgYWxtb3N0RXF1YWwocmVjdC5yaWdodCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC50b3AgPCB5IHx8IGFsbW9zdEVxdWFsKHJlY3QudG9wLCB5LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LmJvdHRvbSA+IHkgfHwgYWxtb3N0RXF1YWwocmVjdC5ib3R0b20sIHksIHRvbGVyYW5jZSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWlucyhyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKVxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IGxlZnQgPSBNYXRoLm1pbihyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgcmlnaHQgPSBNYXRoLm1heChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCB0b3AgPSBNYXRoLm1pbihyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IGJvdHRvbSA9IE1hdGgubWF4KHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgcmV0dXJuIHtcbiAgICBib3R0b20sXG4gICAgaGVpZ2h0OiBib3R0b20gLSB0b3AsXG4gICAgbGVmdCxcbiAgICByaWdodCxcbiAgICB0b3AsXG4gICAgd2lkdGg6IHJpZ2h0IC0gbGVmdCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICByZWN0cyxcbiAgdG9sZXJhbmNlLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwibWVyZ2VUb3VjaGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0c0xpbmVVcFZlcnRpY2FsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIubGVmdCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCBob3Jpem9udGFsQWxsb3dlZCA9ICFkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzO1xuICAgICAgY29uc3QgYWxpZ25lZCA9XG4gICAgICAgIChyZWN0c0xpbmVVcEhvcml6b250YWxseSAmJiBob3Jpem9udGFsQWxsb3dlZCkgfHxcbiAgICAgICAgKHJlY3RzTGluZVVwVmVydGljYWxseSAmJiAhcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkpO1xuICAgICAgY29uc3QgY2FuTWVyZ2UgPSBhbGlnbmVkICYmIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpO1xuICAgICAgaWYgKGNhbk1lcmdlKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGBDTElFTlQgUkVDVDogbWVyZ2luZyB0d28gaW50byBvbmUsIFZFUlRJQ0FMOiAke3JlY3RzTGluZVVwVmVydGljYWxseX0gSE9SSVpPTlRBTDogJHtyZWN0c0xpbmVVcEhvcml6b250YWxseX0gKCR7ZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c30pYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gcmVjdDEgJiYgcmVjdCAhPT0gcmVjdDI7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXBsYWNlbWVudENsaWVudFJlY3QgPSBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgbmV3UmVjdHMucHVzaChyZXBsYWNlbWVudENsaWVudFJlY3QpO1xuICAgICAgICByZXR1cm4gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgICAgICAgIG5ld1JlY3RzLFxuICAgICAgICAgIHRvbGVyYW5jZSxcbiAgICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAocmFuZ2UsIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMpIHtcbiAgY29uc3QgcmFuZ2VDbGllbnRSZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG4gIHJldHVybiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcF8oXG4gICAgcmFuZ2VDbGllbnRSZWN0cyxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwXyhcbiAgY2xpZW50UmVjdHMsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBjb25zdCB0b2xlcmFuY2UgPSAxO1xuICBjb25zdCBvcmlnaW5hbFJlY3RzID0gW107XG4gIGZvciAoY29uc3QgcmFuZ2VDbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgb3JpZ2luYWxSZWN0cy5wdXNoKHtcbiAgICAgIGJvdHRvbTogcmFuZ2VDbGllbnRSZWN0LmJvdHRvbSxcbiAgICAgIGhlaWdodDogcmFuZ2VDbGllbnRSZWN0LmhlaWdodCxcbiAgICAgIGxlZnQ6IHJhbmdlQ2xpZW50UmVjdC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5yaWdodCxcbiAgICAgIHRvcDogcmFuZ2VDbGllbnRSZWN0LnRvcCxcbiAgICAgIHdpZHRoOiByYW5nZUNsaWVudFJlY3Qud2lkdGgsXG4gICAgfSk7XG4gIH1cbiAgY29uc3QgbWVyZ2VkUmVjdHMgPSBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gICAgb3JpZ2luYWxSZWN0cyxcbiAgICB0b2xlcmFuY2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICBjb25zdCBub0NvbnRhaW5lZFJlY3RzID0gcmVtb3ZlQ29udGFpbmVkUmVjdHMobWVyZ2VkUmVjdHMsIHRvbGVyYW5jZSk7XG4gIGNvbnN0IG5ld1JlY3RzID0gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhub0NvbnRhaW5lZFJlY3RzKTtcbiAgY29uc3QgbWluQXJlYSA9IDIgKiAyO1xuICBmb3IgKGxldCBqID0gbmV3UmVjdHMubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICBjb25zdCByZWN0ID0gbmV3UmVjdHNbal07XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCAqIHJlY3QuaGVpZ2h0ID4gbWluQXJlYTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgaWYgKG5ld1JlY3RzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSBzbWFsbFwiKTtcbiAgICAgICAgfVxuICAgICAgICBuZXdSZWN0cy5zcGxpY2UoaiwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsLCBidXQga2VlcCBvdGhlcndpc2UgZW1wdHkhXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoSVNfREVWKSB7XG4gICAgY2hlY2tPdmVybGFwcyhuZXdSZWN0cyk7XG4gIH1cbiAgaWYgKElTX0RFVikge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYENMSUVOVCBSRUNUOiByZWR1Y2VkICR7b3JpZ2luYWxSZWN0cy5sZW5ndGh9IC0tPiAke25ld1JlY3RzLmxlbmd0aH1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4gbmV3UmVjdHM7XG59XG5cbmZ1bmN0aW9uIGlzUGFnaW5hdGVkKGRvY3VtZW50KSB7XG4gIHJldHVybiAoXG4gICAgZG9jdW1lbnQgJiZcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiZcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX1BBR0lOQVRFRClcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCkge1xuICBpZiAoZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCkge1xuICAgIHJldHVybiBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50O1xuICB9XG4gIHJldHVybiBkb2N1bWVudC5ib2R5O1xufVxuXG5mdW5jdGlvbiBlbnN1cmVDb250YWluZXIod2luLCBhbm5vdGF0aW9uRmxhZykge1xuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBpZiAoIV9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgaWYgKCFib2R5RXZlbnRMaXN0ZW5lcnNTZXQpIHtcbiAgICAgIGJvZHlFdmVudExpc3RlbmVyc1NldCA9IHRydWU7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwibW91c2Vkb3duXCIsXG4gICAgICAgIChldikgPT4ge1xuICAgICAgICAgIGxhc3RNb3VzZURvd25YID0gZXYuY2xpZW50WDtcbiAgICAgICAgICBsYXN0TW91c2VEb3duWSA9IGV2LmNsaWVudFk7XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcIm1vdXNldXBcIixcbiAgICAgICAgKGV2KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgTWF0aC5hYnMobGFzdE1vdXNlRG93blggLSBldi5jbGllbnRYKSA8IDMgJiZcbiAgICAgICAgICAgIE1hdGguYWJzKGxhc3RNb3VzZURvd25ZIC0gZXYuY2xpZW50WSkgPCAzXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcIm1vdXNlbW92ZVwiLFxuICAgICAgICAoZXYpID0+IHtcbiAgICAgICAgICBwcm9jZXNzTW91c2VFdmVudCh3aW4sIGV2KTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJ0b3VjaGVuZFwiLFxuICAgICAgICBmdW5jdGlvbiB0b3VjaEVuZChlKSB7XG4gICAgICAgICAgcHJvY2Vzc1RvdWNoRXZlbnQod2luLCBlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgfVxuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBJRF9ISUdITElHSFRTX0NPTlRBSU5FUik7XG5cbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChfaGlnaGxpZ2h0c0NvbnRhaW5lcik7XG4gIH1cblxuICByZXR1cm4gX2hpZ2hsaWdodHNDb250YWluZXI7XG59XG5cbmZ1bmN0aW9uIGhpZGVBbGxoaWdobGlnaHRzKCkge1xuICBpZiAoX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lci5yZW1vdmUoKTtcbiAgICBfaGlnaGxpZ2h0c0NvbnRhaW5lciA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVzdHJveUFsbGhpZ2hsaWdodHMoKSB7XG4gIGhpZGVBbGxoaWdobGlnaHRzKCk7XG4gIF9oaWdobGlnaHRzLnNwbGljZSgwLCBfaGlnaGxpZ2h0cy5sZW5ndGgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveUhpZ2hsaWdodChpZCkge1xuICBsZXQgaSA9IC0xO1xuICBsZXQgX2RvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoLCBqKSA9PiB7XG4gICAgaSA9IGo7XG4gICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICB9KTtcbiAgaWYgKGhpZ2hsaWdodCAmJiBpID49IDAgJiYgaSA8IF9oaWdobGlnaHRzLmxlbmd0aCkge1xuICAgIF9oaWdobGlnaHRzLnNwbGljZShpLCAxKTtcbiAgfVxuICBjb25zdCBoaWdobGlnaHRDb250YWluZXIgPSBfZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoaGlnaGxpZ2h0Q29udGFpbmVyKSB7XG4gICAgaGlnaGxpZ2h0Q29udGFpbmVyLnJlbW92ZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2ZpVGV4dE5vZGUobm9kZSkge1xuICByZXR1cm4gbm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREU7XG59XG5cbmZ1bmN0aW9uIGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChlbGVtZW50LCBjaGlsZCkge1xuICBsZXQgZm91bmQgPSAtMTtcbiAgbGV0IHRleHROb2RlSW5kZXggPSAtMTtcbiAgbGV0IHByZXZpb3VzV2FzRWxlbWVudCA9IGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkTm9kZSA9IGVsZW1lbnQuY2hpbGROb2Rlc1tpXTtcbiAgICBjb25zdCBpc1RleHQgPSBpc0NmaVRleHROb2RlKGNoaWxkTm9kZSk7XG4gICAgaWYgKGlzVGV4dCB8fCBwcmV2aW91c1dhc0VsZW1lbnQpIHtcbiAgICAgIHRleHROb2RlSW5kZXggKz0gMjtcbiAgICB9XG4gICAgaWYgKGlzVGV4dCkge1xuICAgICAgaWYgKGNoaWxkTm9kZSA9PT0gY2hpbGQpIHtcbiAgICAgICAgZm91bmQgPSB0ZXh0Tm9kZUluZGV4O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcHJldmlvdXNXYXNFbGVtZW50ID0gY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERTtcbiAgfVxuICByZXR1cm4gZm91bmQ7XG59XG5cbmZ1bmN0aW9uIGdldENvbW1vbkFuY2VzdG9yRWxlbWVudChub2RlMSwgbm9kZTIpIHtcbiAgaWYgKG5vZGUxLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMSA9PT0gbm9kZTIpIHtcbiAgICByZXR1cm4gbm9kZTE7XG4gIH1cbiAgaWYgKG5vZGUxLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMS5jb250YWlucyhub2RlMikpIHtcbiAgICByZXR1cm4gbm9kZTE7XG4gIH1cbiAgaWYgKG5vZGUyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBub2RlMi5jb250YWlucyhub2RlMSkpIHtcbiAgICByZXR1cm4gbm9kZTI7XG4gIH1cbiAgY29uc3Qgbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbiA9IFtdO1xuICBsZXQgcGFyZW50ID0gbm9kZTEucGFyZW50Tm9kZTtcbiAgd2hpbGUgKHBhcmVudCAmJiBwYXJlbnQubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbi5wdXNoKHBhcmVudCk7XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XG4gIH1cbiAgY29uc3Qgbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbiA9IFtdO1xuICBwYXJlbnQgPSBub2RlMi5wYXJlbnROb2RlO1xuICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluLnB1c2gocGFyZW50KTtcbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgfVxuICBsZXQgY29tbW9uQW5jZXN0b3IgPSBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluLmZpbmQoXG4gICAgKG5vZGUxRWxlbWVudEFuY2VzdG9yKSA9PiB7XG4gICAgICByZXR1cm4gbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbi5pbmRleE9mKG5vZGUxRWxlbWVudEFuY2VzdG9yKSA+PSAwO1xuICAgIH1cbiAgKTtcbiAgaWYgKCFjb21tb25BbmNlc3Rvcikge1xuICAgIGNvbW1vbkFuY2VzdG9yID0gbm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbi5maW5kKChub2RlMkVsZW1lbnRBbmNlc3RvcikgPT4ge1xuICAgICAgcmV0dXJuIG5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4uaW5kZXhPZihub2RlMkVsZW1lbnRBbmNlc3RvcikgPj0gMDtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gY29tbW9uQW5jZXN0b3I7XG59XG5cbmZ1bmN0aW9uIGZ1bGxRdWFsaWZpZWRTZWxlY3Rvcihub2RlKSB7XG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIGNvbnN0IGxvd2VyQ2FzZU5hbWUgPVxuICAgICAgKG5vZGUubG9jYWxOYW1lICYmIG5vZGUubG9jYWxOYW1lLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgICBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgcmV0dXJuIGxvd2VyQ2FzZU5hbWU7XG4gIH1cbiAgLy9yZXR1cm4gY3NzUGF0aChub2RlLCBqdXN0U2VsZWN0b3IpO1xuICByZXR1cm4gY3NzUGF0aChub2RlLCB0cnVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvKCkge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmICghc2VsZWN0aW9uKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIENPTExBUFNFRC5cIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYXdUZXh0ID0gc2VsZWN0aW9uLnRvU3RyaW5nKCk7XG4gIGNvbnN0IGNsZWFuVGV4dCA9IHJhd1RleHQudHJpbSgpLnJlcGxhY2UoL1xcbi9nLCBcIiBcIikucmVwbGFjZSgvXFxzXFxzKy9nLCBcIiBcIik7XG4gIGlmIChjbGVhblRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIFRFWFQgRU1QVFkuXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFzZWxlY3Rpb24uYW5jaG9yTm9kZSB8fCAhc2VsZWN0aW9uLmZvY3VzTm9kZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2UgPVxuICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxXG4gICAgICA/IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApXG4gICAgICA6IGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0XG4gICAgICAgICk7XG4gIGlmICghcmFuZ2UgfHwgcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCIkJCQkJCQkJCQkJCQkJCQkJCBDQU5OT1QgR0VUIE5PTi1DT0xMQVBTRUQgU0VMRUNUSU9OIFJBTkdFPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYW5nZUluZm8gPSBjb252ZXJ0UmFuZ2UocmFuZ2UsIGZ1bGxRdWFsaWZpZWRTZWxlY3RvciwgY29tcHV0ZUNGSSk7XG4gIGlmICghcmFuZ2VJbmZvKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gU0VMRUNUSU9OIFJBTkdFIElORk8gRkFJTD8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoSVNfREVWICYmIERFQlVHX1ZJU1VBTFMpIHtcbiAgICBjb25zdCByZXN0b3JlZFJhbmdlID0gY29udmVydFJhbmdlSW5mbyh3aW4uZG9jdW1lbnQsIHJhbmdlSW5mbyk7XG4gICAgaWYgKHJlc3RvcmVkUmFuZ2UpIHtcbiAgICAgIGlmIChcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydE9mZnNldCA9PT0gcmFuZ2Uuc3RhcnRPZmZzZXQgJiZcbiAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRPZmZzZXQgPT09IHJhbmdlLmVuZE9mZnNldCAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5zdGFydENvbnRhaW5lciAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLmVuZENvbnRhaW5lciA9PT0gcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgICApIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJTRUxFQ1RJT04gUkFOR0UgUkVTVE9SRUQgT0tBWSAoZGV2IGNoZWNrKS5cIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhcIlNFTEVDVElPTiBSQU5HRSBSRVNUT1JFIEZBSUwgKGRldiBjaGVjaykuXCIpO1xuICAgICAgICBkdW1wRGVidWcoXG4gICAgICAgICAgXCJTRUxFQ1RJT05cIixcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIk9SREVSRUQgUkFOR0UgRlJPTSBTRUxFQ1RJT05cIixcbiAgICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgICAgICByYW5nZS5zdGFydE9mZnNldCxcbiAgICAgICAgICByYW5nZS5lbmRDb250YWluZXIsXG4gICAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIlJFU1RPUkVEIFJBTkdFXCIsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kQ29udGFpbmVyLFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kT2Zmc2V0LFxuICAgICAgICAgIGdldENzc1NlbGVjdG9yXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiQ0FOTk9UIFJFU1RPUkUgU0VMRUNUSU9OIFJBTkdFID8/IVwiKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGxvY2F0aW9uczogcmFuZ2VJbmZvMkxvY2F0aW9uKHJhbmdlSW5mbyksXG4gICAgdGV4dDoge1xuICAgICAgaGlnaGxpZ2h0OiByYXdUZXh0LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNoZWNrQmxhY2tsaXN0ZWQoZWwpIHtcbiAgbGV0IGJsYWNrbGlzdGVkSWQ7XG4gIGNvbnN0IGlkID0gZWwuZ2V0QXR0cmlidXRlKFwiaWRcIik7XG4gIGlmIChpZCAmJiBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSS5pbmRleE9mKGlkKSA+PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJjaGVja0JsYWNrbGlzdGVkIElEOiBcIiArIGlkKTtcbiAgICBibGFja2xpc3RlZElkID0gaWQ7XG4gIH1cbiAgbGV0IGJsYWNrbGlzdGVkQ2xhc3M7XG4gIGZvciAoY29uc3QgaXRlbSBvZiBfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoaXRlbSkpIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiY2hlY2tCbGFja2xpc3RlZCBDTEFTUzogXCIgKyBpdGVtKTtcbiAgICAgIGJsYWNrbGlzdGVkQ2xhc3MgPSBpdGVtO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChibGFja2xpc3RlZElkIHx8IGJsYWNrbGlzdGVkQ2xhc3MpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY3NzUGF0aChub2RlLCBvcHRpbWl6ZWQpIHtcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cblxuICBjb25zdCBzdGVwcyA9IFtdO1xuICBsZXQgY29udGV4dE5vZGUgPSBub2RlO1xuICB3aGlsZSAoY29udGV4dE5vZGUpIHtcbiAgICBjb25zdCBzdGVwID0gX2Nzc1BhdGhTdGVwKGNvbnRleHROb2RlLCAhIW9wdGltaXplZCwgY29udGV4dE5vZGUgPT09IG5vZGUpO1xuICAgIGlmICghc3RlcCkge1xuICAgICAgYnJlYWs7IC8vIEVycm9yIC0gYmFpbCBvdXQgZWFybHkuXG4gICAgfVxuICAgIHN0ZXBzLnB1c2goc3RlcC52YWx1ZSk7XG4gICAgaWYgKHN0ZXAub3B0aW1pemVkKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY29udGV4dE5vZGUgPSBjb250ZXh0Tm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHN0ZXBzLnJldmVyc2UoKTtcbiAgcmV0dXJuIHN0ZXBzLmpvaW4oXCIgPiBcIik7XG59XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4vLyBodHRwczovL2Nocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vYmxpbmsvKy9tYXN0ZXIvU291cmNlL2RldnRvb2xzL2Zyb250X2VuZC9jb21wb25lbnRzL0RPTVByZXNlbnRhdGlvblV0aWxzLmpzIzMxNlxuZnVuY3Rpb24gX2Nzc1BhdGhTdGVwKG5vZGUsIG9wdGltaXplZCwgaXNUYXJnZXROb2RlKSB7XG4gIGZ1bmN0aW9uIHByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMobmQpIHtcbiAgICBjb25zdCBjbGFzc0F0dHJpYnV0ZSA9IG5kLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpO1xuICAgIGlmICghY2xhc3NBdHRyaWJ1dGUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NBdHRyaWJ1dGVcbiAgICAgIC5zcGxpdCgvXFxzKy9nKVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLm1hcCgobm0pID0+IHtcbiAgICAgICAgLy8gVGhlIHByZWZpeCBpcyByZXF1aXJlZCB0byBzdG9yZSBcIl9fcHJvdG9fX1wiIGluIGEgb2JqZWN0LWJhc2VkIG1hcC5cbiAgICAgICAgcmV0dXJuIFwiJFwiICsgbm07XG4gICAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlkU2VsZWN0b3IoaWRkKSB7XG4gICAgcmV0dXJuIFwiI1wiICsgZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkKGlkZCk7XG4gIH1cblxuICBmdW5jdGlvbiBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQoaWRlbnQpIHtcbiAgICBpZiAoaXNDU1NJZGVudGlmaWVyKGlkZW50KSkge1xuICAgICAgcmV0dXJuIGlkZW50O1xuICAgIH1cblxuICAgIGNvbnN0IHNob3VsZEVzY2FwZUZpcnN0ID0gL14oPzpbMC05XXwtWzAtOS1dPykvLnRlc3QoaWRlbnQpO1xuICAgIGNvbnN0IGxhc3RJbmRleCA9IGlkZW50Lmxlbmd0aCAtIDE7XG4gICAgcmV0dXJuIGlkZW50LnJlcGxhY2UoLy4vZywgZnVuY3Rpb24gKGMsIGlpKSB7XG4gICAgICByZXR1cm4gKHNob3VsZEVzY2FwZUZpcnN0ICYmIGlpID09PSAwKSB8fCAhaXNDU1NJZGVudENoYXIoYylcbiAgICAgICAgPyBlc2NhcGVBc2NpaUNoYXIoYywgaWkgPT09IGxhc3RJbmRleClcbiAgICAgICAgOiBjO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZXNjYXBlQXNjaWlDaGFyKGMsIGlzTGFzdCkge1xuICAgIHJldHVybiBcIlxcXFxcIiArIHRvSGV4Qnl0ZShjKSArIChpc0xhc3QgPyBcIlwiIDogXCIgXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9IZXhCeXRlKGMpIHtcbiAgICBsZXQgaGV4Qnl0ZSA9IGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNik7XG4gICAgaWYgKGhleEJ5dGUubGVuZ3RoID09PSAxKSB7XG4gICAgICBoZXhCeXRlID0gXCIwXCIgKyBoZXhCeXRlO1xuICAgIH1cbiAgICByZXR1cm4gaGV4Qnl0ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQ1NTSWRlbnRDaGFyKGMpIHtcbiAgICBpZiAoL1thLXpBLVowLTlfLV0vLnRlc3QoYykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gYy5jaGFyQ29kZUF0KDApID49IDB4YTA7XG4gIH1cblxuICBmdW5jdGlvbiBpc0NTU0lkZW50aWZpZXIodmFsdWUpIHtcbiAgICByZXR1cm4gL14tP1thLXpBLVpfXVthLXpBLVowLTlfLV0qJC8udGVzdCh2YWx1ZSk7XG4gIH1cblxuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGxvd2VyQ2FzZU5hbWUgPVxuICAgIChub2RlLmxvY2FsTmFtZSAmJiBub2RlLmxvY2FsTmFtZS50b0xvd2VyQ2FzZSgpKSB8fFxuICAgIG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuICBjb25zdCBlbGVtZW50ID0gbm9kZTtcblxuICBjb25zdCBpZCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaWRcIik7XG5cbiAgaWYgKG9wdGltaXplZCkge1xuICAgIGlmIChpZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3B0aW1pemVkOiB0cnVlLFxuICAgICAgICB2YWx1ZTogaWRTZWxlY3RvcihpZCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBsb3dlckNhc2VOYW1lID09PSBcImJvZHlcIiB8fFxuICAgICAgbG93ZXJDYXNlTmFtZSA9PT0gXCJoZWFkXCIgfHxcbiAgICAgIGxvd2VyQ2FzZU5hbWUgPT09IFwiaHRtbFwiXG4gICAgKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICAgIHZhbHVlOiBsb3dlckNhc2VOYW1lLCAvLyBub2RlLm5vZGVOYW1lSW5Db3JyZWN0Q2FzZSgpLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBub2RlTmFtZSA9IGxvd2VyQ2FzZU5hbWU7IC8vIG5vZGUubm9kZU5hbWVJbkNvcnJlY3RDYXNlKCk7XG4gIGlmIChpZCkge1xuICAgIHJldHVybiB7XG4gICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICB2YWx1ZTogbm9kZU5hbWUgKyBpZFNlbGVjdG9yKGlkKSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuXG4gIGlmICghcGFyZW50IHx8IHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5ET0NVTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgIHZhbHVlOiBub2RlTmFtZSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfID0gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhlbGVtZW50KTtcblxuICBjb25zdCBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheSA9IFtdOyAvLyAua2V5U2V0KClcbiAgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfLmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICBpZiAocHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkuaW5kZXhPZihhcnJJdGVtKSA8IDApIHtcbiAgICAgIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5LnB1c2goYXJySXRlbSk7XG4gICAgfVxuICB9KTtcblxuICBsZXQgbmVlZHNDbGFzc05hbWVzID0gZmFsc2U7XG4gIGxldCBuZWVkc050aENoaWxkID0gZmFsc2U7XG4gIGxldCBvd25JbmRleCA9IC0xO1xuICBsZXQgZWxlbWVudEluZGV4ID0gLTE7XG4gIGNvbnN0IHNpYmxpbmdzID0gcGFyZW50LmNoaWxkcmVuO1xuXG4gIGZvciAoXG4gICAgbGV0IGkgPSAwO1xuICAgIChvd25JbmRleCA9PT0gLTEgfHwgIW5lZWRzTnRoQ2hpbGQpICYmIGkgPCBzaWJsaW5ncy5sZW5ndGg7XG4gICAgKytpXG4gICkge1xuICAgIGNvbnN0IHNpYmxpbmcgPSBzaWJsaW5nc1tpXTtcbiAgICBpZiAoc2libGluZy5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBlbGVtZW50SW5kZXggKz0gMTtcbiAgICBpZiAoc2libGluZyA9PT0gbm9kZSkge1xuICAgICAgb3duSW5kZXggPSBlbGVtZW50SW5kZXg7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKG5lZWRzTnRoQ2hpbGQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHNpYmxpbmcubm9kZU5hbWVJbkNvcnJlY3RDYXNlKClcbiAgICBjb25zdCBzaWJsaW5nTmFtZSA9XG4gICAgICAoc2libGluZy5sb2NhbE5hbWUgJiYgc2libGluZy5sb2NhbE5hbWUudG9Mb3dlckNhc2UoKSkgfHxcbiAgICAgIHNpYmxpbmcubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoc2libGluZ05hbWUgIT09IG5vZGVOYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbmVlZHNDbGFzc05hbWVzID0gdHJ1ZTtcblxuICAgIGNvbnN0IG93bkNsYXNzTmFtZXMgPSBbXTtcbiAgICBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheS5mb3JFYWNoKChhcnJJdGVtKSA9PiB7XG4gICAgICBvd25DbGFzc05hbWVzLnB1c2goYXJySXRlbSk7XG4gICAgfSk7XG4gICAgbGV0IG93bkNsYXNzTmFtZUNvdW50ID0gb3duQ2xhc3NOYW1lcy5sZW5ndGg7XG5cbiAgICBpZiAob3duQ2xhc3NOYW1lQ291bnQgPT09IDApIHtcbiAgICAgIG5lZWRzTnRoQ2hpbGQgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHNpYmxpbmdDbGFzc05hbWVzQXJyYXlfID0gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhzaWJsaW5nKTtcbiAgICBjb25zdCBzaWJsaW5nQ2xhc3NOYW1lc0FycmF5ID0gW107IC8vIC5rZXlTZXQoKVxuICAgIHNpYmxpbmdDbGFzc05hbWVzQXJyYXlfLmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICAgIGlmIChzaWJsaW5nQ2xhc3NOYW1lc0FycmF5LmluZGV4T2YoYXJySXRlbSkgPCAwKSB7XG4gICAgICAgIHNpYmxpbmdDbGFzc05hbWVzQXJyYXkucHVzaChhcnJJdGVtKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgc2libGluZ0NsYXNzIG9mIHNpYmxpbmdDbGFzc05hbWVzQXJyYXkpIHtcbiAgICAgIGNvbnN0IGluZCA9IG93bkNsYXNzTmFtZXMuaW5kZXhPZihzaWJsaW5nQ2xhc3MpO1xuICAgICAgaWYgKGluZCA8IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIG93bkNsYXNzTmFtZXMuc3BsaWNlKGluZCwgMSk7IC8vIGRlbGV0ZSBvd25DbGFzc05hbWVzW3NpYmxpbmdDbGFzc107XG5cbiAgICAgIGlmICghLS1vd25DbGFzc05hbWVDb3VudCkge1xuICAgICAgICBuZWVkc050aENoaWxkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHJlc3VsdCA9IG5vZGVOYW1lO1xuICBpZiAoXG4gICAgaXNUYXJnZXROb2RlICYmXG4gICAgbm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJlxuICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwidHlwZVwiKSAmJlxuICAgICFlbGVtZW50LmdldEF0dHJpYnV0ZShcImlkXCIpICYmXG4gICAgIWVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIilcbiAgKSB7XG4gICAgcmVzdWx0ICs9ICdbdHlwZT1cIicgKyBlbGVtZW50LmdldEF0dHJpYnV0ZShcInR5cGVcIikgKyAnXCJdJztcbiAgfVxuICBpZiAobmVlZHNOdGhDaGlsZCkge1xuICAgIHJlc3VsdCArPSBcIjpudGgtY2hpbGQoXCIgKyAob3duSW5kZXggKyAxKSArIFwiKVwiO1xuICB9IGVsc2UgaWYgKG5lZWRzQ2xhc3NOYW1lcykge1xuICAgIGZvciAoY29uc3QgcHJlZml4ZWROYW1lIG9mIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5KSB7XG4gICAgICByZXN1bHQgKz0gXCIuXCIgKyBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQocHJlZml4ZWROYW1lLnN1YnN0cigxKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBvcHRpbWl6ZWQ6IGZhbHNlLFxuICAgIHZhbHVlOiByZXN1bHQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVDRkkobm9kZSkge1xuICAvLyBUT0RPOiBoYW5kbGUgY2hhcmFjdGVyIHBvc2l0aW9uIGluc2lkZSB0ZXh0IG5vZGVcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxldCBjZmkgPSBcIlwiO1xuXG4gIGxldCBjdXJyZW50RWxlbWVudCA9IG5vZGU7XG4gIHdoaWxlIChcbiAgICBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlICYmXG4gICAgY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgKSB7XG4gICAgY29uc3QgYmxhY2tsaXN0ZWQgPSBjaGVja0JsYWNrbGlzdGVkKGN1cnJlbnRFbGVtZW50KTtcbiAgICBpZiAoIWJsYWNrbGlzdGVkKSB7XG4gICAgICBjb25zdCBjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuID0gY3VycmVudEVsZW1lbnQucGFyZW50Tm9kZS5jaGlsZHJlbjtcbiAgICAgIGxldCBjdXJyZW50RWxlbWVudEluZGV4ID0gLTE7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGN1cnJlbnRFbGVtZW50ID09PSBjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuW2ldKSB7XG4gICAgICAgICAgY3VycmVudEVsZW1lbnRJbmRleCA9IGk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50RWxlbWVudEluZGV4ID49IDApIHtcbiAgICAgICAgY29uc3QgY2ZpSW5kZXggPSAoY3VycmVudEVsZW1lbnRJbmRleCArIDEpICogMjtcbiAgICAgICAgY2ZpID1cbiAgICAgICAgICBjZmlJbmRleCArXG4gICAgICAgICAgKGN1cnJlbnRFbGVtZW50LmlkID8gXCJbXCIgKyBjdXJyZW50RWxlbWVudC5pZCArIFwiXVwiIDogXCJcIikgK1xuICAgICAgICAgIChjZmkubGVuZ3RoID8gXCIvXCIgKyBjZmkgOiBcIlwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY3VycmVudEVsZW1lbnQgPSBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlO1xuICB9XG5cbiAgcmV0dXJuIFwiL1wiICsgY2ZpO1xufVxuXG5mdW5jdGlvbiBfY3JlYXRlSGlnaGxpZ2h0KGxvY2F0aW9ucywgY29sb3IsIHBvaW50ZXJJbnRlcmFjdGlvbiwgdHlwZSkge1xuICBjb25zdCByYW5nZUluZm8gPSBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb25zKTtcbiAgY29uc3QgdW5pcXVlU3RyID0gYCR7cmFuZ2VJbmZvLmNmaX0ke3JhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcn0ke3JhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleH0ke3JhbmdlSW5mby5zdGFydE9mZnNldH0ke3JhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3J9JHtyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4fSR7cmFuZ2VJbmZvLmVuZE9mZnNldH1gO1xuXG4gIGNvbnN0IGhhc2ggPSByZXF1aXJlKFwiaGFzaC5qc1wiKTtcbiAgY29uc3Qgc2hhMjU2SGV4ID0gaGFzaC5zaGEyNTYoKS51cGRhdGUodW5pcXVlU3RyKS5kaWdlc3QoXCJoZXhcIik7XG5cbiAgdmFyIGlkO1xuICBpZiAodHlwZSA9PSBJRF9ISUdITElHSFRTX0NPTlRBSU5FUikge1xuICAgIGlkID0gXCJSMl9ISUdITElHSFRfXCIgKyBzaGEyNTZIZXg7XG4gIH0gZWxzZSB7XG4gICAgaWQgPSBcIlIyX0FOTk9UQVRJT05fXCIgKyBzaGEyNTZIZXg7XG4gIH1cblxuICBkZXN0cm95SGlnaGxpZ2h0KGlkKTtcblxuICBjb25zdCBoaWdobGlnaHQgPSB7XG4gICAgY29sb3I6IGNvbG9yID8gY29sb3IgOiBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IsXG4gICAgaWQsXG4gICAgcG9pbnRlckludGVyYWN0aW9uLFxuICAgIHJhbmdlSW5mbyxcbiAgfTtcbiAgX2hpZ2hsaWdodHMucHVzaChoaWdobGlnaHQpO1xuICBjcmVhdGVIaWdobGlnaHREb20oXG4gICAgd2luZG93LFxuICAgIGhpZ2hsaWdodCxcbiAgICB0eXBlID09IElEX0FOTk9UQVRJT05fQ09OVEFJTkVSID8gdHJ1ZSA6IGZhbHNlXG4gICk7XG5cbiAgcmV0dXJuIGhpZ2hsaWdodDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhpZ2hsaWdodChzZWxlY3Rpb25JbmZvLCBjb2xvciwgcG9pbnRlckludGVyYWN0aW9uKSB7XG4gIHJldHVybiBfY3JlYXRlSGlnaGxpZ2h0KFxuICAgIHNlbGVjdGlvbkluZm8sXG4gICAgY29sb3IsXG4gICAgcG9pbnRlckludGVyYWN0aW9uLFxuICAgIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBbm5vdGF0aW9uKGlkKSB7XG4gIGxldCBpID0gLTE7XG5cbiAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCwgaikgPT4ge1xuICAgIGkgPSBqO1xuICAgIHJldHVybiBoLmlkID09PSBpZDtcbiAgfSk7XG4gIGlmIChpID09IF9oaWdobGlnaHRzLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHZhciBsb2NhdGlvbnMgPSB7XG4gICAgbG9jYXRpb25zOiByYW5nZUluZm8yTG9jYXRpb24oaGlnaGxpZ2h0LnJhbmdlSW5mbyksXG4gIH07XG5cbiAgcmV0dXJuIF9jcmVhdGVIaWdobGlnaHQoXG4gICAgbG9jYXRpb25zLFxuICAgIGhpZ2hsaWdodC5jb2xvcixcbiAgICB0cnVlLFxuICAgIElEX0FOTk9UQVRJT05fQ09OVEFJTkVSXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUhpZ2hsaWdodERvbSh3aW4sIGhpZ2hsaWdodCwgYW5ub3RhdGlvbkZsYWcpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG5cbiAgY29uc3Qgc2NhbGUgPVxuICAgIDEgL1xuICAgICh3aW4uUkVBRElVTTIgJiYgd2luLlJFQURJVU0yLmlzRml4ZWRMYXlvdXRcbiAgICAgID8gd2luLlJFQURJVU0yLmZ4bFZpZXdwb3J0U2NhbGVcbiAgICAgIDogMSk7XG5cbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuXG4gIGNvbnN0IHJhbmdlID0gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgaGlnaGxpZ2h0LnJhbmdlSW5mbyk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBoaWdobGlnaHRzQ29udGFpbmVyID0gZW5zdXJlQ29udGFpbmVyKHdpbiwgYW5ub3RhdGlvbkZsYWcpO1xuICBjb25zdCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG4gIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBoaWdobGlnaHQuaWQpO1xuICBoaWdobGlnaHRQYXJlbnQuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0NPTlRBSU5FUik7XG5cbiAgZG9jdW1lbnQuYm9keS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcbiAgaGlnaGxpZ2h0UGFyZW50LnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICBpZiAoaGlnaGxpZ2h0LnBvaW50ZXJJbnRlcmFjdGlvbikge1xuICAgIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJkYXRhLWNsaWNrXCIsIFwiMVwiKTtcbiAgfVxuXG4gIGNvbnN0IGJvZHlSZWN0ID0gZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgY29uc3QgdXNlU1ZHID0gIURFQlVHX1ZJU1VBTFMgJiYgVVNFX1NWRztcbiAgLy9jb25zdCB1c2VTVkcgPSBVU0VfU1ZHO1xuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgbGV0IGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnO1xuICBjb25zdCByb3VuZGVkQ29ybmVyID0gMztcbiAgY29uc3QgdW5kZXJsaW5lVGhpY2tuZXNzID0gMjtcbiAgY29uc3Qgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgPSAzO1xuICBjb25zdCBvcGFjaXR5ID0gREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFk7XG4gIGxldCBleHRyYSA9IFwiXCI7XG4gIGNvbnN0IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdCA9XG4gICAgZnJhbWVGb3JIaWdobGlnaHRBbm5vdGF0aW9uTWFya1dpdGhJRCh3aW4sIGhpZ2hsaWdodC5pZCk7XG5cbiAgbGV0IHhPZmZzZXQ7XG4gIGxldCB5T2Zmc2V0O1xuICBsZXQgYW5ub3RhdGlvbk9mZnNldDtcblxuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0IDogYm9keVJlY3QubGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICAgIGFubm90YXRpb25PZmZzZXQgPVxuICAgICAgcGFyc2VJbnQoXG4gICAgICAgIChyYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QucmlnaHQgLSB4T2Zmc2V0KSAvIHdpbmRvdy5pbm5lcldpZHRoXG4gICAgICApICsgMTtcbiAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICAgIGFubm90YXRpb25PZmZzZXQgPSBwYXJzZUludChcbiAgICAgIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5yaWdodCAvIHdpbmRvdy5pbm5lcldpZHRoICsgMVxuICAgICk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBpZiAodXNlU1ZHKSB7XG4gICAgICBjb25zdCBib3JkZXJUaGlja25lc3MgPSAwO1xuICAgICAgaWYgKCFoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZykge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdSZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICBTVkdfWE1MX05BTUVTUEFDRSxcbiAgICAgICAgXCJyZWN0XCJcbiAgICAgICk7XG5cbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICBgZmlsbDogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pICFpbXBvcnRhbnQ7IGZpbGwtb3BhY2l0eTogJHtvcGFjaXR5fSAhaW1wb3J0YW50OyBzdHJva2Utd2lkdGg6IDA7YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNjYWxlID0gc2NhbGU7XG5cbiAgICAgIC8qXG4gICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdCA9IHtcbiAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAqL1xuXG4gICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwicnhcIiwgYCR7cm91bmRlZENvcm5lciAqIHNjYWxlfWApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwicnlcIiwgYCR7cm91bmRlZENvcm5lciAqIHNjYWxlfWApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInhcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QubGVmdCAtIGJvcmRlclRoaWNrbmVzcykgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInlcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QudG9wIC0gYm9yZGVyVGhpY2tuZXNzKSAqIHNjYWxlfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0LmhlaWdodCArIGJvcmRlclRoaWNrbmVzcyAqIDIpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJ3aWR0aFwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC53aWR0aCArIGJvcmRlclRoaWNrbmVzcyAqIDIpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnLmFwcGVuZENoaWxkKGhpZ2hsaWdodEFyZWFTVkdSZWN0KTtcbiAgICAgIGlmIChkcmF3VW5kZXJsaW5lKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICAgIFwibGluZVwiXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9BUkVBKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgICBgc3Ryb2tlLWxpbmVjYXA6IHJvdW5kOyBzdHJva2Utd2lkdGg6ICR7XG4gICAgICAgICAgICB1bmRlcmxpbmVUaGlja25lc3MgKiBzY2FsZVxuICAgICAgICAgIH07IHN0cm9rZTogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSkgIWltcG9ydGFudDsgc3Ryb2tlLW9wYWNpdHk6ICR7b3BhY2l0eX0gIWltcG9ydGFudGBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGluZU9mZnNldCA9XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCA+IHJvdW5kZWRDb3JuZXIgPyByb3VuZGVkQ29ybmVyIDogMDtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDFcIixcbiAgICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICsgbGluZU9mZnNldCkgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngyXCIsXG4gICAgICAgICAgYCR7XG4gICAgICAgICAgICAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICtcbiAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAtXG4gICAgICAgICAgICAgIGxpbmVPZmZzZXQpICpcbiAgICAgICAgICAgIHNjYWxlXG4gICAgICAgICAgfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgeSA9XG4gICAgICAgICAgKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QudG9wICtcbiAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0IC1cbiAgICAgICAgICAgIHVuZGVybGluZVRoaWNrbmVzcyAvIDIpICpcbiAgICAgICAgICBzY2FsZTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTFcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTJcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIndpZHRoXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0QXJlYVNWR0xpbmUpO1xuICAgICAgfVxuICAgICAgaWYgKGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkdMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICAgIFwibGluZVwiXG4gICAgICAgICk7XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICAgIGBzdHJva2UtbGluZWNhcDogYnV0dDsgc3Ryb2tlLXdpZHRoOiAke1xuICAgICAgICAgICAgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgKiBzY2FsZVxuICAgICAgICAgIH07IHN0cm9rZTogcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSkgIWltcG9ydGFudDsgc3Ryb2tlLW9wYWNpdHk6ICR7b3BhY2l0eX0gIWltcG9ydGFudGBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2NhbGUgPSBzY2FsZTtcblxuICAgICAgICAvKlxuICAgICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngxXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ4MlwiLFxuICAgICAgICAgIGAke1xuICAgICAgICAgICAgKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QubGVmdCArIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGgpICpcbiAgICAgICAgICAgIHNjYWxlXG4gICAgICAgICAgfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbGluZU9mZnNldCA9IGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgY29uc3QgeSA9IChoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LnRvcCArIGxpbmVPZmZzZXQpICogc2NhbGU7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkxXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcInkyXCIsIGAke3l9YCk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcImhlaWdodFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QuaGVpZ2h0ICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ3aWR0aFwiLFxuICAgICAgICAgIGAke2hpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3Qud2lkdGggKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnLmFwcGVuZENoaWxkKGhpZ2hsaWdodEFyZWFTVkdMaW5lKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgICAgIGhpZ2hsaWdodEFyZWEuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuXG4gICAgICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgICAgICBjb25zdCByZ2IgPSBNYXRoLnJvdW5kKDB4ZmZmZmZmICogTWF0aC5yYW5kb20oKSk7XG4gICAgICAgIGNvbnN0IHIgPSByZ2IgPj4gMTY7XG4gICAgICAgIGNvbnN0IGcgPSAocmdiID4+IDgpICYgMjU1O1xuICAgICAgICBjb25zdCBiID0gcmdiICYgMjU1O1xuICAgICAgICBleHRyYSA9IGBvdXRsaW5lLWNvbG9yOiByZ2IoJHtyfSwgJHtnfSwgJHtifSk7IG91dGxpbmUtc3R5bGU6IHNvbGlkOyBvdXRsaW5lLXdpZHRoOiAxcHg7IG91dGxpbmUtb2Zmc2V0OiAtMXB4O2A7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZHJhd1VuZGVybGluZSkge1xuICAgICAgICAgIGV4dHJhICs9IGBib3JkZXItYm90dG9tOiAke3VuZGVybGluZVRoaWNrbmVzcyAqIHNjYWxlfXB4IHNvbGlkIHJnYmEoJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5yZWRcbiAgICAgICAgICB9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7XG4gICAgICAgICAgICBoaWdobGlnaHQuY29sb3IuYmx1ZVxuICAgICAgICAgIH0sICR7b3BhY2l0eX0pICFpbXBvcnRhbnRgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoaWdobGlnaHRBcmVhLnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICBgYm9yZGVyLXJhZGl1czogJHtyb3VuZGVkQ29ybmVyfXB4ICFpbXBvcnRhbnQ7IGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDsgJHtleHRyYX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gICAgICBoaWdobGlnaHRBcmVhLnNjYWxlID0gc2NhbGU7XG4gICAgICAvKlxuICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAqL1xuICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdobGlnaHRBcmVhLnJlY3QgPSB7XG4gICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLndpZHRoID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LndpZHRoICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5oZWlnaHQgPSBgJHtoaWdobGlnaHRBcmVhLnJlY3QuaGVpZ2h0ICogc2NhbGV9cHhgO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5sZWZ0ID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LmxlZnQgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnRvcCA9IGAke2hpZ2hsaWdodEFyZWEucmVjdC50b3AgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRQYXJlbnQuYXBwZW5kKGhpZ2hsaWdodEFyZWEpO1xuICAgICAgaWYgKCFERUJVR19WSVNVQUxTICYmIGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIC8vaWYgKGRyYXdTdHJpa2VUaHJvdWdoKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgICAgYGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDtgXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdCA9IHtcbiAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqL1xuXG4gICAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS53aWR0aCA9IGAke1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3Qud2lkdGggKiBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS5oZWlnaHQgPSBgJHtcbiAgICAgICAgICBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyAqIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLmxlZnQgPSBgJHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0LmxlZnQgKiBzY2FsZVxuICAgICAgICB9cHhgO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zdHlsZS50b3AgPSBgJHtcbiAgICAgICAgICAoaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC50b3AgK1xuICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC5oZWlnaHQgLyAyIC1cbiAgICAgICAgICAgIHN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzIC8gMikgKlxuICAgICAgICAgIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYUxpbmUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKHVzZVNWRyAmJiBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZykge1xuICAgIGNvbnN0IGhpZ2hsaWdodEFyZWFTVkcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX1hNTF9OQU1FU1BBQ0UsIFwic3ZnXCIpO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc2V0QXR0cmlidXRlKFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS5vdmVyZmxvdyA9IFwidmlzaWJsZVwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUubGVmdCA9IFwiMFwiO1xuICAgIGhpZ2hsaWdodEFyZWFTVkcuc3R5bGUudG9wID0gXCIwXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5hcHBlbmQoaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcpO1xuICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYVNWRyk7XG4gIH1cblxuICBjb25zdCBoaWdobGlnaHRCb3VuZGluZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgaGlnaGxpZ2h0Qm91bmRpbmcuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBKTtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXG4gICAgICBcInN0eWxlXCIsXG4gICAgICBgYm9yZGVyLXJhZGl1czogJHtyb3VuZGVkQ29ybmVyfXB4ICFpbXBvcnRhbnQ7IGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudDsgJHtleHRyYX1gXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSk7XG4gIH1cblxuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUucG9zaXRpb24gPSBwYWdpbmF0ZWQgPyBcImZpeGVkXCIgOiBcImFic29sdXRlXCI7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnNjYWxlID0gc2NhbGU7XG5cbiAgaWYgKERFQlVHX1ZJU1VBTFMpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXG4gICAgICBcInN0eWxlXCIsXG4gICAgICBgb3V0bGluZS1jb2xvcjogbWFnZW50YTsgb3V0bGluZS1zdHlsZTogc29saWQ7IG91dGxpbmUtd2lkdGg6IDFweDsgb3V0bGluZS1vZmZzZXQ6IC0xcHg7YFxuICAgICk7XG4gIH1cblxuICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5yZWN0ID0ge1xuICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QgPSByYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5yZWN0ID0ge1xuICAgICAgaGVpZ2h0OiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgIHRvcDogcmFuZ2VCb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgIHdpZHRoOiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9O1xuICB9XG5cbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUud2lkdGggPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LndpZHRoICogc2NhbGV9cHhgO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5oZWlnaHQgPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LmhlaWdodCAqIHNjYWxlfXB4YDtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUubGVmdCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3QubGVmdCAqIHNjYWxlfXB4YDtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUudG9wID0gYCR7aGlnaGxpZ2h0Qm91bmRpbmcucmVjdC50b3AgKiBzY2FsZX1weGA7XG5cbiAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRCb3VuZGluZyk7XG4gIGhpZ2hsaWdodHNDb250YWluZXIuYXBwZW5kKGhpZ2hsaWdodFBhcmVudCk7XG5cbiAgcmV0dXJuIGhpZ2hsaWdodFBhcmVudDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT3JkZXJlZFJhbmdlKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQsIGVuZE5vZGUsIGVuZE9mZnNldCkge1xuICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZS5zZXRTdGFydChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIGlmICghcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGNvbnNvbGUubG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBDT0xMQVBTRUQgLi4uIFJBTkdFIFJFVkVSU0U/XCIpO1xuICBjb25zdCByYW5nZVJldmVyc2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2VSZXZlcnNlLnNldFN0YXJ0KGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRFbmQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIGlmICghcmFuZ2VSZXZlcnNlLmNvbGxhcHNlZCkge1xuICAgIGNvbnNvbGUubG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIE9LLlwiKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgY29uc29sZS5sb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgQUxTTyBDT0xMQVBTRUQ/IVwiKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gY29udmVydFJhbmdlKHJhbmdlLCBnZXRDc3NTZWxlY3RvciwgY29tcHV0ZUVsZW1lbnRDRkkpIHtcbiAgY29uc3Qgc3RhcnRJc0VsZW1lbnQgPSByYW5nZS5zdGFydENvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyRWxlbWVudCA9IHN0YXJ0SXNFbGVtZW50XG4gICAgPyByYW5nZS5zdGFydENvbnRhaW5lclxuICAgIDogcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZSAmJlxuICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICA/IHJhbmdlLnN0YXJ0Q29udGFpbmVyLnBhcmVudE5vZGVcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKCFzdGFydENvbnRhaW5lckVsZW1lbnQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID0gc3RhcnRJc0VsZW1lbnRcbiAgICA/IC0xXG4gICAgOiBBcnJheS5mcm9tKHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzKS5pbmRleE9mKFxuICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lclxuICAgICAgKTtcbiAgaWYgKHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IDwgLTEpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yID0gZ2V0Q3NzU2VsZWN0b3IoXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50XG4gICk7XG4gIGNvbnN0IGVuZElzRWxlbWVudCA9IHJhbmdlLmVuZENvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7XG4gIGNvbnN0IGVuZENvbnRhaW5lckVsZW1lbnQgPSBlbmRJc0VsZW1lbnRcbiAgICA/IHJhbmdlLmVuZENvbnRhaW5lclxuICAgIDogcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGUgJiZcbiAgICAgIHJhbmdlLmVuZENvbnRhaW5lci5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgID8gcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGVcbiAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKCFlbmRDb250YWluZXJFbGVtZW50KSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPSBlbmRJc0VsZW1lbnRcbiAgICA/IC0xXG4gICAgOiBBcnJheS5mcm9tKGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2RlcykuaW5kZXhPZihyYW5nZS5lbmRDb250YWluZXIpO1xuICBpZiAoZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IDwgLTEpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciA9IGdldENzc1NlbGVjdG9yKGVuZENvbnRhaW5lckVsZW1lbnQpO1xuICBjb25zdCBjb21tb25FbGVtZW50QW5jZXN0b3IgPSBnZXRDb21tb25BbmNlc3RvckVsZW1lbnQoXG4gICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2UuZW5kQ29udGFpbmVyXG4gICk7XG4gIGlmICghY29tbW9uRWxlbWVudEFuY2VzdG9yKSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gTk8gUkFOR0UgQ09NTU9OIEFOQ0VTVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAocmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIpIHtcbiAgICBjb25zdCByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCA9XG4gICAgICByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lci5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREVcbiAgICAgICAgPyByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lclxuICAgICAgICA6IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQgJiZcbiAgICAgIHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50Lm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgICkge1xuICAgICAgaWYgKGNvbW1vbkVsZW1lbnRBbmNlc3RvciAhPT0gcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCI+Pj4+Pj4gQ09NTU9OIEFOQ0VTVE9SIENPTlRBSU5FUiBESUZGPz8hXCIpO1xuICAgICAgICBjb25zb2xlLmxvZyhnZXRDc3NTZWxlY3Rvcihjb21tb25FbGVtZW50QW5jZXN0b3IpKTtcbiAgICAgICAgY29uc29sZS5sb2coZ2V0Q3NzU2VsZWN0b3IocmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3Qgcm9vdEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShjb21tb25FbGVtZW50QW5jZXN0b3IpO1xuICBjb25zdCBzdGFydEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShzdGFydENvbnRhaW5lckVsZW1lbnQpO1xuICBjb25zdCBlbmRFbGVtZW50Q2ZpID0gY29tcHV0ZUVsZW1lbnRDRkkoZW5kQ29udGFpbmVyRWxlbWVudCk7XG4gIGxldCBjZmk7XG4gIGlmIChyb290RWxlbWVudENmaSAmJiBzdGFydEVsZW1lbnRDZmkgJiYgZW5kRWxlbWVudENmaSkge1xuICAgIGxldCBzdGFydEVsZW1lbnRPclRleHRDZmkgPSBzdGFydEVsZW1lbnRDZmk7XG4gICAgaWYgKCFzdGFydElzRWxlbWVudCkge1xuICAgICAgY29uc3Qgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkgPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXJcbiAgICAgICk7XG4gICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICBzdGFydEVsZW1lbnRDZmkgK1xuICAgICAgICBcIi9cIiArXG4gICAgICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpICtcbiAgICAgICAgXCI6XCIgK1xuICAgICAgICByYW5nZS5zdGFydE9mZnNldDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICByYW5nZS5zdGFydE9mZnNldCA+PSAwICYmXG4gICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0IDwgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgY2hpbGROb2RlID0gc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2Uuc3RhcnRPZmZzZXRdO1xuICAgICAgICBpZiAoY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIChyYW5nZS5zdGFydE9mZnNldCArIDEpICogMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBjZmlUZXh0Tm9kZUluZGV4ID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LFxuICAgICAgICAgICAgY2hpbGROb2RlXG4gICAgICAgICAgKTtcbiAgICAgICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPSBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIGNmaVRleHROb2RlSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNmaUluZGV4T2ZMYXN0RWxlbWVudCA9XG4gICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkRWxlbWVudENvdW50ICogMjtcbiAgICAgICAgY29uc3QgbGFzdENoaWxkTm9kZSA9XG4gICAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbXG4gICAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggLSAxXG4gICAgICAgICAgXTtcbiAgICAgICAgaWYgKGxhc3RDaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBzdGFydEVsZW1lbnRDZmkgKyBcIi9cIiArIChjZmlJbmRleE9mTGFzdEVsZW1lbnQgKyAyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBsZXQgZW5kRWxlbWVudE9yVGV4dENmaSA9IGVuZEVsZW1lbnRDZmk7XG4gICAgaWYgKCFlbmRJc0VsZW1lbnQpIHtcbiAgICAgIGNvbnN0IGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSA9IGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChcbiAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgICApO1xuICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgIGVuZEVsZW1lbnRDZmkgK1xuICAgICAgICBcIi9cIiArXG4gICAgICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSArXG4gICAgICAgIFwiOlwiICtcbiAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIHJhbmdlLmVuZE9mZnNldCA+PSAwICYmXG4gICAgICAgIHJhbmdlLmVuZE9mZnNldCA8IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2UuZW5kT2Zmc2V0XTtcbiAgICAgICAgaWYgKGNoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID0gZW5kRWxlbWVudENmaSArIFwiL1wiICsgKHJhbmdlLmVuZE9mZnNldCArIDEpICogMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBjZmlUZXh0Tm9kZUluZGV4ID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICAgICAgZW5kQ29udGFpbmVyRWxlbWVudCxcbiAgICAgICAgICAgIGNoaWxkTm9kZVxuICAgICAgICAgICk7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9IGVuZEVsZW1lbnRDZmkgKyBcIi9cIiArIGNmaVRleHROb2RlSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNmaUluZGV4T2ZMYXN0RWxlbWVudCA9IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQgKiAyO1xuICAgICAgICBjb25zdCBsYXN0Q2hpbGROb2RlID1cbiAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXNbXG4gICAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoIC0gMVxuICAgICAgICAgIF07XG4gICAgICAgIGlmIChsYXN0Q2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgZW5kRWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgZW5kRWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNmaSA9XG4gICAgICByb290RWxlbWVudENmaSArXG4gICAgICBcIixcIiArXG4gICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkucmVwbGFjZShyb290RWxlbWVudENmaSwgXCJcIikgK1xuICAgICAgXCIsXCIgK1xuICAgICAgZW5kRWxlbWVudE9yVGV4dENmaS5yZXBsYWNlKHJvb3RFbGVtZW50Q2ZpLCBcIlwiKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGNmaSxcbiAgICBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIGVuZE9mZnNldDogcmFuZ2UuZW5kT2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiByYW5nZS5zdGFydE9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgcmFuZ2VJbmZvKSB7XG4gIGNvbnN0IHN0YXJ0RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghc3RhcnRFbGVtZW50KSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBTVEFSVCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IHN0YXJ0Q29udGFpbmVyID0gc3RhcnRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBzdGFydENvbnRhaW5lciA9XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICBjb25zdCBlbmRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghZW5kRWxlbWVudCkge1xuICAgIGNvbnNvbGUubG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gRU5EIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgZW5kQ29udGFpbmVyID0gZW5kRWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVuZENvbnRhaW5lciA9XG4gICAgICBlbmRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICBzdGFydENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uc3RhcnRPZmZzZXQsXG4gICAgZW5kQ29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5lbmRPZmZzZXRcbiAgKTtcbn1cblxuZnVuY3Rpb24gZnJhbWVGb3JIaWdobGlnaHRBbm5vdGF0aW9uTWFya1dpdGhJRCh3aW4sIGlkKSB7XG4gIGxldCBjbGllbnRSZWN0cyA9IGZyYW1lRm9ySGlnaGxpZ2h0V2l0aElEKGlkKTtcbiAgaWYgKCFjbGllbnRSZWN0cykgcmV0dXJuO1xuXG4gIHZhciB0b3BDbGllbnRSZWN0ID0gY2xpZW50UmVjdHNbMF07XG4gIHZhciBtYXhIZWlnaHQgPSB0b3BDbGllbnRSZWN0LmhlaWdodDtcbiAgZm9yIChjb25zdCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgaWYgKGNsaWVudFJlY3QudG9wIDwgdG9wQ2xpZW50UmVjdC50b3ApIHRvcENsaWVudFJlY3QgPSBjbGllbnRSZWN0O1xuICAgIGlmIChjbGllbnRSZWN0LmhlaWdodCA+IG1heEhlaWdodCkgbWF4SGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQ7XG4gIH1cblxuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeU9mZnNldDtcbiAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wIDogYm9keVJlY3QudG9wO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICB2YXIgbmV3VG9wID0gdG9wQ2xpZW50UmVjdC50b3A7XG5cbiAgaWYgKF9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgZG8ge1xuICAgICAgdmFyIGJvdW5kaW5nQXJlYXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFxuICAgICAgICBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcbiAgICAgICk7XG4gICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgIC8vZm9yIChsZXQgaSA9IDAsIGxlbmd0aCA9IGJvdW5kaW5nQXJlYXMuc25hcHNob3RMZW5ndGg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgZm9yIChcbiAgICAgICAgdmFyIGkgPSAwLCBsZW4gPSBib3VuZGluZ0FyZWFzLmxlbmd0aCB8IDA7XG4gICAgICAgIGkgPCBsZW47XG4gICAgICAgIGkgPSAoaSArIDEpIHwgMFxuICAgICAgKSB7XG4gICAgICAgIHZhciBib3VuZGluZ0FyZWEgPSBib3VuZGluZ0FyZWFzW2ldO1xuICAgICAgICBpZiAoTWF0aC5hYnMoYm91bmRpbmdBcmVhLnJlY3QudG9wIC0gKG5ld1RvcCAtIHlPZmZzZXQpKSA8IDMpIHtcbiAgICAgICAgICBuZXdUb3AgKz0gYm91bmRpbmdBcmVhLnJlY3QuaGVpZ2h0O1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gd2hpbGUgKGZvdW5kKTtcbiAgfVxuXG4gIHRvcENsaWVudFJlY3QudG9wID0gbmV3VG9wO1xuICB0b3BDbGllbnRSZWN0LmhlaWdodCA9IG1heEhlaWdodDtcblxuICByZXR1cm4gdG9wQ2xpZW50UmVjdDtcbn1cblxuZnVuY3Rpb24gaGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGxldCBpID0gLTE7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzLmZpbmQoKGgsIGopID0+IHtcbiAgICBpID0gajtcbiAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gIH0pO1xuICByZXR1cm4gaGlnaGxpZ2h0O1xufVxuXG5mdW5jdGlvbiBmcmFtZUZvckhpZ2hsaWdodFdpdGhJRChpZCkge1xuICBjb25zdCBoaWdobGlnaHQgPSBoaWdobGlnaHRXaXRoSUQoaWQpO1xuICBpZiAoIWhpZ2hsaWdodCkgcmV0dXJuO1xuXG4gIGNvbnN0IGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG4gIGNvbnN0IHJhbmdlID0gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgaGlnaGxpZ2h0LnJhbmdlSW5mbyk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgZHJhd1VuZGVybGluZSA9IGZhbHNlO1xuICBjb25zdCBkcmF3U3RyaWtlVGhyb3VnaCA9IGZhbHNlO1xuICBjb25zdCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gZHJhd1VuZGVybGluZSB8fCBkcmF3U3RyaWtlVGhyb3VnaDtcbiAgLy9jb25zdCBjbGllbnRSZWN0cyA9IERFQlVHX1ZJU1VBTFMgPyByYW5nZS5nZXRDbGllbnRSZWN0cygpIDpcbiAgY29uc3QgY2xpZW50UmVjdHMgPSBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgICByYW5nZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG5cbiAgcmV0dXJuIGNsaWVudFJlY3RzO1xufVxuXG5mdW5jdGlvbiByYW5nZUluZm8yTG9jYXRpb24ocmFuZ2VJbmZvKSB7XG4gIHJldHVybiB7XG4gICAgY3NzU2VsZWN0b3I6IHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICBwYXJ0aWFsQ2ZpOiByYW5nZUluZm8uY2ZpLFxuICAgIGRvbVJhbmdlOiB7XG4gICAgICBzdGFydDoge1xuICAgICAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgICAgICB0ZXh0Tm9kZUluZGV4OiByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgICAgIG9mZnNldDogcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgICAgfSxcbiAgICAgIGVuZDoge1xuICAgICAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcixcbiAgICAgICAgdGV4dE5vZGVJbmRleDogcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICAgICAgb2Zmc2V0OiByYW5nZUluZm8uZW5kT2Zmc2V0LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb24pIHtcbiAgY29uc3QgbG9jYXRpb25zID0gbG9jYXRpb24ubG9jYXRpb25zO1xuICBjb25zdCBkb21SYW5nZSA9IGxvY2F0aW9ucy5kb21SYW5nZTtcbiAgY29uc3Qgc3RhcnQgPSBkb21SYW5nZS5zdGFydDtcbiAgY29uc3QgZW5kID0gZG9tUmFuZ2UuZW5kO1xuXG4gIHJldHVybiB7XG4gICAgY2ZpOiBsb2NhdGlvbi5wYXJ0aWFsQ2ZpLFxuICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogZW5kLnRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBlbmQuY3NzU2VsZWN0b3IsXG4gICAgZW5kT2Zmc2V0OiBlbmQub2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBzdGFydC50ZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBzdGFydC5jc3NTZWxlY3RvcixcbiAgICBzdGFydE9mZnNldDogc3RhcnQub2Zmc2V0LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IGhpZ2hsaWdodFdpdGhJRChpZCk7XG4gIGlmICghaGlnaGxpZ2h0KSByZXR1cm47XG5cbiAgY29uc3QgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgcmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCBoaWdobGlnaHQucmFuZ2VJbmZvKTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgdmFyIHNpemUgPSB7XG4gICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgIHNjcmVlbkhlaWdodDogd2luZG93Lm91dGVySGVpZ2h0LFxuICAgIGxlZnQ6IGNsaWVudFJlY3RzWzBdLmxlZnQsXG4gICAgd2lkdGg6IGNsaWVudFJlY3RzWzBdLndpZHRoLFxuICAgIHRvcDogY2xpZW50UmVjdHNbMF0udG9wLFxuICAgIGhlaWdodDogY2xpZW50UmVjdHNbMF0uaGVpZ2h0LFxuICB9O1xuXG4gIHJldHVybiBzaXplO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0aW9uUmVjdCgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciByYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuXG4gICAgY29uc3QgY2xpZW50UmVjdCA9IHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdmFyIGhhbmRsZUJvdW5kcyA9IHtcbiAgICAgIHNjcmVlbldpZHRoOiB3aW5kb3cub3V0ZXJXaWR0aCxcbiAgICAgIHNjcmVlbkhlaWdodDogd2luZG93Lm91dGVySGVpZ2h0LFxuICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0LFxuICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICB0b3A6IGNsaWVudFJlY3QudG9wLFxuICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICB9O1xuICAgIHJldHVybiBoYW5kbGVCb3VuZHM7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0U2Nyb2xsTW9kZShmbGFnKSB7XG4gIGlmICghZmxhZykge1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX1BBR0lOQVRFRCk7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfUEFHSU5BVEVEKTtcbiAgfVxufVxuXG4vKlxuIGlmIChkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKSB7IC8vIElFID49IDk7IG90aGVyIGJyb3dzZXJzXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgLy9hbGVydChcIllvdSd2ZSB0cmllZCB0byBvcGVuIGNvbnRleHQgbWVudVwiKTsgLy9oZXJlIHlvdSBkcmF3IHlvdXIgb3duIG1lbnVcbiAgICAgICAgICAgIC8vZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgLy9sZXQgZ2V0Q3NzU2VsZWN0b3IgPSBmdWxsUXVhbGlmaWVkU2VsZWN0b3I7XG4gICAgICAgICAgICBcblx0XHRcdGxldCBzdHIgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG5cdFx0XHRsZXQgc2VsZWN0aW9uSW5mbyA9IGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvKCk7XG5cdFx0XHRsZXQgcG9zID0gY3JlYXRlSGlnaGxpZ2h0KHNlbGVjdGlvbkluZm8se3JlZDoxMCxncmVlbjo1MCxibHVlOjIzMH0sdHJ1ZSk7XG5cdFx0XHRsZXQgcmV0MiA9IGNyZWF0ZUFubm90YXRpb24ocG9zLmlkKTtcblx0XHRcdFxuICB9LCBmYWxzZSk7XG4gICAgfSBlbHNlIHsgLy8gSUUgPCA5XG4gICAgICAgIGRvY3VtZW50LmF0dGFjaEV2ZW50KCdvbmNvbnRleHRtZW51JywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBhbGVydChcIllvdSd2ZSB0cmllZCB0byBvcGVuIGNvbnRleHQgbWVudVwiKTtcbiAgICAgICAgICAgIHdpbmRvdy5ldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG4qL1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgbG9nIGFzIGxvZ05hdGl2ZSwgbG9nRXJyb3IsIHNuYXBDdXJyZW50T2Zmc2V0IH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IHRvTmF0aXZlUmVjdCB9IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IFRleHRSYW5nZSB9IGZyb20gXCIuL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90ZXh0LXJhbmdlXCI7XG5cbi8vIFBvbHlmaWxsIGZvciBBbmRyb2lkIEFQSSAyNlxuaW1wb3J0IG1hdGNoQWxsIGZyb20gXCJzdHJpbmcucHJvdG90eXBlLm1hdGNoYWxsXCI7XG5tYXRjaEFsbC5zaGltKCk7XG5cbmNvbnN0IGRlYnVnID0gdHJ1ZTtcblxuLy8gTm90aWZ5IG5hdGl2ZSBjb2RlIHRoYXQgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwibG9hZFwiLFxuICBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGlzU2VsZWN0aW5nID0gZmFsc2U7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2xsYXBzZWQgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuaXNDb2xsYXBzZWQ7XG5cbiAgICAgIGlmIChjb2xsYXBzZWQgJiYgaXNTZWxlY3RpbmcpIHtcbiAgICAgICAgaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgQW5kcm9pZC5vblNlbGVjdGlvbkVuZCgpO1xuICAgICAgICAvLyBTbmFwcyB0aGUgY3VycmVudCBjb2x1bW4gaW4gY2FzZSB0aGUgdXNlciBzaGlmdGVkIHRoZSBzY3JvbGwgYnkgZHJhZ2dpbmcgdGhlIHRleHQgc2VsZWN0aW9uLlxuICAgICAgICBzbmFwQ3VycmVudE9mZnNldCgpO1xuICAgICAgfSBlbHNlIGlmICghY29sbGFwc2VkICYmICFpc1NlbGVjdGluZykge1xuICAgICAgICBpc1NlbGVjdGluZyA9IHRydWU7XG4gICAgICAgIEFuZHJvaWQub25TZWxlY3Rpb25TdGFydCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICBmYWxzZVxuKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb24oKSB7XG4gIGNvbnN0IHRleHQgPSBnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCgpO1xuICBpZiAoIXRleHQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCByZWN0ID0gZ2V0U2VsZWN0aW9uUmVjdCgpO1xuICByZXR1cm4geyB0ZXh0LCByZWN0IH07XG59XG5cbmZ1bmN0aW9uIGdldFNlbGVjdGlvblJlY3QoKSB7XG4gIHRyeSB7XG4gICAgbGV0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmFuZ2UgPSBzZWwuZ2V0UmFuZ2VBdCgwKTtcblxuICAgIHJldHVybiB0b05hdGl2ZVJlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nRXJyb3IoZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvblRleHQoKSB7XG4gIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGhpZ2hsaWdodCA9IHNlbGVjdGlvbi50b1N0cmluZygpO1xuICBjb25zdCBjbGVhbkhpZ2hsaWdodCA9IGhpZ2hsaWdodFxuICAgIC50cmltKClcbiAgICAucmVwbGFjZSgvXFxuL2csIFwiIFwiKVxuICAgIC5yZXBsYWNlKC9cXHNcXHMrL2csIFwiIFwiKTtcbiAgaWYgKGNsZWFuSGlnaGxpZ2h0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFzZWxlY3Rpb24uYW5jaG9yTm9kZSB8fCAhc2VsZWN0aW9uLmZvY3VzTm9kZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2UgPVxuICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxXG4gICAgICA/IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApXG4gICAgICA6IGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0XG4gICAgICAgICk7XG4gIGlmICghcmFuZ2UgfHwgcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgbG9nKFwiJCQkJCQkJCQkJCQkJCQkJCQgQ0FOTk9UIEdFVCBOT04tQ09MTEFQU0VEIFNFTEVDVElPTiBSQU5HRT8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCB0ZXh0ID0gZG9jdW1lbnQuYm9keS50ZXh0Q29udGVudDtcbiAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhkb2N1bWVudC5ib2R5KTtcbiAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICBjb25zdCBlbmQgPSB0ZXh0UmFuZ2UuZW5kLm9mZnNldDtcblxuICBjb25zdCBzbmlwcGV0TGVuZ3RoID0gMjAwO1xuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYmVmb3JlIHRoZSBoaWdobGlnaHQsIGlnbm9yaW5nIHRoZSBmaXJzdCBcIndvcmRcIiwgd2hpY2ggbWlnaHQgYmUgY3V0LlxuICBsZXQgYmVmb3JlID0gdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIHNuaXBwZXRMZW5ndGgpLCBzdGFydCk7XG4gIGxldCBmaXJzdFdvcmRTdGFydCA9IGJlZm9yZS5zZWFyY2goL1xcUHtMfVxccHtMfS9ndSk7XG4gIGlmIChmaXJzdFdvcmRTdGFydCAhPT0gLTEpIHtcbiAgICBiZWZvcmUgPSBiZWZvcmUuc2xpY2UoZmlyc3RXb3JkU3RhcnQgKyAxKTtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYWZ0ZXIgdGhlIGhpZ2hsaWdodCwgaWdub3JpbmcgdGhlIGxhc3QgXCJ3b3JkXCIsIHdoaWNoIG1pZ2h0IGJlIGN1dC5cbiAgbGV0IGFmdGVyID0gdGV4dC5zbGljZShlbmQsIE1hdGgubWluKHRleHQubGVuZ3RoLCBlbmQgKyBzbmlwcGV0TGVuZ3RoKSk7XG4gIGxldCBsYXN0V29yZEVuZCA9IEFycmF5LmZyb20oYWZ0ZXIubWF0Y2hBbGwoL1xccHtMfVxcUHtMfS9ndSkpLnBvcCgpO1xuICBpZiAobGFzdFdvcmRFbmQgIT09IHVuZGVmaW5lZCAmJiBsYXN0V29yZEVuZC5pbmRleCA+IDEpIHtcbiAgICBhZnRlciA9IGFmdGVyLnNsaWNlKDAsIGxhc3RXb3JkRW5kLmluZGV4ICsgMSk7XG4gIH1cblxuICByZXR1cm4geyBoaWdobGlnaHQsIGJlZm9yZSwgYWZ0ZXIgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT3JkZXJlZFJhbmdlKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQsIGVuZE5vZGUsIGVuZE9mZnNldCkge1xuICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZS5zZXRTdGFydChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIGlmICghcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgQ09MTEFQU0VEIC4uLiBSQU5HRSBSRVZFUlNFP1wiKTtcbiAgY29uc3QgcmFuZ2VSZXZlcnNlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRTdGFydChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICByYW5nZVJldmVyc2Uuc2V0RW5kKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICBpZiAoIXJhbmdlUmV2ZXJzZS5jb2xsYXBzZWQpIHtcbiAgICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgT0suXCIpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgQUxTTyBDT0xMQVBTRUQ/IVwiKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIHJhbmdlSW5mbykge1xuICBjb25zdCBzdGFydEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIXN0YXJ0RWxlbWVudCkge1xuICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIFNUQVJUIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgc3RhcnRDb250YWluZXIgPSBzdGFydEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBzdGFydENvbnRhaW5lciA9XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCIpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgY29uc3QgZW5kRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIWVuZEVsZW1lbnQpIHtcbiAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBFTkQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBlbmRDb250YWluZXIgPSBlbmRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVuZENvbnRhaW5lciA9XG4gICAgICBlbmRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgIGVuZENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uZW5kT2Zmc2V0XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb24pIHtcbiAgY29uc3QgbG9jYXRpb25zID0gbG9jYXRpb24ubG9jYXRpb25zO1xuICBjb25zdCBkb21SYW5nZSA9IGxvY2F0aW9ucy5kb21SYW5nZTtcbiAgY29uc3Qgc3RhcnQgPSBkb21SYW5nZS5zdGFydDtcbiAgY29uc3QgZW5kID0gZG9tUmFuZ2UuZW5kO1xuXG4gIHJldHVybiB7XG4gICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBlbmQudGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IGVuZC5jc3NTZWxlY3RvcixcbiAgICBlbmRPZmZzZXQ6IGVuZC5vZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IHN0YXJ0LnRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IHN0YXJ0LmNzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiBzdGFydC5vZmZzZXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgbG9nTmF0aXZlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIEJhc2Ugc2NyaXB0IHVzZWQgYnkgYm90aCByZWZsb3dhYmxlIGFuZCBmaXhlZCBsYXlvdXQgcmVzb3VyY2VzLlxuXG5pbXBvcnQgXCIuL2dlc3R1cmVzXCI7XG5pbXBvcnQgXCIuL2tleWJvYXJkXCI7XG5pbXBvcnQge1xuICByZW1vdmVQcm9wZXJ0eSxcbiAgc2Nyb2xsTGVmdCxcbiAgc2Nyb2xsUmlnaHQsXG4gIHNjcm9sbFRvRW5kLFxuICBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1Bvc2l0aW9uLFxuICBzY3JvbGxUb1N0YXJ0LFxuICBzY3JvbGxUb1RleHQsXG4gIHNldFByb3BlcnR5LFxuICBzZXRDU1NQcm9wZXJ0aWVzLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgY3JlYXRlQW5ub3RhdGlvbixcbiAgY3JlYXRlSGlnaGxpZ2h0LFxuICBkZXN0cm95SGlnaGxpZ2h0LFxuICBnZXRDdXJyZW50U2VsZWN0aW9uSW5mbyxcbiAgZ2V0U2VsZWN0aW9uUmVjdCxcbiAgcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElELFxuICBzZXRTY3JvbGxNb2RlLFxufSBmcm9tIFwiLi9oaWdobGlnaHRcIjtcbmltcG9ydCB7IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yIH0gZnJvbSBcIi4vZG9tXCI7XG5pbXBvcnQgeyBnZXRDdXJyZW50U2VsZWN0aW9uIH0gZnJvbSBcIi4vc2VsZWN0aW9uXCI7XG5pbXBvcnQgeyBnZXREZWNvcmF0aW9ucywgcmVnaXN0ZXJUZW1wbGF0ZXMgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcblxuLy8gUHVibGljIEFQSSB1c2VkIGJ5IHRoZSBuYXZpZ2F0b3IuXG53aW5kb3cucmVhZGl1bSA9IHtcbiAgLy8gdXRpbHNcbiAgc2Nyb2xsVG9JZDogc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9Qb3NpdGlvbjogc2Nyb2xsVG9Qb3NpdGlvbixcbiAgc2Nyb2xsVG9UZXh0OiBzY3JvbGxUb1RleHQsXG4gIHNjcm9sbExlZnQ6IHNjcm9sbExlZnQsXG4gIHNjcm9sbFJpZ2h0OiBzY3JvbGxSaWdodCxcbiAgc2Nyb2xsVG9TdGFydDogc2Nyb2xsVG9TdGFydCxcbiAgc2Nyb2xsVG9FbmQ6IHNjcm9sbFRvRW5kLFxuICBzZXRDU1NQcm9wZXJ0aWVzOiBzZXRDU1NQcm9wZXJ0aWVzLFxuICBzZXRQcm9wZXJ0eTogc2V0UHJvcGVydHksXG4gIHJlbW92ZVByb3BlcnR5OiByZW1vdmVQcm9wZXJ0eSxcblxuICAvLyBzZWxlY3Rpb25cbiAgZ2V0Q3VycmVudFNlbGVjdGlvbjogZ2V0Q3VycmVudFNlbGVjdGlvbixcblxuICAvLyBkZWNvcmF0aW9uXG4gIHJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlczogcmVnaXN0ZXJUZW1wbGF0ZXMsXG4gIGdldERlY29yYXRpb25zOiBnZXREZWNvcmF0aW9ucyxcblxuICAvLyBET01cbiAgZmluZEZpcnN0VmlzaWJsZUxvY2F0b3I6IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yLFxufTtcblxuLy8gTGVnYWN5IGhpZ2hsaWdodHMgQVBJLlxud2luZG93LmNyZWF0ZUFubm90YXRpb24gPSBjcmVhdGVBbm5vdGF0aW9uO1xud2luZG93LmNyZWF0ZUhpZ2hsaWdodCA9IGNyZWF0ZUhpZ2hsaWdodDtcbndpbmRvdy5kZXN0cm95SGlnaGxpZ2h0ID0gZGVzdHJveUhpZ2hsaWdodDtcbndpbmRvdy5nZXRDdXJyZW50U2VsZWN0aW9uSW5mbyA9IGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvO1xud2luZG93LmdldFNlbGVjdGlvblJlY3QgPSBnZXRTZWxlY3Rpb25SZWN0O1xud2luZG93LnJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRCA9IHJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRDtcbndpbmRvdy5zZXRTY3JvbGxNb2RlID0gc2V0U2Nyb2xsTW9kZTtcbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIFNjcmlwdCB1c2VkIGZvciBmaXhlZCBsYXlvdXRzIHJlc291cmNlcy5cblxuaW1wb3J0IFwiLi9pbmRleFwiO1xuXG53aW5kb3cucmVhZGl1bS5pc0ZpeGVkTGF5b3V0ID0gdHJ1ZTtcbiJdLCJuYW1lcyI6WyJhcHByb3hTZWFyY2giLCJzZWFyY2giLCJ0ZXh0Iiwic3RyIiwibWF4RXJyb3JzIiwibWF0Y2hQb3MiLCJleGFjdE1hdGNoZXMiLCJpbmRleE9mIiwicHVzaCIsInN0YXJ0IiwiZW5kIiwibGVuZ3RoIiwiZXJyb3JzIiwidGV4dE1hdGNoU2NvcmUiLCJtYXRjaGVzIiwibWF0Y2hRdW90ZSIsInF1b3RlIiwiY29udGV4dCIsIk1hdGgiLCJtaW4iLCJzY29yZU1hdGNoIiwibWF0Y2giLCJxdW90ZVdlaWdodCIsInByZWZpeFdlaWdodCIsInN1ZmZpeFdlaWdodCIsInBvc1dlaWdodCIsInF1b3RlU2NvcmUiLCJwcmVmaXhTY29yZSIsInByZWZpeCIsInNsaWNlIiwibWF4Iiwic3VmZml4U2NvcmUiLCJzdWZmaXgiLCJwb3NTY29yZSIsImhpbnQiLCJvZmZzZXQiLCJhYnMiLCJyYXdTY29yZSIsIm1heFNjb3JlIiwibm9ybWFsaXplZFNjb3JlIiwic2NvcmVkTWF0Y2hlcyIsIm1hcCIsIm0iLCJzY29yZSIsInNvcnQiLCJhIiwiYiIsIm5vZGVUZXh0TGVuZ3RoIiwibm9kZSIsIm5vZGVUeXBlIiwiTm9kZSIsIkVMRU1FTlRfTk9ERSIsIlRFWFRfTk9ERSIsInRleHRDb250ZW50IiwicHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgiLCJzaWJsaW5nIiwicHJldmlvdXNTaWJsaW5nIiwicmVzb2x2ZU9mZnNldHMiLCJlbGVtZW50Iiwib2Zmc2V0cyIsIm5leHRPZmZzZXQiLCJzaGlmdCIsIm5vZGVJdGVyIiwib3duZXJEb2N1bWVudCIsImNyZWF0ZU5vZGVJdGVyYXRvciIsIk5vZGVGaWx0ZXIiLCJTSE9XX1RFWFQiLCJyZXN1bHRzIiwiY3VycmVudE5vZGUiLCJuZXh0Tm9kZSIsInRleHROb2RlIiwidW5kZWZpbmVkIiwiZGF0YSIsIlJhbmdlRXJyb3IiLCJSRVNPTFZFX0ZPUldBUkRTIiwiUkVTT0xWRV9CQUNLV0FSRFMiLCJUZXh0UG9zaXRpb24iLCJFcnJvciIsInBhcmVudCIsImNvbnRhaW5zIiwiZWwiLCJwYXJlbnRFbGVtZW50Iiwib3B0aW9ucyIsImVyciIsImRpcmVjdGlvbiIsInR3IiwiZG9jdW1lbnQiLCJjcmVhdGVUcmVlV2Fsa2VyIiwiZ2V0Um9vdE5vZGUiLCJmb3J3YXJkcyIsInByZXZpb3VzTm9kZSIsImZyb21Qb2ludCIsInRleHRPZmZzZXQiLCJjaGlsZE5vZGVzIiwiaSIsIlRleHRSYW5nZSIsInJlbGF0aXZlVG8iLCJyZXNvbHZlIiwicmFuZ2UiLCJSYW5nZSIsInNldFN0YXJ0Iiwic2V0RW5kIiwic3RhcnRDb250YWluZXIiLCJzdGFydE9mZnNldCIsImVuZENvbnRhaW5lciIsImVuZE9mZnNldCIsInJvb3QiLCJub2RlRnJvbVhQYXRoIiwieHBhdGhGcm9tTm9kZSIsIlJhbmdlQW5jaG9yIiwibm9ybWFsaXplZFJhbmdlIiwiZnJvbVJhbmdlIiwidG9SYW5nZSIsInRleHRSYW5nZSIsInR5cGUiLCJzZWxlY3RvciIsInN0YXJ0UG9zIiwiZnJvbUNoYXJPZmZzZXQiLCJlbmRQb3MiLCJUZXh0UG9zaXRpb25BbmNob3IiLCJmcm9tT2Zmc2V0cyIsIlRleHRRdW90ZUFuY2hvciIsImV4YWN0IiwidG9Qb3NpdGlvbkFuY2hvciIsImNvbnRleHRMZW4iLCJ3aW5kb3ciLCJhZGRFdmVudExpc3RlbmVyIiwiZXZlbnQiLCJBbmRyb2lkIiwibG9nRXJyb3IiLCJtZXNzYWdlIiwiZmlsZW5hbWUiLCJsaW5lbm8iLCJvYnNlcnZlciIsIlJlc2l6ZU9ic2VydmVyIiwib25WaWV3cG9ydFdpZHRoQ2hhbmdlZCIsInNuYXBDdXJyZW50T2Zmc2V0Iiwib2JzZXJ2ZSIsImJvZHkiLCJhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQiLCJpZCIsInZpcnR1YWxDb2wiLCJnZXRFbGVtZW50QnlJZCIsImlzU2Nyb2xsTW9kZUVuYWJsZWQiLCJnZXRDb2x1bW5Db3VudFBlclNjcmVlbiIsInJlbW92ZSIsImRvY3VtZW50V2lkdGgiLCJzY3JvbGxpbmdFbGVtZW50Iiwic2Nyb2xsV2lkdGgiLCJjb2xDb3VudCIsInBhZ2VXaWR0aCIsImhhc09kZENvbENvdW50Iiwicm91bmQiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwic3R5bGUiLCJicmVha0JlZm9yZSIsImlubmVySFRNTCIsImFwcGVuZENoaWxkIiwid2lkdGgiLCJnZXRWaWV3cG9ydFdpZHRoIiwiZGV2aWNlUGl4ZWxSYXRpbyIsInNldFByb3BlcnR5IiwicGFyc2VJbnQiLCJnZXRDb21wdXRlZFN0eWxlIiwiZG9jdW1lbnRFbGVtZW50IiwiZ2V0UHJvcGVydHlWYWx1ZSIsInRyaW0iLCJpc1JUTCIsImRpciIsInRvTG93ZXJDYXNlIiwic2Nyb2xsVG9JZCIsInNjcm9sbFRvUmVjdCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInNjcm9sbFRvUG9zaXRpb24iLCJwb3NpdGlvbiIsInNjcm9sbEhlaWdodCIsInNjcm9sbFRvcCIsImZhY3RvciIsInNjcm9sbExlZnQiLCJzbmFwT2Zmc2V0Iiwic2Nyb2xsVG9UZXh0IiwicmFuZ2VGcm9tTG9jYXRvciIsInNjcm9sbFRvUmFuZ2UiLCJyZWN0IiwidG9wIiwic2Nyb2xsWSIsImlubmVySGVpZ2h0IiwibGVmdCIsInNjcm9sbFgiLCJzY3JvbGxUb1N0YXJ0Iiwic2Nyb2xsVG8iLCJzY3JvbGxUb0VuZCIsIm1pbk9mZnNldCIsInNjcm9sbFRvT2Zmc2V0Iiwic2Nyb2xsUmlnaHQiLCJtYXhPZmZzZXQiLCJjdXJyZW50T2Zmc2V0IiwiZGlmZiIsInZhbHVlIiwiZGVsdGEiLCJsb2NhdG9yIiwibG9jYXRpb25zIiwiaGlnaGxpZ2h0IiwiY3NzU2VsZWN0b3IiLCJxdWVyeVNlbGVjdG9yIiwiYW5jaG9yIiwiYmVmb3JlIiwiYWZ0ZXIiLCJmcmFnbWVudHMiLCJodG1sSWQiLCJjcmVhdGVSYW5nZSIsInNldFN0YXJ0QmVmb3JlIiwic2V0RW5kQWZ0ZXIiLCJlIiwic2V0Q1NTUHJvcGVydGllcyIsInByb3BlcnRpZXMiLCJuYW1lIiwia2V5IiwicmVtb3ZlUHJvcGVydHkiLCJsb2ciLCJBcnJheSIsInByb3RvdHlwZSIsImNhbGwiLCJhcmd1bWVudHMiLCJqb2luIiwibG9nTmF0aXZlIiwiZGVidWciLCJ0b05hdGl2ZVJlY3QiLCJwaXhlbFJhdGlvIiwiaGVpZ2h0IiwicmlnaHQiLCJib3R0b20iLCJnZXRDbGllbnRSZWN0c05vT3ZlcmxhcCIsImRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMiLCJjbGllbnRSZWN0cyIsImdldENsaWVudFJlY3RzIiwidG9sZXJhbmNlIiwib3JpZ2luYWxSZWN0cyIsInJhbmdlQ2xpZW50UmVjdCIsIm1lcmdlZFJlY3RzIiwibWVyZ2VUb3VjaGluZ1JlY3RzIiwibm9Db250YWluZWRSZWN0cyIsInJlbW92ZUNvbnRhaW5lZFJlY3RzIiwibmV3UmVjdHMiLCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIiwibWluQXJlYSIsImoiLCJiaWdFbm91Z2giLCJzcGxpY2UiLCJyZWN0cyIsInJlY3QxIiwicmVjdDIiLCJyZWN0c0xpbmVVcFZlcnRpY2FsbHkiLCJhbG1vc3RFcXVhbCIsInJlY3RzTGluZVVwSG9yaXpvbnRhbGx5IiwiaG9yaXpvbnRhbEFsbG93ZWQiLCJhbGlnbmVkIiwiY2FuTWVyZ2UiLCJyZWN0c1RvdWNoT3JPdmVybGFwIiwiZmlsdGVyIiwicmVwbGFjZW1lbnRDbGllbnRSZWN0IiwiZ2V0Qm91bmRpbmdSZWN0IiwicmVjdHNUb0tlZXAiLCJTZXQiLCJkZWxldGUiLCJwb3NzaWJseUNvbnRhaW5pbmdSZWN0IiwiaGFzIiwicmVjdENvbnRhaW5zIiwiZnJvbSIsInJlY3RDb250YWluc1BvaW50IiwieCIsInkiLCJ0b0FkZCIsInRvUmVtb3ZlIiwic3VidHJhY3RSZWN0czEiLCJyZWN0U3VidHJhY3QiLCJzdWJ0cmFjdFJlY3RzMiIsImFwcGx5IiwicmVjdEludGVyc2VjdGVkIiwicmVjdEludGVyc2VjdCIsInJlY3RBIiwicmVjdEIiLCJyZWN0QyIsInJlY3REIiwibWF4TGVmdCIsIm1pblJpZ2h0IiwibWF4VG9wIiwibWluQm90dG9tIiwic3R5bGVzIiwiTWFwIiwiZ3JvdXBzIiwibGFzdEdyb3VwSWQiLCJyZWdpc3RlclRlbXBsYXRlcyIsIm5ld1N0eWxlcyIsInN0eWxlc2hlZXQiLCJPYmplY3QiLCJlbnRyaWVzIiwic2V0Iiwic3R5bGVFbGVtZW50IiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJnZXREZWNvcmF0aW9ucyIsImdyb3VwTmFtZSIsImdyb3VwIiwiZ2V0IiwiRGVjb3JhdGlvbkdyb3VwIiwiaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQiLCJjbGlja0V2ZW50Iiwic2l6ZSIsImZpbmRUYXJnZXQiLCJncm91cENvbnRlbnQiLCJpdGVtcyIsInJldmVyc2UiLCJpdGVtIiwiY2xpY2thYmxlRWxlbWVudHMiLCJ0b0pTT04iLCJjbGllbnRYIiwiY2xpZW50WSIsInRhcmdldCIsIm9uRGVjb3JhdGlvbkFjdGl2YXRlZCIsIkpTT04iLCJzdHJpbmdpZnkiLCJkZWNvcmF0aW9uIiwiY2xpY2siLCJncm91cElkIiwibGFzdEl0ZW1JZCIsImNvbnRhaW5lciIsImFkZCIsImxheW91dCIsImRlY29yYXRpb25JZCIsImluZGV4IiwiZmluZEluZGV4IiwidXBkYXRlIiwiY2xlYXIiLCJjbGVhckNvbnRhaW5lciIsInJlcXVlc3RMYXlvdXQiLCJmb3JFYWNoIiwiZ3JvdXBDb250YWluZXIiLCJyZXF1aXJlQ29udGFpbmVyIiwiaXRlbUNvbnRhaW5lciIsInZpZXdwb3J0V2lkdGgiLCJpbm5lcldpZHRoIiwiY29sdW1uQ291bnQiLCJ4T2Zmc2V0IiwieU9mZnNldCIsInBvc2l0aW9uRWxlbWVudCIsImJvdW5kaW5nUmVjdCIsImZsb29yIiwiZWxlbWVudFRlbXBsYXRlIiwidGVtcGxhdGUiLCJjb250ZW50IiwiZmlyc3RFbGVtZW50Q2hpbGQiLCJlcnJvciIsInIxIiwicjIiLCJjbGllbnRSZWN0IiwibGluZSIsImNsb25lTm9kZSIsImFwcGVuZCIsImJvdW5kcyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJjaGlsZHJlbiIsImxhc3RTaXplIiwiY2xpZW50V2lkdGgiLCJjbGllbnRIZWlnaHQiLCJnZXRDc3NTZWxlY3RvciIsIm5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQiLCJpbnRlcmFjdGl2ZVRhZ3MiLCJub2RlTmFtZSIsIm91dGVySFRNTCIsImhhc0F0dHJpYnV0ZSIsImdldEF0dHJpYnV0ZSIsImZpbmRGaXJzdFZpc2libGVMb2NhdG9yIiwiZmluZEVsZW1lbnQiLCJocmVmIiwicm9vdEVsZW1lbnQiLCJjaGlsZCIsInNob3VsZElnbm9yZUVsZW1lbnQiLCJpc0VsZW1lbnRWaXNpYmxlIiwicmVhZGl1bSIsImlzRml4ZWRMYXlvdXQiLCJlbFN0eWxlIiwiZGlzcGxheSIsIm9wYWNpdHkiLCJvbkNsaWNrIiwiYmluZERyYWdHZXN0dXJlIiwiZ2V0U2VsZWN0aW9uIiwiaXNDb2xsYXBzZWQiLCJkZWZhdWx0UHJldmVudGVkIiwidGFyZ2V0RWxlbWVudCIsImludGVyYWN0aXZlRWxlbWVudCIsInNob3VsZFByZXZlbnREZWZhdWx0Iiwib25UYXAiLCJzdG9wUHJvcGFnYXRpb24iLCJwcmV2ZW50RGVmYXVsdCIsIm9uU3RhcnQiLCJwYXNzaXZlIiwib25FbmQiLCJvbk1vdmUiLCJzdGF0ZSIsImlzU3RhcnRpbmdEcmFnIiwic3RhcnRYIiwidG91Y2hlcyIsInN0YXJ0WSIsImN1cnJlbnRYIiwiY3VycmVudFkiLCJvZmZzZXRYIiwib2Zmc2V0WSIsIm9uRHJhZ1N0YXJ0Iiwib25EcmFnTW92ZSIsIm9uRHJhZ0VuZCIsInNob3VsZElnbm9yZUV2ZW50Iiwic2VuZFByZXNzS2V5TWVzc2FnZSIsImFjdGl2ZUVsZW1lbnQiLCJyZXBlYXQiLCJrZXlFdmVudCIsImNvZGUiLCJjaGFyYWN0ZXJzIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwia2V5Q29kZSIsImFsdCIsImFsdEtleSIsImNvbnRyb2wiLCJjdHJsS2V5Iiwic2hpZnRLZXkiLCJtZXRhIiwibWV0YUtleSIsIm9uS2V5IiwiUk9PVF9DTEFTU19SRURVQ0VfTU9USU9OIiwiUk9PVF9DTEFTU19OT19GT09UTk9URVMiLCJQT1BVUF9ESUFMT0dfQ0xBU1MiLCJGT09UTk9URVNfQ09OVEFJTkVSX0NMQVNTIiwiRk9PVE5PVEVTX0NMT1NFX0JVVFRPTl9DTEFTUyIsIkZPT1ROT1RFX0ZPUkNFX1NIT1ciLCJUVFNfSURfUFJFVklPVVMiLCJUVFNfSURfTkVYVCIsIlRUU19JRF9TTElERVIiLCJUVFNfSURfQUNUSVZFX1dPUkQiLCJUVFNfSURfQ09OVEFJTkVSIiwiVFRTX0lEX0lORk8iLCJUVFNfTkFWX0JVVFRPTl9DTEFTUyIsIlRUU19JRF9TUEVBS0lOR19ET0NfRUxFTUVOVCIsIlRUU19DTEFTU19JTkpFQ1RFRF9TUEFOIiwiVFRTX0NMQVNTX0lOSkVDVEVEX1NVQlNQQU4iLCJUVFNfSURfSU5KRUNURURfUEFSRU5UIiwiSURfSElHSExJR0hUU19DT05UQUlORVIiLCJJRF9BTk5PVEFUSU9OX0NPTlRBSU5FUiIsIkNMQVNTX0hJR0hMSUdIVF9DT05UQUlORVIiLCJDTEFTU19BTk5PVEFUSU9OX0NPTlRBSU5FUiIsIkNMQVNTX0hJR0hMSUdIVF9BUkVBIiwiQ0xBU1NfQU5OT1RBVElPTl9BUkVBIiwiQ0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUEiLCJDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUEiLCJfYmxhY2tsaXN0SWRDbGFzc0ZvckNGSSIsIkNMQVNTX1BBR0lOQVRFRCIsIklTX0RFViIsIl9oaWdobGlnaHRzIiwiX2hpZ2hsaWdodHNDb250YWluZXIiLCJfYW5ub3RhdGlvbkNvbnRhaW5lciIsImxhc3RNb3VzZURvd25YIiwibGFzdE1vdXNlRG93blkiLCJib2R5RXZlbnRMaXN0ZW5lcnNTZXQiLCJVU0VfU1ZHIiwiREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkiLCJBTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZIiwiREVCVUdfVklTVUFMUyIsIkRFRkFVTFRfQkFDS0dST1VORF9DT0xPUiIsImJsdWUiLCJncmVlbiIsInJlZCIsIkFOTk9UQVRJT05fV0lEVEgiLCJyZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUiLCJfd2luIiwiaGlnaGxpZ2h0Qm91bmRpbmciLCJvdXRsaW5lIiwic2V0SGlnaGxpZ2h0QXJlYVN0eWxlIiwid2luIiwiaGlnaGxpZ2h0QXJlYXMiLCJ1c2VTVkciLCJoaWdobGlnaHRBcmVhIiwiaXNTVkciLCJuYW1lc3BhY2VVUkkiLCJTVkdfWE1MX05BTUVTUEFDRSIsImNvbG9yIiwicmVzZXRIaWdobGlnaHRBcmVhU3R5bGUiLCJwYXJlbnROb2RlIiwiZmluZCIsImgiLCJwcm9jZXNzVG91Y2hFdmVudCIsImV2Iiwic2Nyb2xsRWxlbWVudCIsImdldFNjcm9sbGluZ0VsZW1lbnQiLCJjaGFuZ2VkVG91Y2hlcyIsInBhZ2luYXRlZCIsImlzUGFnaW5hdGVkIiwiYm9keVJlY3QiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJmb3VuZEhpZ2hsaWdodCIsImZvdW5kRWxlbWVudCIsImZvdW5kUmVjdCIsImhpZ2hsaWdodFBhcmVudCIsImhpdCIsImhpZ2hsaWdodEZyYWdtZW50cyIsImhpZ2hsaWdodEZyYWdtZW50Iiwid2l0aFJlY3QiLCJoaWdobGlnaHRCb3VuZGluZ3MiLCJhbGxIaWdobGlnaHRBcmVhcyIsImZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzIiwiZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmciLCJhbGxIaWdobGlnaHRCb3VuZGluZ3MiLCJzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlIiwic2NyZWVuV2lkdGgiLCJvdXRlcldpZHRoIiwic2NyZWVuSGVpZ2h0Iiwib3V0ZXJIZWlnaHQiLCJwYXlsb2FkIiwicHJvY2VzcyIsImVsZWN0cm9uXzEiLCJpcGNSZW5kZXJlciIsInNlbmRUb0hvc3QiLCJSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0siLCJ3ZWJraXRVUkwiLCJjb25zb2xlIiwiaW5jbHVkZXMiLCJoaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZCIsIndlYmtpdCIsIm1lc3NhZ2VIYW5kbGVycyIsInBvc3RNZXNzYWdlIiwiaGlnaGxpZ2h0QWN0aXZhdGVkIiwicHJvY2Vzc01vdXNlRXZlbnQiLCJ0b3VjaGVkUG9zaXRpb24iLCJ0b1ByZXNlcnZlIiwidG9DaGVjayIsImNoZWNrT3ZlcmxhcHMiLCJzdGlsbE92ZXJsYXBpbmdSZWN0cyIsImhhczEiLCJoYXMyIiwieE92ZXJsYXAiLCJnZXRSZWN0T3ZlcmxhcFgiLCJ5T3ZlcmxhcCIsImdldFJlY3RPdmVybGFwWSIsInJhbmdlQ2xpZW50UmVjdHMiLCJnZXRDbGllbnRSZWN0c05vT3ZlcmxhcF8iLCJjbGFzc0xpc3QiLCJlbnN1cmVDb250YWluZXIiLCJhbm5vdGF0aW9uRmxhZyIsInRvdWNoRW5kIiwiaGlkZUFsbGhpZ2hsaWdodHMiLCJkZXN0cm95QWxsaGlnaGxpZ2h0cyIsImRlc3Ryb3lIaWdobGlnaHQiLCJfZG9jdW1lbnQiLCJoaWdobGlnaHRDb250YWluZXIiLCJpc0NmaVRleHROb2RlIiwiZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4IiwiZm91bmQiLCJ0ZXh0Tm9kZUluZGV4IiwicHJldmlvdXNXYXNFbGVtZW50IiwiY2hpbGROb2RlIiwiaXNUZXh0IiwiZ2V0Q29tbW9uQW5jZXN0b3JFbGVtZW50Iiwibm9kZTEiLCJub2RlMiIsIm5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4iLCJub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluIiwiY29tbW9uQW5jZXN0b3IiLCJub2RlMUVsZW1lbnRBbmNlc3RvciIsIm5vZGUyRWxlbWVudEFuY2VzdG9yIiwiZnVsbFF1YWxpZmllZFNlbGVjdG9yIiwibG93ZXJDYXNlTmFtZSIsImxvY2FsTmFtZSIsImNzc1BhdGgiLCJnZXRDdXJyZW50U2VsZWN0aW9uSW5mbyIsInNlbGVjdGlvbiIsInJhd1RleHQiLCJ0b1N0cmluZyIsImNsZWFuVGV4dCIsInJlcGxhY2UiLCJhbmNob3JOb2RlIiwiZm9jdXNOb2RlIiwicmFuZ2VDb3VudCIsImdldFJhbmdlQXQiLCJjcmVhdGVPcmRlcmVkUmFuZ2UiLCJhbmNob3JPZmZzZXQiLCJmb2N1c09mZnNldCIsImNvbGxhcHNlZCIsInJhbmdlSW5mbyIsImNvbnZlcnRSYW5nZSIsImNvbXB1dGVDRkkiLCJyZXN0b3JlZFJhbmdlIiwiY29udmVydFJhbmdlSW5mbyIsImR1bXBEZWJ1ZyIsInJhbmdlSW5mbzJMb2NhdGlvbiIsImNoZWNrQmxhY2tsaXN0ZWQiLCJibGFja2xpc3RlZElkIiwiYmxhY2tsaXN0ZWRDbGFzcyIsIm9wdGltaXplZCIsInN0ZXBzIiwiY29udGV4dE5vZGUiLCJzdGVwIiwiX2Nzc1BhdGhTdGVwIiwiaXNUYXJnZXROb2RlIiwicHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyIsIm5kIiwiY2xhc3NBdHRyaWJ1dGUiLCJzcGxpdCIsIkJvb2xlYW4iLCJubSIsImlkU2VsZWN0b3IiLCJpZGQiLCJlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQiLCJpZGVudCIsImlzQ1NTSWRlbnRpZmllciIsInNob3VsZEVzY2FwZUZpcnN0IiwidGVzdCIsImxhc3RJbmRleCIsImMiLCJpaSIsImlzQ1NTSWRlbnRDaGFyIiwiZXNjYXBlQXNjaWlDaGFyIiwiaXNMYXN0IiwidG9IZXhCeXRlIiwiaGV4Qnl0ZSIsImNoYXJDb2RlQXQiLCJET0NVTUVOVF9OT0RFIiwicHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXlfIiwicHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkiLCJhcnJJdGVtIiwibmVlZHNDbGFzc05hbWVzIiwibmVlZHNOdGhDaGlsZCIsIm93bkluZGV4IiwiZWxlbWVudEluZGV4Iiwic2libGluZ3MiLCJzaWJsaW5nTmFtZSIsIm93bkNsYXNzTmFtZXMiLCJvd25DbGFzc05hbWVDb3VudCIsInNpYmxpbmdDbGFzc05hbWVzQXJyYXlfIiwic2libGluZ0NsYXNzTmFtZXNBcnJheSIsInNpYmxpbmdDbGFzcyIsImluZCIsInJlc3VsdCIsInByZWZpeGVkTmFtZSIsInN1YnN0ciIsImNmaSIsImN1cnJlbnRFbGVtZW50IiwiYmxhY2tsaXN0ZWQiLCJjdXJyZW50RWxlbWVudFBhcmVudENoaWxkcmVuIiwiY3VycmVudEVsZW1lbnRJbmRleCIsImNmaUluZGV4IiwiX2NyZWF0ZUhpZ2hsaWdodCIsInBvaW50ZXJJbnRlcmFjdGlvbiIsImxvY2F0aW9uMlJhbmdlSW5mbyIsInVuaXF1ZVN0ciIsInN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yIiwic3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgiLCJlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IiLCJlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgiLCJoYXNoIiwicmVxdWlyZSIsInNoYTI1NkhleCIsInNoYTI1NiIsImRpZ2VzdCIsImNyZWF0ZUhpZ2hsaWdodERvbSIsImNyZWF0ZUhpZ2hsaWdodCIsInNlbGVjdGlvbkluZm8iLCJjcmVhdGVBbm5vdGF0aW9uIiwic2NhbGUiLCJSRUFESVVNMiIsImZ4bFZpZXdwb3J0U2NhbGUiLCJoaWdobGlnaHRzQ29udGFpbmVyIiwiZHJhd1VuZGVybGluZSIsImRyYXdTdHJpa2VUaHJvdWdoIiwiaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWciLCJyb3VuZGVkQ29ybmVyIiwidW5kZXJsaW5lVGhpY2tuZXNzIiwic3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MiLCJleHRyYSIsInJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdCIsImZyYW1lRm9ySGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtXaXRoSUQiLCJhbm5vdGF0aW9uT2Zmc2V0IiwiYm9yZGVyVGhpY2tuZXNzIiwiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCIsImhpZ2hsaWdodEFyZWFTVkdSZWN0IiwiY3JlYXRlRWxlbWVudE5TIiwiaGlnaGxpZ2h0QXJlYVNWR0xpbmUiLCJsaW5lT2Zmc2V0IiwicmdiIiwicmFuZG9tIiwiciIsImciLCJoaWdobGlnaHRBcmVhTGluZSIsImhpZ2hsaWdodEFyZWFTVkciLCJvdmVyZmxvdyIsInJhbmdlQm91bmRpbmdDbGllbnRSZWN0Iiwic3RhcnROb2RlIiwiZW5kTm9kZSIsInJhbmdlUmV2ZXJzZSIsImNvbXB1dGVFbGVtZW50Q0ZJIiwic3RhcnRJc0VsZW1lbnQiLCJzdGFydENvbnRhaW5lckVsZW1lbnQiLCJlbmRJc0VsZW1lbnQiLCJlbmRDb250YWluZXJFbGVtZW50IiwiY29tbW9uRWxlbWVudEFuY2VzdG9yIiwiY29tbW9uQW5jZXN0b3JDb250YWluZXIiLCJyYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCIsInJvb3RFbGVtZW50Q2ZpIiwic3RhcnRFbGVtZW50Q2ZpIiwiZW5kRWxlbWVudENmaSIsInN0YXJ0RWxlbWVudE9yVGV4dENmaSIsInN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpIiwiY2ZpVGV4dE5vZGVJbmRleCIsImNmaUluZGV4T2ZMYXN0RWxlbWVudCIsImNoaWxkRWxlbWVudENvdW50IiwibGFzdENoaWxkTm9kZSIsImVuZEVsZW1lbnRPclRleHRDZmkiLCJlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkiLCJzdGFydEVsZW1lbnQiLCJlbmRFbGVtZW50IiwiZnJhbWVGb3JIaWdobGlnaHRXaXRoSUQiLCJ0b3BDbGllbnRSZWN0IiwibWF4SGVpZ2h0IiwibmV3VG9wIiwiYm91bmRpbmdBcmVhcyIsImdldEVsZW1lbnRzQnlDbGFzc05hbWUiLCJsZW4iLCJib3VuZGluZ0FyZWEiLCJoaWdobGlnaHRXaXRoSUQiLCJwYXJ0aWFsQ2ZpIiwiZG9tUmFuZ2UiLCJsb2NhdGlvbiIsInJlY3RhbmdsZUZvckhpZ2hsaWdodFdpdGhJRCIsImdldFNlbGVjdGlvblJlY3QiLCJzZWwiLCJoYW5kbGVCb3VuZHMiLCJzZXRTY3JvbGxNb2RlIiwiZmxhZyIsIm1hdGNoQWxsIiwic2hpbSIsImlzU2VsZWN0aW5nIiwib25TZWxlY3Rpb25FbmQiLCJvblNlbGVjdGlvblN0YXJ0IiwiZ2V0Q3VycmVudFNlbGVjdGlvbiIsImdldEN1cnJlbnRTZWxlY3Rpb25UZXh0IiwiY2xlYW5IaWdobGlnaHQiLCJzbmlwcGV0TGVuZ3RoIiwiZmlyc3RXb3JkU3RhcnQiLCJsYXN0V29yZEVuZCIsInBvcCIsInJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlcyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3088\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjEwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsOENBQThDO0FBQ2hGLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1YsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUEsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEMsdURBQXVELHVCQUF1Qjs7QUFFOUU7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRCxHQUFHO0FBQ0gsZ0RBQWdEO0FBQ2hELEdBQUc7QUFDSCxzREFBc0Q7QUFDdEQsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFdBQVcsbUJBQU8sQ0FBQyxJQUFlO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFLO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0Isa0JBQWtCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},3715:function(__unused_webpack_module,exports,__webpack_require__){eval("var hash = exports;\n\nhash.utils = __webpack_require__(6436);\nhash.common = __webpack_require__(5772);\nhash.sha = __webpack_require__(9041);\nhash.ripemd = __webpack_require__(2949);\nhash.hmac = __webpack_require__(2344);\n\n// Proxy hash functions to the main object\nhash.sha1 = hash.sha.sha1;\nhash.sha256 = hash.sha.sha256;\nhash.sha224 = hash.sha.sha224;\nhash.sha384 = hash.sha.sha384;\nhash.sha512 = hash.sha.sha512;\nhash.ripemd160 = hash.ripemd.ripemd160;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcxNS5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQSxhQUFhLG1CQUFPLENBQUMsSUFBYztBQUNuQyxjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBWTtBQUMvQixjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsSUFBYTs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanM/N2Q5MiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3715\n")},5772:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction BlockHash() {\n this.pending = null;\n this.pendingTotal = 0;\n this.blockSize = this.constructor.blockSize;\n this.outSize = this.constructor.outSize;\n this.hmacStrength = this.constructor.hmacStrength;\n this.padLength = this.constructor.padLength / 8;\n this.endian = 'big';\n\n this._delta8 = this.blockSize / 8;\n this._delta32 = this.blockSize / 32;\n}\nexports.BlockHash = BlockHash;\n\nBlockHash.prototype.update = function update(msg, enc) {\n // Convert message to array, pad it, and join into 32bit blocks\n msg = utils.toArray(msg, enc);\n if (!this.pending)\n this.pending = msg;\n else\n this.pending = this.pending.concat(msg);\n this.pendingTotal += msg.length;\n\n // Enough data, try updating\n if (this.pending.length >= this._delta8) {\n msg = this.pending;\n\n // Process pending data in blocks\n var r = msg.length % this._delta8;\n this.pending = msg.slice(msg.length - r, msg.length);\n if (this.pending.length === 0)\n this.pending = null;\n\n msg = utils.join32(msg, 0, msg.length - r, this.endian);\n for (var i = 0; i < msg.length; i += this._delta32)\n this._update(msg, i, i + this._delta32);\n }\n\n return this;\n};\n\nBlockHash.prototype.digest = function digest(enc) {\n this.update(this._pad());\n assert(this.pending === null);\n\n return this._digest(enc);\n};\n\nBlockHash.prototype._pad = function pad() {\n var len = this.pendingTotal;\n var bytes = this._delta8;\n var k = bytes - ((len + this.padLength) % bytes);\n var res = new Array(k + this.padLength);\n res[0] = 0x80;\n for (var i = 1; i < k; i++)\n res[i] = 0;\n\n // Append length\n len <<= 3;\n if (this.endian === 'big') {\n for (var t = 8; t < this.padLength; t++)\n res[i++] = 0;\n\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = len & 0xff;\n } else {\n res[i++] = len & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n\n for (t = 8; t < this.padLength; t++)\n res[i++] = 0;\n }\n\n return res;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTc3Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLE9BQU87QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzP2VkYzkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5772\n")},2344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction Hmac(hash, key, enc) {\n if (!(this instanceof Hmac))\n return new Hmac(hash, key, enc);\n this.Hash = hash;\n this.blockSize = hash.blockSize / 8;\n this.outSize = hash.outSize / 8;\n this.inner = null;\n this.outer = null;\n\n this._init(utils.toArray(key, enc));\n}\nmodule.exports = Hmac;\n\nHmac.prototype._init = function init(key) {\n // Shorten key, if needed\n if (key.length > this.blockSize)\n key = new this.Hash().update(key).digest();\n assert(key.length <= this.blockSize);\n\n // Add padding to key\n for (var i = key.length; i < this.blockSize; i++)\n key.push(0);\n\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x36;\n this.inner = new this.Hash().update(key);\n\n // 0x36 ^ 0x5c = 0x6a\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x6a;\n this.outer = new this.Hash().update(key);\n};\n\nHmac.prototype.update = function update(msg, enc) {\n this.inner.update(msg, enc);\n return this;\n};\n\nHmac.prototype.digest = function digest(enc) {\n this.outer.update(this.inner.digest());\n return this.outer.digest(enc);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsb0JBQW9CO0FBQy9DOztBQUVBLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvaG1hYy5qcz8yMTM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gSG1hYyhoYXNoLCBrZXksIGVuYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hYykpXG4gICAgcmV0dXJuIG5ldyBIbWFjKGhhc2gsIGtleSwgZW5jKTtcbiAgdGhpcy5IYXNoID0gaGFzaDtcbiAgdGhpcy5ibG9ja1NpemUgPSBoYXNoLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMub3V0U2l6ZSA9IGhhc2gub3V0U2l6ZSAvIDg7XG4gIHRoaXMuaW5uZXIgPSBudWxsO1xuICB0aGlzLm91dGVyID0gbnVsbDtcblxuICB0aGlzLl9pbml0KHV0aWxzLnRvQXJyYXkoa2V5LCBlbmMpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hYztcblxuSG1hYy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGtleSkge1xuICAvLyBTaG9ydGVuIGtleSwgaWYgbmVlZGVkXG4gIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpXG4gICAga2V5ID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xuICBhc3NlcnQoa2V5Lmxlbmd0aCA8PSB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gQWRkIHBhZGRpbmcgdG8ga2V5XG4gIGZvciAodmFyIGkgPSBrZXkubGVuZ3RoOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKylcbiAgICBrZXkucHVzaCgwKTtcblxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDM2O1xuICB0aGlzLmlubmVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xuXG4gIC8vIDB4MzYgXiAweDVjID0gMHg2YVxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2344\n")},2949:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_3 = utils.sum32_3;\nvar sum32_4 = utils.sum32_4;\nvar BlockHash = common.BlockHash;\n\nfunction RIPEMD160() {\n if (!(this instanceof RIPEMD160))\n return new RIPEMD160();\n\n BlockHash.call(this);\n\n this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];\n this.endian = 'little';\n}\nutils.inherits(RIPEMD160, BlockHash);\nexports.ripemd160 = RIPEMD160;\n\nRIPEMD160.blockSize = 512;\nRIPEMD160.outSize = 160;\nRIPEMD160.hmacStrength = 192;\nRIPEMD160.padLength = 64;\n\nRIPEMD160.prototype._update = function update(msg, start) {\n var A = this.h[0];\n var B = this.h[1];\n var C = this.h[2];\n var D = this.h[3];\n var E = this.h[4];\n var Ah = A;\n var Bh = B;\n var Ch = C;\n var Dh = D;\n var Eh = E;\n for (var j = 0; j < 80; j++) {\n var T = sum32(\n rotl32(\n sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),\n s[j]),\n E);\n A = E;\n E = D;\n D = rotl32(C, 10);\n C = B;\n B = T;\n T = sum32(\n rotl32(\n sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),\n sh[j]),\n Eh);\n Ah = Eh;\n Eh = Dh;\n Dh = rotl32(Ch, 10);\n Ch = Bh;\n Bh = T;\n }\n T = sum32_3(this.h[1], C, Dh);\n this.h[1] = sum32_3(this.h[2], D, Eh);\n this.h[2] = sum32_3(this.h[3], E, Ah);\n this.h[3] = sum32_3(this.h[4], A, Bh);\n this.h[4] = sum32_3(this.h[0], B, Ch);\n this.h[0] = T;\n};\n\nRIPEMD160.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'little');\n else\n return utils.split32(this.h, 'little');\n};\n\nfunction f(j, x, y, z) {\n if (j <= 15)\n return x ^ y ^ z;\n else if (j <= 31)\n return (x & y) | ((~x) & z);\n else if (j <= 47)\n return (x | (~y)) ^ z;\n else if (j <= 63)\n return (x & z) | (y & (~z));\n else\n return x ^ (y | (~z));\n}\n\nfunction K(j) {\n if (j <= 15)\n return 0x00000000;\n else if (j <= 31)\n return 0x5a827999;\n else if (j <= 47)\n return 0x6ed9eba1;\n else if (j <= 63)\n return 0x8f1bbcdc;\n else\n return 0xa953fd4e;\n}\n\nfunction Kh(j) {\n if (j <= 15)\n return 0x50a28be6;\n else if (j <= 31)\n return 0x5c4dd124;\n else if (j <= 47)\n return 0x6d703ef3;\n else if (j <= 63)\n return 0x7a6d76e9;\n else\n return 0x00000000;\n}\n\nvar r = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,\n 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,\n 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13\n];\n\nvar rh = [\n 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,\n 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,\n 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,\n 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,\n 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11\n];\n\nvar s = [\n 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,\n 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,\n 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,\n 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,\n 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6\n];\n\nvar sh = [\n 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,\n 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,\n 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,\n 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,\n 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11\n];\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBVTs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzP2JiNDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2949\n")},9041:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nexports.sha1 = __webpack_require__(4761);\nexports.sha224 = __webpack_require__(799);\nexports.sha256 = __webpack_require__(9344);\nexports.sha384 = __webpack_require__(772);\nexports.sha512 = __webpack_require__(5900);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA0MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix3Q0FBaUM7QUFDakMseUNBQXFDO0FBQ3JDLDBDQUFxQztBQUNyQyx5Q0FBcUM7QUFDckMsMENBQXFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcz81OTE5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGEvMScpO1xuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYS8yMjQnKTtcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEvMjU2Jyk7XG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhLzM4NCcpO1xuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYS81MTInKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9041\n")},4761:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_5 = utils.sum32_5;\nvar ft_1 = shaCommon.ft_1;\nvar BlockHash = common.BlockHash;\n\nvar sha1_K = [\n 0x5A827999, 0x6ED9EBA1,\n 0x8F1BBCDC, 0xCA62C1D6\n];\n\nfunction SHA1() {\n if (!(this instanceof SHA1))\n return new SHA1();\n\n BlockHash.call(this);\n this.h = [\n 0x67452301, 0xefcdab89, 0x98badcfe,\n 0x10325476, 0xc3d2e1f0 ];\n this.W = new Array(80);\n}\n\nutils.inherits(SHA1, BlockHash);\nmodule.exports = SHA1;\n\nSHA1.blockSize = 512;\nSHA1.outSize = 160;\nSHA1.hmacStrength = 80;\nSHA1.padLength = 64;\n\nSHA1.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n\n for(; i < W.length; i++)\n W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n\n for (i = 0; i < W.length; i++) {\n var s = ~~(i / 20);\n var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);\n e = d;\n d = c;\n c = rotl32(b, 30);\n b = a;\n a = t;\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n};\n\nSHA1.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc2MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVOztBQUVsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixRQUFRO0FBQzFCOztBQUVBLFFBQVEsY0FBYztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzEuanM/MTNlMiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGZ0XzEgPSBzaGFDb21tb24uZnRfMTtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMTtcblxuU0hBMS5ibG9ja1NpemUgPSA1MTI7XG5TSEExLm91dFNpemUgPSAxNjA7XG5TSEExLmhtYWNTdHJlbmd0aCA9IDgwO1xuU0hBMS5wYWRMZW5ndGggPSA2NDtcblxuU0hBMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuXG4gIGZvcig7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSByb3RsMzIoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSwgMSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4761\n")},799:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar SHA256 = __webpack_require__(9344);\n\nfunction SHA224() {\n if (!(this instanceof SHA224))\n return new SHA224();\n\n SHA256.call(this);\n this.h = [\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];\n}\nutils.inherits(SHA224, SHA256);\nmodule.exports = SHA224;\n\nSHA224.blockSize = 512;\nSHA224.outSize = 224;\nSHA224.hmacStrength = 192;\nSHA224.padLength = 64;\n\nSHA224.prototype._digest = function digest(enc) {\n // Just truncate output\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 7), 'big');\n else\n return utils.split32(this.h.slice(0, 7), 'big');\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVO0FBQzlCLGFBQWEsbUJBQU8sQ0FBQyxJQUFPOztBQUU1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzIyNC5qcz8wN2YyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBTSEEyNTYgPSByZXF1aXJlKCcuLzI1NicpO1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///799\n")},9344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\nvar assert = __webpack_require__(9746);\n\nvar sum32 = utils.sum32;\nvar sum32_4 = utils.sum32_4;\nvar sum32_5 = utils.sum32_5;\nvar ch32 = shaCommon.ch32;\nvar maj32 = shaCommon.maj32;\nvar s0_256 = shaCommon.s0_256;\nvar s1_256 = shaCommon.s1_256;\nvar g0_256 = shaCommon.g0_256;\nvar g1_256 = shaCommon.g1_256;\n\nvar BlockHash = common.BlockHash;\n\nvar sha256_K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\nfunction SHA256() {\n if (!(this instanceof SHA256))\n return new SHA256();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n ];\n this.k = sha256_K;\n this.W = new Array(64);\n}\nutils.inherits(SHA256, BlockHash);\nmodule.exports = SHA256;\n\nSHA256.blockSize = 512;\nSHA256.outSize = 256;\nSHA256.hmacStrength = 192;\nSHA256.padLength = 64;\n\nSHA256.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i++)\n W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n var f = this.h[5];\n var g = this.h[6];\n var h = this.h[7];\n\n assert(this.k.length === W.length);\n for (i = 0; i < W.length; i++) {\n var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);\n var T2 = sum32(s0_256(a), maj32(a, b, c));\n h = g;\n g = f;\n f = e;\n e = sum32(d, T1);\n d = c;\n c = b;\n b = a;\n a = sum32(T1, T2);\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n this.h[5] = sum32(this.h[5], f);\n this.h[6] = sum32(this.h[6], g);\n this.h[7] = sum32(this.h[7], h);\n};\n\nSHA256.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBLFNBQVMsY0FBYztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMjU2LmpzPzZlZWQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIHNoYUNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciBjaDMyID0gc2hhQ29tbW9uLmNoMzI7XG52YXIgbWFqMzIgPSBzaGFDb21tb24ubWFqMzI7XG52YXIgczBfMjU2ID0gc2hhQ29tbW9uLnMwXzI1NjtcbnZhciBzMV8yNTYgPSBzaGFDb21tb24uczFfMjU2O1xudmFyIGcwXzI1NiA9IHNoYUNvbW1vbi5nMF8yNTY7XG52YXIgZzFfMjU2ID0gc2hhQ29tbW9uLmcxXzI1NjtcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG4gIF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBUMSA9IHN1bTMyXzUoaCwgczFfMjU2KGUpLCBjaDMyKGUsIGYsIGcpLCB0aGlzLmtbaV0sIFdbaV0pO1xuICAgIHZhciBUMiA9IHN1bTMyKHMwXzI1NihhKSwgbWFqMzIoYSwgYiwgYykpO1xuICAgIGggPSBnO1xuICAgIGcgPSBmO1xuICAgIGYgPSBlO1xuICAgIGUgPSBzdW0zMihkLCBUMSk7XG4gICAgZCA9IGM7XG4gICAgYyA9IGI7XG4gICAgYiA9IGE7XG4gICAgYSA9IHN1bTMyKFQxLCBUMik7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xuICB0aGlzLmhbNV0gPSBzdW0zMih0aGlzLmhbNV0sIGYpO1xuICB0aGlzLmhbNl0gPSBzdW0zMih0aGlzLmhbNl0sIGcpO1xuICB0aGlzLmhbN10gPSBzdW0zMih0aGlzLmhbN10sIGgpO1xufTtcblxuU0hBMjU2LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9344\n")},772:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\n\nvar SHA512 = __webpack_require__(5900);\n\nfunction SHA384() {\n if (!(this instanceof SHA384))\n return new SHA384();\n\n SHA512.call(this);\n this.h = [\n 0xcbbb9d5d, 0xc1059ed8,\n 0x629a292a, 0x367cd507,\n 0x9159015a, 0x3070dd17,\n 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31,\n 0x8eb44a87, 0x68581511,\n 0xdb0c2e0d, 0x64f98fa7,\n 0x47b5481d, 0xbefa4fa4 ];\n}\nutils.inherits(SHA384, SHA512);\nmodule.exports = SHA384;\n\nSHA384.blockSize = 1024;\nSHA384.outSize = 384;\nSHA384.hmacStrength = 192;\nSHA384.padLength = 128;\n\nSHA384.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 12), 'big');\n else\n return utils.split32(this.h.slice(0, 12), 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcyLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVOztBQUU5QixhQUFhLG1CQUFPLENBQUMsSUFBTzs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMzg0LmpzPzhiOTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi81MTInKTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///772\n")},5900:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar assert = __webpack_require__(9746);\n\nvar rotr64_hi = utils.rotr64_hi;\nvar rotr64_lo = utils.rotr64_lo;\nvar shr64_hi = utils.shr64_hi;\nvar shr64_lo = utils.shr64_lo;\nvar sum64 = utils.sum64;\nvar sum64_hi = utils.sum64_hi;\nvar sum64_lo = utils.sum64_lo;\nvar sum64_4_hi = utils.sum64_4_hi;\nvar sum64_4_lo = utils.sum64_4_lo;\nvar sum64_5_hi = utils.sum64_5_hi;\nvar sum64_5_lo = utils.sum64_5_lo;\n\nvar BlockHash = common.BlockHash;\n\nvar sha512_K = [\n 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,\n 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,\n 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,\n 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,\n 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,\n 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,\n 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,\n 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,\n 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,\n 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,\n 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,\n 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,\n 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,\n 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,\n 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,\n 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,\n 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,\n 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,\n 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,\n 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,\n 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,\n 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,\n 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,\n 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,\n 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,\n 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,\n 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,\n 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,\n 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,\n 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,\n 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,\n 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,\n 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,\n 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,\n 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,\n 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,\n 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,\n 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,\n 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,\n 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817\n];\n\nfunction SHA512() {\n if (!(this instanceof SHA512))\n return new SHA512();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xf3bcc908,\n 0xbb67ae85, 0x84caa73b,\n 0x3c6ef372, 0xfe94f82b,\n 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1,\n 0x9b05688c, 0x2b3e6c1f,\n 0x1f83d9ab, 0xfb41bd6b,\n 0x5be0cd19, 0x137e2179 ];\n this.k = sha512_K;\n this.W = new Array(160);\n}\nutils.inherits(SHA512, BlockHash);\nmodule.exports = SHA512;\n\nSHA512.blockSize = 1024;\nSHA512.outSize = 512;\nSHA512.hmacStrength = 192;\nSHA512.padLength = 128;\n\nSHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {\n var W = this.W;\n\n // 32 x 32bit words\n for (var i = 0; i < 32; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i += 2) {\n var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2\n var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);\n var c1_hi = W[i - 14]; // i - 7\n var c1_lo = W[i - 13];\n var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15\n var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);\n var c3_hi = W[i - 32]; // i - 16\n var c3_lo = W[i - 31];\n\n W[i] = sum64_4_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n W[i + 1] = sum64_4_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n }\n};\n\nSHA512.prototype._update = function _update(msg, start) {\n this._prepareBlock(msg, start);\n\n var W = this.W;\n\n var ah = this.h[0];\n var al = this.h[1];\n var bh = this.h[2];\n var bl = this.h[3];\n var ch = this.h[4];\n var cl = this.h[5];\n var dh = this.h[6];\n var dl = this.h[7];\n var eh = this.h[8];\n var el = this.h[9];\n var fh = this.h[10];\n var fl = this.h[11];\n var gh = this.h[12];\n var gl = this.h[13];\n var hh = this.h[14];\n var hl = this.h[15];\n\n assert(this.k.length === W.length);\n for (var i = 0; i < W.length; i += 2) {\n var c0_hi = hh;\n var c0_lo = hl;\n var c1_hi = s1_512_hi(eh, el);\n var c1_lo = s1_512_lo(eh, el);\n var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);\n var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);\n var c3_hi = this.k[i];\n var c3_lo = this.k[i + 1];\n var c4_hi = W[i];\n var c4_lo = W[i + 1];\n\n var T1_hi = sum64_5_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n var T1_lo = sum64_5_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n\n c0_hi = s0_512_hi(ah, al);\n c0_lo = s0_512_lo(ah, al);\n c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);\n c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);\n\n var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);\n var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);\n\n hh = gh;\n hl = gl;\n\n gh = fh;\n gl = fl;\n\n fh = eh;\n fl = el;\n\n eh = sum64_hi(dh, dl, T1_hi, T1_lo);\n el = sum64_lo(dl, dl, T1_hi, T1_lo);\n\n dh = ch;\n dl = cl;\n\n ch = bh;\n cl = bl;\n\n bh = ah;\n bl = al;\n\n ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);\n al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);\n }\n\n sum64(this.h, 0, ah, al);\n sum64(this.h, 2, bh, bl);\n sum64(this.h, 4, ch, cl);\n sum64(this.h, 6, dh, dl);\n sum64(this.h, 8, eh, el);\n sum64(this.h, 10, fh, fl);\n sum64(this.h, 12, gh, gl);\n sum64(this.h, 14, hh, hl);\n};\n\nSHA512.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n\nfunction ch64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ ((~xh) & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction ch64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ ((~xl) & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 28);\n var c1_hi = rotr64_hi(xl, xh, 2); // 34\n var c2_hi = rotr64_hi(xl, xh, 7); // 39\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 28);\n var c1_lo = rotr64_lo(xl, xh, 2); // 34\n var c2_lo = rotr64_lo(xl, xh, 7); // 39\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 14);\n var c1_hi = rotr64_hi(xh, xl, 18);\n var c2_hi = rotr64_hi(xl, xh, 9); // 41\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 14);\n var c1_lo = rotr64_lo(xh, xl, 18);\n var c2_lo = rotr64_lo(xl, xh, 9); // 41\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 1);\n var c1_hi = rotr64_hi(xh, xl, 8);\n var c2_hi = shr64_hi(xh, xl, 7);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 1);\n var c1_lo = rotr64_lo(xh, xl, 8);\n var c2_lo = shr64_lo(xh, xl, 7);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 19);\n var c1_hi = rotr64_hi(xl, xh, 29); // 61\n var c2_hi = shr64_hi(xh, xl, 6);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 19);\n var c1_lo = rotr64_lo(xl, xh, 29); // 61\n var c2_lo = shr64_lo(xh, xl, 6);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTkwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixRQUFRO0FBQzFCO0FBQ0EsU0FBUyxjQUFjO0FBQ3ZCLGdEQUFnRDtBQUNoRDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzUxMi5qcz9iNTI1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbnZhciByb3RyNjRfaGkgPSB1dGlscy5yb3RyNjRfaGk7XG52YXIgcm90cjY0X2xvID0gdXRpbHMucm90cjY0X2xvO1xudmFyIHNocjY0X2hpID0gdXRpbHMuc2hyNjRfaGk7XG52YXIgc2hyNjRfbG8gPSB1dGlscy5zaHI2NF9sbztcbnZhciBzdW02NCA9IHV0aWxzLnN1bTY0O1xudmFyIHN1bTY0X2hpID0gdXRpbHMuc3VtNjRfaGk7XG52YXIgc3VtNjRfbG8gPSB1dGlscy5zdW02NF9sbztcbnZhciBzdW02NF80X2hpID0gdXRpbHMuc3VtNjRfNF9oaTtcbnZhciBzdW02NF80X2xvID0gdXRpbHMuc3VtNjRfNF9sbztcbnZhciBzdW02NF81X2hpID0gdXRpbHMuc3VtNjRfNV9oaTtcbnZhciBzdW02NF81X2xvID0gdXRpbHMuc3VtNjRfNV9sbztcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCxcbiAgICAweGJiNjdhZTg1LCAweDg0Y2FhNzNiLFxuICAgIDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIsXG4gICAgMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSxcbiAgICAweDUxMGU1MjdmLCAweGFkZTY4MmQxLFxuICAgIDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYsXG4gICAgMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YixcbiAgICAweDViZTBjZDE5LCAweDEzN2UyMTc5IF07XG4gIHRoaXMuayA9IHNoYTUxMl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoMTYwKTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTUxMiwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBNTEyO1xuXG5TSEE1MTIuYmxvY2tTaXplID0gMTAyNDtcblNIQTUxMi5vdXRTaXplID0gNTEyO1xuU0hBNTEyLmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTUxMi5wYWRMZW5ndGggPSAxMjg7XG5cblNIQTUxMi5wcm90b3R5cGUuX3ByZXBhcmVCbG9jayA9IGZ1bmN0aW9uIF9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICAvLyAzMiB4IDMyYml0IHdvcmRzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGcxXzUxMl9oaShXW2kgLSA0XSwgV1tpIC0gM10pOyAgLy8gaSAtIDJcbiAgICB2YXIgYzBfbG8gPSBnMV81MTJfbG8oV1tpIC0gNF0sIFdbaSAtIDNdKTtcbiAgICB2YXIgYzFfaGkgPSBXW2kgLSAxNF07ICAvLyBpIC0gN1xuICAgIHZhciBjMV9sbyA9IFdbaSAtIDEzXTtcbiAgICB2YXIgYzJfaGkgPSBnMF81MTJfaGkoV1tpIC0gMzBdLCBXW2kgLSAyOV0pOyAgLy8gaSAtIDE1XG4gICAgdmFyIGMyX2xvID0gZzBfNTEyX2xvKFdbaSAtIDMwXSwgV1tpIC0gMjldKTtcbiAgICB2YXIgYzNfaGkgPSBXW2kgLSAzMl07ICAvLyBpIC0gMTZcbiAgICB2YXIgYzNfbG8gPSBXW2kgLSAzMV07XG5cbiAgICBXW2ldID0gc3VtNjRfNF9oaShcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyk7XG4gICAgV1tpICsgMV0gPSBzdW02NF80X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcbiAgICB2YXIgVDFfbG8gPSBzdW02NF81X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcblxuICAgIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgYzBfbG8gPSBzMF81MTJfbG8oYWgsIGFsKTtcbiAgICBjMV9oaSA9IG1hajY0X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wpO1xuICAgIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gY2g2NF9oaSh4aCwgeGwsIHloLCB5bCwgemgpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICh4aCAmIHpoKSBeICh5aCAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKHhsICYgemwpIF4gKHlsICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDEpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDEpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5900\n")},7038:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar rotr32 = utils.rotr32;\n\nfunction ft_1(s, x, y, z) {\n if (s === 0)\n return ch32(x, y, z);\n if (s === 1 || s === 3)\n return p32(x, y, z);\n if (s === 2)\n return maj32(x, y, z);\n}\nexports.ft_1 = ft_1;\n\nfunction ch32(x, y, z) {\n return (x & y) ^ ((~x) & z);\n}\nexports.ch32 = ch32;\n\nfunction maj32(x, y, z) {\n return (x & y) ^ (x & z) ^ (y & z);\n}\nexports.maj32 = maj32;\n\nfunction p32(x, y, z) {\n return x ^ y ^ z;\n}\nexports.p32 = p32;\n\nfunction s0_256(x) {\n return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);\n}\nexports.s0_256 = s0_256;\n\nfunction s1_256(x) {\n return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);\n}\nexports.s1_256 = s1_256;\n\nfunction g0_256(x) {\n return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);\n}\nexports.g0_256 = g0_256;\n\nfunction g1_256(x) {\n return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);\n}\nexports.g1_256 = g1_256;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAzOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0EsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxjQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS9jb21tb24uanM/YWE1NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgcm90cjMyID0gdXRpbHMucm90cjMyO1xuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuZXhwb3J0cy5mdF8xID0gZnRfMTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cbmV4cG9ydHMuY2gzMiA9IGNoMzI7XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cbmV4cG9ydHMubWFqMzIgPSBtYWozMjtcblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cbmV4cG9ydHMucDMyID0gcDMyO1xuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5leHBvcnRzLnMwXzI1NiA9IHMwXzI1NjtcblxuZnVuY3Rpb24gczFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA2KSBeIHJvdHIzMih4LCAxMSkgXiByb3RyMzIoeCwgMjUpO1xufVxuZXhwb3J0cy5zMV8yNTYgPSBzMV8yNTY7XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuZXhwb3J0cy5nMF8yNTYgPSBnMF8yNTY7XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5leHBvcnRzLmcxXzI1NiA9IGcxXzI1NjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7038\n")},6436:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar assert = __webpack_require__(9746);\nvar inherits = __webpack_require__(5717);\n\nexports.inherits = inherits;\n\nfunction isSurrogatePair(msg, i) {\n if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {\n return false;\n }\n if (i < 0 || i + 1 >= msg.length) {\n return false;\n }\n return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;\n}\n\nfunction toArray(msg, enc) {\n if (Array.isArray(msg))\n return msg.slice();\n if (!msg)\n return [];\n var res = [];\n if (typeof msg === 'string') {\n if (!enc) {\n // Inspired by stringToUtf8ByteArray() in closure-library by Google\n // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143\n // Apache License 2.0\n // https://github.com/google/closure-library/blob/master/LICENSE\n var p = 0;\n for (var i = 0; i < msg.length; i++) {\n var c = msg.charCodeAt(i);\n if (c < 128) {\n res[p++] = c;\n } else if (c < 2048) {\n res[p++] = (c >> 6) | 192;\n res[p++] = (c & 63) | 128;\n } else if (isSurrogatePair(msg, i)) {\n c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);\n res[p++] = (c >> 18) | 240;\n res[p++] = ((c >> 12) & 63) | 128;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n } else {\n res[p++] = (c >> 12) | 224;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n }\n }\n } else if (enc === 'hex') {\n msg = msg.replace(/[^a-z0-9]+/ig, '');\n if (msg.length % 2 !== 0)\n msg = '0' + msg;\n for (i = 0; i < msg.length; i += 2)\n res.push(parseInt(msg[i] + msg[i + 1], 16));\n }\n } else {\n for (i = 0; i < msg.length; i++)\n res[i] = msg[i] | 0;\n }\n return res;\n}\nexports.toArray = toArray;\n\nfunction toHex(msg) {\n var res = '';\n for (var i = 0; i < msg.length; i++)\n res += zero2(msg[i].toString(16));\n return res;\n}\nexports.toHex = toHex;\n\nfunction htonl(w) {\n var res = (w >>> 24) |\n ((w >>> 8) & 0xff00) |\n ((w << 8) & 0xff0000) |\n ((w & 0xff) << 24);\n return res >>> 0;\n}\nexports.htonl = htonl;\n\nfunction toHex32(msg, endian) {\n var res = '';\n for (var i = 0; i < msg.length; i++) {\n var w = msg[i];\n if (endian === 'little')\n w = htonl(w);\n res += zero8(w.toString(16));\n }\n return res;\n}\nexports.toHex32 = toHex32;\n\nfunction zero2(word) {\n if (word.length === 1)\n return '0' + word;\n else\n return word;\n}\nexports.zero2 = zero2;\n\nfunction zero8(word) {\n if (word.length === 7)\n return '0' + word;\n else if (word.length === 6)\n return '00' + word;\n else if (word.length === 5)\n return '000' + word;\n else if (word.length === 4)\n return '0000' + word;\n else if (word.length === 3)\n return '00000' + word;\n else if (word.length === 2)\n return '000000' + word;\n else if (word.length === 1)\n return '0000000' + word;\n else\n return word;\n}\nexports.zero8 = zero8;\n\nfunction join32(msg, start, end, endian) {\n var len = end - start;\n assert(len % 4 === 0);\n var res = new Array(len / 4);\n for (var i = 0, k = start; i < res.length; i++, k += 4) {\n var w;\n if (endian === 'big')\n w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];\n else\n w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];\n res[i] = w >>> 0;\n }\n return res;\n}\nexports.join32 = join32;\n\nfunction split32(msg, endian) {\n var res = new Array(msg.length * 4);\n for (var i = 0, k = 0; i < msg.length; i++, k += 4) {\n var m = msg[i];\n if (endian === 'big') {\n res[k] = m >>> 24;\n res[k + 1] = (m >>> 16) & 0xff;\n res[k + 2] = (m >>> 8) & 0xff;\n res[k + 3] = m & 0xff;\n } else {\n res[k + 3] = m >>> 24;\n res[k + 2] = (m >>> 16) & 0xff;\n res[k + 1] = (m >>> 8) & 0xff;\n res[k] = m & 0xff;\n }\n }\n return res;\n}\nexports.split32 = split32;\n\nfunction rotr32(w, b) {\n return (w >>> b) | (w << (32 - b));\n}\nexports.rotr32 = rotr32;\n\nfunction rotl32(w, b) {\n return (w << b) | (w >>> (32 - b));\n}\nexports.rotl32 = rotl32;\n\nfunction sum32(a, b) {\n return (a + b) >>> 0;\n}\nexports.sum32 = sum32;\n\nfunction sum32_3(a, b, c) {\n return (a + b + c) >>> 0;\n}\nexports.sum32_3 = sum32_3;\n\nfunction sum32_4(a, b, c, d) {\n return (a + b + c + d) >>> 0;\n}\nexports.sum32_4 = sum32_4;\n\nfunction sum32_5(a, b, c, d, e) {\n return (a + b + c + d + e) >>> 0;\n}\nexports.sum32_5 = sum32_5;\n\nfunction sum64(buf, pos, ah, al) {\n var bh = buf[pos];\n var bl = buf[pos + 1];\n\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n buf[pos] = hi >>> 0;\n buf[pos + 1] = lo;\n}\nexports.sum64 = sum64;\n\nfunction sum64_hi(ah, al, bh, bl) {\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n return hi >>> 0;\n}\nexports.sum64_hi = sum64_hi;\n\nfunction sum64_lo(ah, al, bh, bl) {\n var lo = al + bl;\n return lo >>> 0;\n}\nexports.sum64_lo = sum64_lo;\n\nfunction sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n\n var hi = ah + bh + ch + dh + carry;\n return hi >>> 0;\n}\nexports.sum64_4_hi = sum64_4_hi;\n\nfunction sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {\n var lo = al + bl + cl + dl;\n return lo >>> 0;\n}\nexports.sum64_4_lo = sum64_4_lo;\n\nfunction sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n lo = (lo + el) >>> 0;\n carry += lo < el ? 1 : 0;\n\n var hi = ah + bh + ch + dh + eh + carry;\n return hi >>> 0;\n}\nexports.sum64_5_hi = sum64_5_hi;\n\nfunction sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var lo = al + bl + cl + dl + el;\n\n return lo >>> 0;\n}\nexports.sum64_5_lo = sum64_5_lo;\n\nfunction rotr64_hi(ah, al, num) {\n var r = (al << (32 - num)) | (ah >>> num);\n return r >>> 0;\n}\nexports.rotr64_hi = rotr64_hi;\n\nfunction rotr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.rotr64_lo = rotr64_lo;\n\nfunction shr64_hi(ah, al, num) {\n return ah >>> num;\n}\nexports.shr64_hi = shr64_hi;\n\nfunction shr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.shr64_lo = shr64_lo;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBcUI7QUFDMUMsZUFBZSxtQkFBTyxDQUFDLElBQVU7O0FBRWpDLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGdCQUFnQjtBQUN0QztBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0EsSUFBSTtBQUNKLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsZ0JBQWdCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcz9jM2MwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuaW5oZXJpdHMgPSBpbmhlcml0cztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkge1xuICBpZiAoKG1zZy5jaGFyQ29kZUF0KGkpICYgMHhGQzAwKSAhPT0gMHhEODAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpIDwgMCB8fCBpICsgMSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAobXNnLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwO1xufVxuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIC8vIEluc3BpcmVkIGJ5IHN0cmluZ1RvVXRmOEJ5dGVBcnJheSgpIGluIGNsb3N1cmUtbGlicmFyeSBieSBHb29nbGVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvODU5OGQ4NzI0MmFmNTlhYWMyMzMyNzA3NDJjODk4NGUyYjJiZGJlMC9jbG9zdXJlL2dvb2cvY3J5cHQvY3J5cHQuanMjTDExNy1MMTQzXG4gICAgICAvLyBBcGFjaGUgTGljZW5zZSAyLjBcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAgICAgIHZhciBwID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSBjO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPCAyMDQ4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyA+PiA2KSB8IDE5MjtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3Vycm9nYXRlUGFpcihtc2csIGkpKSB7XG4gICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgJiAweDAzRkYpIDw8IDEwKSArIChtc2cuY2hhckNvZGVBdCgrK2kpICYgMHgwM0ZGKTtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDE4KSB8IDI0MDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiAxMikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoKGMgPj4gNikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyAmIDYzKSB8IDEyODtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDEyKSB8IDIyNDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleCA9IHRvSGV4O1xuXG5mdW5jdGlvbiBodG9ubCh3KSB7XG4gIHZhciByZXMgPSAodyA+Pj4gMjQpIHxcbiAgICAgICAgICAgICgodyA+Pj4gOCkgJiAweGZmMDApIHxcbiAgICAgICAgICAgICgodyA8PCA4KSAmIDB4ZmYwMDAwKSB8XG4gICAgICAgICAgICAoKHcgJiAweGZmKSA8PCAyNCk7XG4gIHJldHVybiByZXMgPj4+IDA7XG59XG5leHBvcnRzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHplcm84KHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSA3KVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNilcbiAgICByZXR1cm4gJzAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA1KVxuICAgIHJldHVybiAnMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA0KVxuICAgIHJldHVybiAnMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMylcbiAgICByZXR1cm4gJzAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAyKVxuICAgIHJldHVybiAnMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMDAwMDAwMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5zcGxpdDMyID0gc3BsaXQzMjtcblxuZnVuY3Rpb24gcm90cjMyKHcsIGIpIHtcbiAgcmV0dXJuICh3ID4+PiBiKSB8ICh3IDw8ICgzMiAtIGIpKTtcbn1cbmV4cG9ydHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyID0gc3VtMzI7XG5cbmZ1bmN0aW9uIHN1bTMyXzMoYSwgYiwgYykge1xuICByZXR1cm4gKGEgKyBiICsgYykgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNSA9IHN1bTMyXzU7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0X2hpID0gc3VtNjRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0X2xvKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IGFsICsgYmw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNF9sbyA9IHN1bTY0XzRfbG87XG5cbmZ1bmN0aW9uIHN1bTY0XzVfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZWwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGVsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBlaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMucm90cjY0X2hpID0gcm90cjY0X2hpO1xuXG5mdW5jdGlvbiByb3RyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufVxuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnNocjY0X2xvID0gc2hyNjRfbG87XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6436\n")},5717:function(module){eval("if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTcxNy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzPzNmYjUiXSwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5717\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},9746:function(module){eval("module.exports = assert;\n\nfunction assert(val, msg) {\n if (!val)\n throw new Error(msg || 'Assertion failed');\n}\n\nassert.equal = function assertEqual(l, r, msg) {\n if (l != r)\n throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvbWluaW1hbGlzdGljLWFzc2VydC9pbmRleC5qcz9kYTNlIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXNzZXJ0O1xuXG5mdW5jdGlvbiBhc3NlcnQodmFsLCBtc2cpIHtcbiAgaWYgKCF2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBhc3NlcnRFcXVhbChsLCByLCBtc2cpIHtcbiAgaWYgKGwgIT0gcilcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICgnQXNzZXJ0aW9uIGZhaWxlZDogJyArIGwgKyAnICE9ICcgKyByKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9746\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz81OWY4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz8zNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/MWJmMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzP2I4OGUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NmRiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/ZmI1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz9mMGYzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/YjMwZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz82OTY3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzP2E4ZjciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz83NzYwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/Yjg2MiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzc0OWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz9hYTJiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82ZGMxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz83ZmY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZDJhYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzPzYwOGYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzPzY5NDciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz83YTkyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz80NTY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YjY2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzP2FhYTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz9lZDA1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz9mMTM2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZWVlNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz84MTA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzPzdmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz8zNTA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz9iYTg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz9jZGZlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz8zNGI3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzkxOWUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9jZjY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz8wZjA5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/ZTQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz8zMmFlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzJjNTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/ZThjZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/M2Q3NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9jNmVmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/MGFlMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/MmI4ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/NzczNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzPzViNGEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzPzY4MWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz81NmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzPzUxYTAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/M2JkYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz9iN2UzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzPzA5YmMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZThlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/MDY5OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/ZjhkMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz9lNGZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzPzJhMmYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/MTNkNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9jNjA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(Q){var t=__webpack_module_cache__[Q];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[Q]={exports:{}};return __webpack_modules__[Q](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=function(Q){var t=Q&&Q.__esModule?function(){return Q.default}:function(){return Q};return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=function(Q,t){for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(Q,n)&&Object.defineProperty(Q,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=function(Q,t){return Object.prototype.hasOwnProperty.call(Q,t)};var __webpack_exports__=__webpack_require__(3088)})(); \ No newline at end of file +(function(){var __webpack_modules__={3089:function(__unused_webpack_module,exports){"use strict";eval('var __webpack_unused_export__;\n\n/**\n * Implementation of Myers\' online approximate string matching algorithm [1],\n * with additional optimizations suggested by [2].\n *\n * This has O((k/w) * n) complexity where `n` is the length of the text, `k` is\n * the maximum number of errors allowed (always <= the pattern length) and `w`\n * is the word size. Because JS only supports bitwise operations on 32 bit\n * integers, `w` is 32.\n *\n * As far as I am aware, there aren\'t any online algorithms which are\n * significantly better for a wide range of input parameters. The problem can be\n * solved faster using "filter then verify" approaches which first filter out\n * regions of the text that cannot match using a "cheap" check and then verify\n * the remaining potential matches. The verify step requires an algorithm such\n * as this one however.\n *\n * The algorithm\'s approach is essentially to optimize the classic dynamic\n * programming solution to the problem by computing columns of the matrix in\n * word-sized chunks (ie. dealing with 32 chars of the pattern at a time) and\n * avoiding calculating regions of the matrix where the minimum error count is\n * guaranteed to exceed the input threshold.\n *\n * The paper consists of two parts, the first describes the core algorithm for\n * matching patterns <= the size of a word (implemented by `advanceBlock` here).\n * The second uses the core algorithm as part of a larger block-based algorithm\n * to handle longer patterns.\n *\n * [1] G. Myers, “A Fast Bit-Vector Algorithm for Approximate String Matching\n * Based on Dynamic Programming,” vol. 46, no. 3, pp. 395–415, 1999.\n *\n * [2] Šošić, M. (2014). An simd dynamic programming c/c++ library (Doctoral\n * dissertation, Fakultet Elektrotehnike i računarstva, Sveučilište u Zagrebu).\n */\n__webpack_unused_export__ = ({ value: true });\nfunction reverse(s) {\n return s\n .split("")\n .reverse()\n .join("");\n}\n/**\n * Given the ends of approximate matches for `pattern` in `text`, find\n * the start of the matches.\n *\n * @param findEndFn - Function for finding the end of matches in\n * text.\n * @return Matches with the `start` property set.\n */\nfunction findMatchStarts(text, pattern, matches) {\n var patRev = reverse(pattern);\n return matches.map(function (m) {\n // Find start of each match by reversing the pattern and matching segment\n // of text and searching for an approx match with the same number of\n // errors.\n var minStart = Math.max(0, m.end - pattern.length - m.errors);\n var textRev = reverse(text.slice(minStart, m.end));\n // If there are multiple possible start points, choose the one that\n // maximizes the length of the match.\n var start = findMatchEnds(textRev, patRev, m.errors).reduce(function (min, rm) {\n if (m.end - rm.end < min) {\n return m.end - rm.end;\n }\n return min;\n }, m.end);\n return {\n start: start,\n end: m.end,\n errors: m.errors\n };\n });\n}\n/**\n * Return 1 if a number is non-zero or zero otherwise, without using\n * conditional operators.\n *\n * This should get inlined into `advanceBlock` below by the JIT.\n *\n * Adapted from https://stackoverflow.com/a/3912218/434243\n */\nfunction oneIfNotZero(n) {\n return ((n | -n) >> 31) & 1;\n}\n/**\n * Block calculation step of the algorithm.\n *\n * From Fig 8. on p. 408 of [1], additionally optimized to replace conditional\n * checks with bitwise operations as per Section 4.2.3 of [2].\n *\n * @param ctx - The pattern context object\n * @param peq - The `peq` array for the current character (`ctx.peq.get(ch)`)\n * @param b - The block level\n * @param hIn - Horizontal input delta ∈ {1,0,-1}\n * @return Horizontal output delta ∈ {1,0,-1}\n */\nfunction advanceBlock(ctx, peq, b, hIn) {\n var pV = ctx.P[b];\n var mV = ctx.M[b];\n var hInIsNegative = hIn >>> 31; // 1 if hIn < 0 or 0 otherwise.\n var eq = peq[b] | hInIsNegative;\n // Step 1: Compute horizontal deltas.\n var xV = eq | mV;\n var xH = (((eq & pV) + pV) ^ pV) | eq;\n var pH = mV | ~(xH | pV);\n var mH = pV & xH;\n // Step 2: Update score (value of last row of this block).\n var hOut = oneIfNotZero(pH & ctx.lastRowMask[b]) -\n oneIfNotZero(mH & ctx.lastRowMask[b]);\n // Step 3: Update vertical deltas for use when processing next char.\n pH <<= 1;\n mH <<= 1;\n mH |= hInIsNegative;\n pH |= oneIfNotZero(hIn) - hInIsNegative; // set pH[0] if hIn > 0\n pV = mH | ~(xV | pH);\n mV = pH & xV;\n ctx.P[b] = pV;\n ctx.M[b] = mV;\n return hOut;\n}\n/**\n * Find the ends and error counts for matches of `pattern` in `text`.\n *\n * Only the matches with the lowest error count are reported. Other matches\n * with error counts <= maxErrors are discarded.\n *\n * This is the block-based search algorithm from Fig. 9 on p.410 of [1].\n */\nfunction findMatchEnds(text, pattern, maxErrors) {\n if (pattern.length === 0) {\n return [];\n }\n // Clamp error count so we can rely on the `maxErrors` and `pattern.length`\n // rows being in the same block below.\n maxErrors = Math.min(maxErrors, pattern.length);\n var matches = [];\n // Word size.\n var w = 32;\n // Index of maximum block level.\n var bMax = Math.ceil(pattern.length / w) - 1;\n // Context used across block calculations.\n var ctx = {\n P: new Uint32Array(bMax + 1),\n M: new Uint32Array(bMax + 1),\n lastRowMask: new Uint32Array(bMax + 1)\n };\n ctx.lastRowMask.fill(1 << 31);\n ctx.lastRowMask[bMax] = 1 << (pattern.length - 1) % w;\n // Dummy "peq" array for chars in the text which do not occur in the pattern.\n var emptyPeq = new Uint32Array(bMax + 1);\n // Map of UTF-16 character code to bit vector indicating positions in the\n // pattern that equal that character.\n var peq = new Map();\n // Version of `peq` that only stores mappings for small characters. This\n // allows faster lookups when iterating through the text because a simple\n // array lookup can be done instead of a hash table lookup.\n var asciiPeq = [];\n for (var i = 0; i < 256; i++) {\n asciiPeq.push(emptyPeq);\n }\n // Calculate `ctx.peq` - a map of character values to bitmasks indicating\n // positions of that character within the pattern, where each bit represents\n // a position in the pattern.\n for (var c = 0; c < pattern.length; c += 1) {\n var val = pattern.charCodeAt(c);\n if (peq.has(val)) {\n // Duplicate char in pattern.\n continue;\n }\n var charPeq = new Uint32Array(bMax + 1);\n peq.set(val, charPeq);\n if (val < asciiPeq.length) {\n asciiPeq[val] = charPeq;\n }\n for (var b = 0; b <= bMax; b += 1) {\n charPeq[b] = 0;\n // Set all the bits where the pattern matches the current char (ch).\n // For indexes beyond the end of the pattern, always set the bit as if the\n // pattern contained a wildcard char in that position.\n for (var r = 0; r < w; r += 1) {\n var idx = b * w + r;\n if (idx >= pattern.length) {\n continue;\n }\n var match = pattern.charCodeAt(idx) === val;\n if (match) {\n charPeq[b] |= 1 << r;\n }\n }\n }\n }\n // Index of last-active block level in the column.\n var y = Math.max(0, Math.ceil(maxErrors / w) - 1);\n // Initialize maximum error count at bottom of each block.\n var score = new Uint32Array(bMax + 1);\n for (var b = 0; b <= y; b += 1) {\n score[b] = (b + 1) * w;\n }\n score[bMax] = pattern.length;\n // Initialize vertical deltas for each block.\n for (var b = 0; b <= y; b += 1) {\n ctx.P[b] = ~0;\n ctx.M[b] = 0;\n }\n // Process each char of the text, computing the error count for `w` chars of\n // the pattern at a time.\n for (var j = 0; j < text.length; j += 1) {\n // Lookup the bitmask representing the positions of the current char from\n // the text within the pattern.\n var charCode = text.charCodeAt(j);\n var charPeq = void 0;\n if (charCode < asciiPeq.length) {\n // Fast array lookup.\n charPeq = asciiPeq[charCode];\n }\n else {\n // Slower hash table lookup.\n charPeq = peq.get(charCode);\n if (typeof charPeq === "undefined") {\n charPeq = emptyPeq;\n }\n }\n // Calculate error count for blocks that we definitely have to process for\n // this column.\n var carry = 0;\n for (var b = 0; b <= y; b += 1) {\n carry = advanceBlock(ctx, charPeq, b, carry);\n score[b] += carry;\n }\n // Check if we also need to compute an additional block, or if we can reduce\n // the number of blocks processed for the next column.\n if (score[y] - carry <= maxErrors &&\n y < bMax &&\n (charPeq[y + 1] & 1 || carry < 0)) {\n // Error count for bottom block is under threshold, increase the number of\n // blocks processed for this column & next by 1.\n y += 1;\n ctx.P[y] = ~0;\n ctx.M[y] = 0;\n var maxBlockScore = y === bMax ? pattern.length % w : w;\n score[y] =\n score[y - 1] +\n maxBlockScore -\n carry +\n advanceBlock(ctx, charPeq, y, carry);\n }\n else {\n // Error count for bottom block exceeds threshold, reduce the number of\n // blocks processed for the next column.\n while (y > 0 && score[y] >= maxErrors + w) {\n y -= 1;\n }\n }\n // If error count is under threshold, report a match.\n if (y === bMax && score[y] <= maxErrors) {\n if (score[y] < maxErrors) {\n // Discard any earlier, worse matches.\n matches.splice(0, matches.length);\n }\n matches.push({\n start: -1,\n end: j + 1,\n errors: score[y]\n });\n // Because `search` only reports the matches with the lowest error count,\n // we can "ratchet down" the max error threshold whenever a match is\n // encountered and thereby save a small amount of work for the remainder\n // of the text.\n maxErrors = score[y];\n }\n }\n return matches;\n}\n/**\n * Search for matches for `pattern` in `text` allowing up to `maxErrors` errors.\n *\n * Returns the start, and end positions and error counts for each lowest-cost\n * match. Only the "best" matches are returned.\n */\nfunction search(text, pattern, maxErrors) {\n var matches = findMatchEnds(text, pattern, maxErrors);\n return findMatchStarts(text, pattern, matches);\n}\nexports.Z = search;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA4OS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkMsRUFBRSxhQUFhLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLE9BQU87QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2FwcHJveC1zdHJpbmctbWF0Y2gvZGlzdC9pbmRleC5qcz83MjMwIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBNeWVycycgb25saW5lIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBhbGdvcml0aG0gWzFdLFxuICogd2l0aCBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgc3VnZ2VzdGVkIGJ5IFsyXS5cbiAqXG4gKiBUaGlzIGhhcyBPKChrL3cpICogbikgY29tcGxleGl0eSB3aGVyZSBgbmAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCwgYGtgIGlzXG4gKiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIGFsbG93ZWQgKGFsd2F5cyA8PSB0aGUgcGF0dGVybiBsZW5ndGgpIGFuZCBgd2BcbiAqIGlzIHRoZSB3b3JkIHNpemUuIEJlY2F1c2UgSlMgb25seSBzdXBwb3J0cyBiaXR3aXNlIG9wZXJhdGlvbnMgb24gMzIgYml0XG4gKiBpbnRlZ2VycywgYHdgIGlzIDMyLlxuICpcbiAqIEFzIGZhciBhcyBJIGFtIGF3YXJlLCB0aGVyZSBhcmVuJ3QgYW55IG9ubGluZSBhbGdvcml0aG1zIHdoaWNoIGFyZVxuICogc2lnbmlmaWNhbnRseSBiZXR0ZXIgZm9yIGEgd2lkZSByYW5nZSBvZiBpbnB1dCBwYXJhbWV0ZXJzLiBUaGUgcHJvYmxlbSBjYW4gYmVcbiAqIHNvbHZlZCBmYXN0ZXIgdXNpbmcgXCJmaWx0ZXIgdGhlbiB2ZXJpZnlcIiBhcHByb2FjaGVzIHdoaWNoIGZpcnN0IGZpbHRlciBvdXRcbiAqIHJlZ2lvbnMgb2YgdGhlIHRleHQgdGhhdCBjYW5ub3QgbWF0Y2ggdXNpbmcgYSBcImNoZWFwXCIgY2hlY2sgYW5kIHRoZW4gdmVyaWZ5XG4gKiB0aGUgcmVtYWluaW5nIHBvdGVudGlhbCBtYXRjaGVzLiBUaGUgdmVyaWZ5IHN0ZXAgcmVxdWlyZXMgYW4gYWxnb3JpdGhtIHN1Y2hcbiAqIGFzIHRoaXMgb25lIGhvd2V2ZXIuXG4gKlxuICogVGhlIGFsZ29yaXRobSdzIGFwcHJvYWNoIGlzIGVzc2VudGlhbGx5IHRvIG9wdGltaXplIHRoZSBjbGFzc2ljIGR5bmFtaWNcbiAqIHByb2dyYW1taW5nIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGJ5IGNvbXB1dGluZyBjb2x1bW5zIG9mIHRoZSBtYXRyaXggaW5cbiAqIHdvcmQtc2l6ZWQgY2h1bmtzIChpZS4gZGVhbGluZyB3aXRoIDMyIGNoYXJzIG9mIHRoZSBwYXR0ZXJuIGF0IGEgdGltZSkgYW5kXG4gKiBhdm9pZGluZyBjYWxjdWxhdGluZyByZWdpb25zIG9mIHRoZSBtYXRyaXggd2hlcmUgdGhlIG1pbmltdW0gZXJyb3IgY291bnQgaXNcbiAqIGd1YXJhbnRlZWQgdG8gZXhjZWVkIHRoZSBpbnB1dCB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHBhcGVyIGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgdGhlIGZpcnN0IGRlc2NyaWJlcyB0aGUgY29yZSBhbGdvcml0aG0gZm9yXG4gKiBtYXRjaGluZyBwYXR0ZXJucyA8PSB0aGUgc2l6ZSBvZiBhIHdvcmQgKGltcGxlbWVudGVkIGJ5IGBhZHZhbmNlQmxvY2tgIGhlcmUpLlxuICogVGhlIHNlY29uZCB1c2VzIHRoZSBjb3JlIGFsZ29yaXRobSBhcyBwYXJ0IG9mIGEgbGFyZ2VyIGJsb2NrLWJhc2VkIGFsZ29yaXRobVxuICogdG8gaGFuZGxlIGxvbmdlciBwYXR0ZXJucy5cbiAqXG4gKiBbMV0gRy4gTXllcnMsIOKAnEEgRmFzdCBCaXQtVmVjdG9yIEFsZ29yaXRobSBmb3IgQXBwcm94aW1hdGUgU3RyaW5nIE1hdGNoaW5nXG4gKiBCYXNlZCBvbiBEeW5hbWljIFByb2dyYW1taW5nLOKAnSB2b2wuIDQ2LCBuby4gMywgcHAuIDM5NeKAkzQxNSwgMTk5OS5cbiAqXG4gKiBbMl0gxaBvxaFpxIcsIE0uICgyMDE0KS4gQW4gc2ltZCBkeW5hbWljIHByb2dyYW1taW5nIGMvYysrIGxpYnJhcnkgKERvY3RvcmFsXG4gKiBkaXNzZXJ0YXRpb24sIEZha3VsdGV0IEVsZWt0cm90ZWhuaWtlIGkgcmHEjXVuYXJzdHZhLCBTdmV1xI1pbGnFoXRlIHUgWmFncmVidSkuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJldmVyc2Uocykge1xuICAgIHJldHVybiBzXG4gICAgICAgIC5zcGxpdChcIlwiKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5qb2luKFwiXCIpO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgZW5kcyBvZiBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHRleHRgLCBmaW5kXG4gKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMuXG4gKlxuICogQHBhcmFtIGZpbmRFbmRGbiAtIEZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBlbmQgb2YgbWF0Y2hlcyBpblxuICogdGV4dC5cbiAqIEByZXR1cm4gTWF0Y2hlcyB3aXRoIHRoZSBgc3RhcnRgIHByb3BlcnR5IHNldC5cbiAqL1xuZnVuY3Rpb24gZmluZE1hdGNoU3RhcnRzKHRleHQsIHBhdHRlcm4sIG1hdGNoZXMpIHtcbiAgICB2YXIgcGF0UmV2ID0gcmV2ZXJzZShwYXR0ZXJuKTtcbiAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgLy8gRmluZCBzdGFydCBvZiBlYWNoIG1hdGNoIGJ5IHJldmVyc2luZyB0aGUgcGF0dGVybiBhbmQgbWF0Y2hpbmcgc2VnbWVudFxuICAgICAgICAvLyBvZiB0ZXh0IGFuZCBzZWFyY2hpbmcgZm9yIGFuIGFwcHJveCBtYXRjaCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZlxuICAgICAgICAvLyBlcnJvcnMuXG4gICAgICAgIHZhciBtaW5TdGFydCA9IE1hdGgubWF4KDAsIG0uZW5kIC0gcGF0dGVybi5sZW5ndGggLSBtLmVycm9ycyk7XG4gICAgICAgIHZhciB0ZXh0UmV2ID0gcmV2ZXJzZSh0ZXh0LnNsaWNlKG1pblN0YXJ0LCBtLmVuZCkpO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgc3RhcnQgcG9pbnRzLCBjaG9vc2UgdGhlIG9uZSB0aGF0XG4gICAgICAgIC8vIG1heGltaXplcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaC5cbiAgICAgICAgdmFyIHN0YXJ0ID0gZmluZE1hdGNoRW5kcyh0ZXh0UmV2LCBwYXRSZXYsIG0uZXJyb3JzKS5yZWR1Y2UoZnVuY3Rpb24gKG1pbiwgcm0pIHtcbiAgICAgICAgICAgIGlmIChtLmVuZCAtIHJtLmVuZCA8IG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmVuZCAtIHJtLmVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtaW47XG4gICAgICAgIH0sIG0uZW5kKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogbS5lbmQsXG4gICAgICAgICAgICBlcnJvcnM6IG0uZXJyb3JzXG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybiAxIGlmIGEgbnVtYmVyIGlzIG5vbi16ZXJvIG9yIHplcm8gb3RoZXJ3aXNlLCB3aXRob3V0IHVzaW5nXG4gKiBjb25kaXRpb25hbCBvcGVyYXRvcnMuXG4gKlxuICogVGhpcyBzaG91bGQgZ2V0IGlubGluZWQgaW50byBgYWR2YW5jZUJsb2NrYCBiZWxvdyBieSB0aGUgSklULlxuICpcbiAqIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzkxMjIxOC80MzQyNDNcbiAqL1xuZnVuY3Rpb24gb25lSWZOb3RaZXJvKG4pIHtcbiAgICByZXR1cm4gKChuIHwgLW4pID4+IDMxKSAmIDE7XG59XG4vKipcbiAqIEJsb2NrIGNhbGN1bGF0aW9uIHN0ZXAgb2YgdGhlIGFsZ29yaXRobS5cbiAqXG4gKiBGcm9tIEZpZyA4LiBvbiBwLiA0MDggb2YgWzFdLCBhZGRpdGlvbmFsbHkgb3B0aW1pemVkIHRvIHJlcGxhY2UgY29uZGl0aW9uYWxcbiAqIGNoZWNrcyB3aXRoIGJpdHdpc2Ugb3BlcmF0aW9ucyBhcyBwZXIgU2VjdGlvbiA0LjIuMyBvZiBbMl0uXG4gKlxuICogQHBhcmFtIGN0eCAtIFRoZSBwYXR0ZXJuIGNvbnRleHQgb2JqZWN0XG4gKiBAcGFyYW0gcGVxIC0gVGhlIGBwZXFgIGFycmF5IGZvciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgKGBjdHgucGVxLmdldChjaClgKVxuICogQHBhcmFtIGIgLSBUaGUgYmxvY2sgbGV2ZWxcbiAqIEBwYXJhbSBoSW4gLSBIb3Jpem9udGFsIGlucHV0IGRlbHRhIOKIiCB7MSwwLC0xfVxuICogQHJldHVybiBIb3Jpem9udGFsIG91dHB1dCBkZWx0YSDiiIggezEsMCwtMX1cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUJsb2NrKGN0eCwgcGVxLCBiLCBoSW4pIHtcbiAgICB2YXIgcFYgPSBjdHguUFtiXTtcbiAgICB2YXIgbVYgPSBjdHguTVtiXTtcbiAgICB2YXIgaEluSXNOZWdhdGl2ZSA9IGhJbiA+Pj4gMzE7IC8vIDEgaWYgaEluIDwgMCBvciAwIG90aGVyd2lzZS5cbiAgICB2YXIgZXEgPSBwZXFbYl0gfCBoSW5Jc05lZ2F0aXZlO1xuICAgIC8vIFN0ZXAgMTogQ29tcHV0ZSBob3Jpem9udGFsIGRlbHRhcy5cbiAgICB2YXIgeFYgPSBlcSB8IG1WO1xuICAgIHZhciB4SCA9ICgoKGVxICYgcFYpICsgcFYpIF4gcFYpIHwgZXE7XG4gICAgdmFyIHBIID0gbVYgfCB+KHhIIHwgcFYpO1xuICAgIHZhciBtSCA9IHBWICYgeEg7XG4gICAgLy8gU3RlcCAyOiBVcGRhdGUgc2NvcmUgKHZhbHVlIG9mIGxhc3Qgcm93IG9mIHRoaXMgYmxvY2spLlxuICAgIHZhciBoT3V0ID0gb25lSWZOb3RaZXJvKHBIICYgY3R4Lmxhc3RSb3dNYXNrW2JdKSAtXG4gICAgICAgIG9uZUlmTm90WmVybyhtSCAmIGN0eC5sYXN0Um93TWFza1tiXSk7XG4gICAgLy8gU3RlcCAzOiBVcGRhdGUgdmVydGljYWwgZGVsdGFzIGZvciB1c2Ugd2hlbiBwcm9jZXNzaW5nIG5leHQgY2hhci5cbiAgICBwSCA8PD0gMTtcbiAgICBtSCA8PD0gMTtcbiAgICBtSCB8PSBoSW5Jc05lZ2F0aXZlO1xuICAgIHBIIHw9IG9uZUlmTm90WmVybyhoSW4pIC0gaEluSXNOZWdhdGl2ZTsgLy8gc2V0IHBIWzBdIGlmIGhJbiA+IDBcbiAgICBwViA9IG1IIHwgfih4ViB8IHBIKTtcbiAgICBtViA9IHBIICYgeFY7XG4gICAgY3R4LlBbYl0gPSBwVjtcbiAgICBjdHguTVtiXSA9IG1WO1xuICAgIHJldHVybiBoT3V0O1xufVxuLyoqXG4gKiBGaW5kIHRoZSBlbmRzIGFuZCBlcnJvciBjb3VudHMgZm9yIG1hdGNoZXMgb2YgYHBhdHRlcm5gIGluIGB0ZXh0YC5cbiAqXG4gKiBPbmx5IHRoZSBtYXRjaGVzIHdpdGggdGhlIGxvd2VzdCBlcnJvciBjb3VudCBhcmUgcmVwb3J0ZWQuIE90aGVyIG1hdGNoZXNcbiAqIHdpdGggZXJyb3IgY291bnRzIDw9IG1heEVycm9ycyBhcmUgZGlzY2FyZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGJsb2NrLWJhc2VkIHNlYXJjaCBhbGdvcml0aG0gZnJvbSBGaWcuIDkgb24gcC40MTAgb2YgWzFdLlxuICovXG5mdW5jdGlvbiBmaW5kTWF0Y2hFbmRzKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIENsYW1wIGVycm9yIGNvdW50IHNvIHdlIGNhbiByZWx5IG9uIHRoZSBgbWF4RXJyb3JzYCBhbmQgYHBhdHRlcm4ubGVuZ3RoYFxuICAgIC8vIHJvd3MgYmVpbmcgaW4gdGhlIHNhbWUgYmxvY2sgYmVsb3cuXG4gICAgbWF4RXJyb3JzID0gTWF0aC5taW4obWF4RXJyb3JzLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgICAvLyBXb3JkIHNpemUuXG4gICAgdmFyIHcgPSAzMjtcbiAgICAvLyBJbmRleCBvZiBtYXhpbXVtIGJsb2NrIGxldmVsLlxuICAgIHZhciBiTWF4ID0gTWF0aC5jZWlsKHBhdHRlcm4ubGVuZ3RoIC8gdykgLSAxO1xuICAgIC8vIENvbnRleHQgdXNlZCBhY3Jvc3MgYmxvY2sgY2FsY3VsYXRpb25zLlxuICAgIHZhciBjdHggPSB7XG4gICAgICAgIFA6IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIE06IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIGxhc3RSb3dNYXNrOiBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpXG4gICAgfTtcbiAgICBjdHgubGFzdFJvd01hc2suZmlsbCgxIDw8IDMxKTtcbiAgICBjdHgubGFzdFJvd01hc2tbYk1heF0gPSAxIDw8IChwYXR0ZXJuLmxlbmd0aCAtIDEpICUgdztcbiAgICAvLyBEdW1teSBcInBlcVwiIGFycmF5IGZvciBjaGFycyBpbiB0aGUgdGV4dCB3aGljaCBkbyBub3Qgb2NjdXIgaW4gdGhlIHBhdHRlcm4uXG4gICAgdmFyIGVtcHR5UGVxID0gbmV3IFVpbnQzMkFycmF5KGJNYXggKyAxKTtcbiAgICAvLyBNYXAgb2YgVVRGLTE2IGNoYXJhY3RlciBjb2RlIHRvIGJpdCB2ZWN0b3IgaW5kaWNhdGluZyBwb3NpdGlvbnMgaW4gdGhlXG4gICAgLy8gcGF0dGVybiB0aGF0IGVxdWFsIHRoYXQgY2hhcmFjdGVyLlxuICAgIHZhciBwZXEgPSBuZXcgTWFwKCk7XG4gICAgLy8gVmVyc2lvbiBvZiBgcGVxYCB0aGF0IG9ubHkgc3RvcmVzIG1hcHBpbmdzIGZvciBzbWFsbCBjaGFyYWN0ZXJzLiBUaGlzXG4gICAgLy8gYWxsb3dzIGZhc3RlciBsb29rdXBzIHdoZW4gaXRlcmF0aW5nIHRocm91Z2ggdGhlIHRleHQgYmVjYXVzZSBhIHNpbXBsZVxuICAgIC8vIGFycmF5IGxvb2t1cCBjYW4gYmUgZG9uZSBpbnN0ZWFkIG9mIGEgaGFzaCB0YWJsZSBsb29rdXAuXG4gICAgdmFyIGFzY2lpUGVxID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgICBhc2NpaVBlcS5wdXNoKGVtcHR5UGVxKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlIGBjdHgucGVxYCAtIGEgbWFwIG9mIGNoYXJhY3RlciB2YWx1ZXMgdG8gYml0bWFza3MgaW5kaWNhdGluZ1xuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGF0IGNoYXJhY3RlciB3aXRoaW4gdGhlIHBhdHRlcm4sIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHNcbiAgICAvLyBhIHBvc2l0aW9uIGluIHRoZSBwYXR0ZXJuLlxuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgcGF0dGVybi5sZW5ndGg7IGMgKz0gMSkge1xuICAgICAgICB2YXIgdmFsID0gcGF0dGVybi5jaGFyQ29kZUF0KGMpO1xuICAgICAgICBpZiAocGVxLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgY2hhciBpbiBwYXR0ZXJuLlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoYXJQZXEgPSBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpO1xuICAgICAgICBwZXEuc2V0KHZhbCwgY2hhclBlcSk7XG4gICAgICAgIGlmICh2YWwgPCBhc2NpaVBlcS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFzY2lpUGVxW3ZhbF0gPSBjaGFyUGVxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGIgPSAwOyBiIDw9IGJNYXg7IGIgKz0gMSkge1xuICAgICAgICAgICAgY2hhclBlcVtiXSA9IDA7XG4gICAgICAgICAgICAvLyBTZXQgYWxsIHRoZSBiaXRzIHdoZXJlIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGN1cnJlbnQgY2hhciAoY2gpLlxuICAgICAgICAgICAgLy8gRm9yIGluZGV4ZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIGFsd2F5cyBzZXQgdGhlIGJpdCBhcyBpZiB0aGVcbiAgICAgICAgICAgIC8vIHBhdHRlcm4gY29udGFpbmVkIGEgd2lsZGNhcmQgY2hhciBpbiB0aGF0IHBvc2l0aW9uLlxuICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCB3OyByICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gYiAqIHcgKyByO1xuICAgICAgICAgICAgICAgIGlmIChpZHggPj0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IHBhdHRlcm4uY2hhckNvZGVBdChpZHgpID09PSB2YWw7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJQZXFbYl0gfD0gMSA8PCByO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJbmRleCBvZiBsYXN0LWFjdGl2ZSBibG9jayBsZXZlbCBpbiB0aGUgY29sdW1uLlxuICAgIHZhciB5ID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKG1heEVycm9ycyAvIHcpIC0gMSk7XG4gICAgLy8gSW5pdGlhbGl6ZSBtYXhpbXVtIGVycm9yIGNvdW50IGF0IGJvdHRvbSBvZiBlYWNoIGJsb2NrLlxuICAgIHZhciBzY29yZSA9IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSk7XG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIHNjb3JlW2JdID0gKGIgKyAxKSAqIHc7XG4gICAgfVxuICAgIHNjb3JlW2JNYXhdID0gcGF0dGVybi5sZW5ndGg7XG4gICAgLy8gSW5pdGlhbGl6ZSB2ZXJ0aWNhbCBkZWx0YXMgZm9yIGVhY2ggYmxvY2suXG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIGN0eC5QW2JdID0gfjA7XG4gICAgICAgIGN0eC5NW2JdID0gMDtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBlYWNoIGNoYXIgb2YgdGhlIHRleHQsIGNvbXB1dGluZyB0aGUgZXJyb3IgY291bnQgZm9yIGB3YCBjaGFycyBvZlxuICAgIC8vIHRoZSBwYXR0ZXJuIGF0IGEgdGltZS5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRleHQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBiaXRtYXNrIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb25zIG9mIHRoZSBjdXJyZW50IGNoYXIgZnJvbVxuICAgICAgICAvLyB0aGUgdGV4dCB3aXRoaW4gdGhlIHBhdHRlcm4uXG4gICAgICAgIHZhciBjaGFyQ29kZSA9IHRleHQuY2hhckNvZGVBdChqKTtcbiAgICAgICAgdmFyIGNoYXJQZXEgPSB2b2lkIDA7XG4gICAgICAgIGlmIChjaGFyQ29kZSA8IGFzY2lpUGVxLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gRmFzdCBhcnJheSBsb29rdXAuXG4gICAgICAgICAgICBjaGFyUGVxID0gYXNjaWlQZXFbY2hhckNvZGVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU2xvd2VyIGhhc2ggdGFibGUgbG9va3VwLlxuICAgICAgICAgICAgY2hhclBlcSA9IHBlcS5nZXQoY2hhckNvZGUpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyUGVxID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgY2hhclBlcSA9IGVtcHR5UGVxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3VudCBmb3IgYmxvY2tzIHRoYXQgd2UgZGVmaW5pdGVseSBoYXZlIHRvIHByb2Nlc3MgZm9yXG4gICAgICAgIC8vIHRoaXMgY29sdW1uLlxuICAgICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBiID0gMDsgYiA8PSB5OyBiICs9IDEpIHtcbiAgICAgICAgICAgIGNhcnJ5ID0gYWR2YW5jZUJsb2NrKGN0eCwgY2hhclBlcSwgYiwgY2FycnkpO1xuICAgICAgICAgICAgc2NvcmVbYl0gKz0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgYWxzbyBuZWVkIHRvIGNvbXB1dGUgYW4gYWRkaXRpb25hbCBibG9jaywgb3IgaWYgd2UgY2FuIHJlZHVjZVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGJsb2NrcyBwcm9jZXNzZWQgZm9yIHRoZSBuZXh0IGNvbHVtbi5cbiAgICAgICAgaWYgKHNjb3JlW3ldIC0gY2FycnkgPD0gbWF4RXJyb3JzICYmXG4gICAgICAgICAgICB5IDwgYk1heCAmJlxuICAgICAgICAgICAgKGNoYXJQZXFbeSArIDFdICYgMSB8fCBjYXJyeSA8IDApKSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGlzIHVuZGVyIHRocmVzaG9sZCwgaW5jcmVhc2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhpcyBjb2x1bW4gJiBuZXh0IGJ5IDEuXG4gICAgICAgICAgICB5ICs9IDE7XG4gICAgICAgICAgICBjdHguUFt5XSA9IH4wO1xuICAgICAgICAgICAgY3R4Lk1beV0gPSAwO1xuICAgICAgICAgICAgdmFyIG1heEJsb2NrU2NvcmUgPSB5ID09PSBiTWF4ID8gcGF0dGVybi5sZW5ndGggJSB3IDogdztcbiAgICAgICAgICAgIHNjb3JlW3ldID1cbiAgICAgICAgICAgICAgICBzY29yZVt5IC0gMV0gK1xuICAgICAgICAgICAgICAgICAgICBtYXhCbG9ja1Njb3JlIC1cbiAgICAgICAgICAgICAgICAgICAgY2FycnkgK1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlQmxvY2soY3R4LCBjaGFyUGVxLCB5LCBjYXJyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGV4Y2VlZHMgdGhyZXNob2xkLCByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhlIG5leHQgY29sdW1uLlxuICAgICAgICAgICAgd2hpbGUgKHkgPiAwICYmIHNjb3JlW3ldID49IG1heEVycm9ycyArIHcpIHtcbiAgICAgICAgICAgICAgICB5IC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZXJyb3IgY291bnQgaXMgdW5kZXIgdGhyZXNob2xkLCByZXBvcnQgYSBtYXRjaC5cbiAgICAgICAgaWYgKHkgPT09IGJNYXggJiYgc2NvcmVbeV0gPD0gbWF4RXJyb3JzKSB7XG4gICAgICAgICAgICBpZiAoc2NvcmVbeV0gPCBtYXhFcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIGFueSBlYXJsaWVyLCB3b3JzZSBtYXRjaGVzLlxuICAgICAgICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKDAsIG1hdGNoZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICAgICAgICAgIGVuZDogaiArIDEsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBzY29yZVt5XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBCZWNhdXNlIGBzZWFyY2hgIG9ubHkgcmVwb3J0cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBsb3dlc3QgZXJyb3IgY291bnQsXG4gICAgICAgICAgICAvLyB3ZSBjYW4gXCJyYXRjaGV0IGRvd25cIiB0aGUgbWF4IGVycm9yIHRocmVzaG9sZCB3aGVuZXZlciBhIG1hdGNoIGlzXG4gICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbmQgdGhlcmVieSBzYXZlIGEgc21hbGwgYW1vdW50IG9mIHdvcmsgZm9yIHRoZSByZW1haW5kZXJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB0ZXh0LlxuICAgICAgICAgICAgbWF4RXJyb3JzID0gc2NvcmVbeV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59XG4vKipcbiAqIFNlYXJjaCBmb3IgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogUmV0dXJucyB0aGUgc3RhcnQsIGFuZCBlbmQgcG9zaXRpb25zIGFuZCBlcnJvciBjb3VudHMgZm9yIGVhY2ggbG93ZXN0LWNvc3RcbiAqIG1hdGNoLiBPbmx5IHRoZSBcImJlc3RcIiBtYXRjaGVzIGFyZSByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoRW5kcyh0ZXh0LCBwYXR0ZXJuLCBtYXhFcnJvcnMpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hTdGFydHModGV4dCwgcGF0dGVybiwgbWF0Y2hlcyk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzZWFyY2g7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3089\n')},5298:function(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__){"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/approx-string-match/dist/index.js\nvar dist = __webpack_require__(3089);\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/match-quote.js\n\n/**\n * @typedef {import(\'approx-string-match\').Match} StringMatch\n */\n\n/**\n * @typedef Match\n * @prop {number} start - Start offset of match in text\n * @prop {number} end - End offset of match in text\n * @prop {number} score -\n * Score for the match between 0 and 1.0, where 1.0 indicates a perfect match\n * for the quote and context.\n */\n\n/**\n * Find the best approximate matches for `str` in `text` allowing up to `maxErrors` errors.\n *\n * @param {string} text\n * @param {string} str\n * @param {number} maxErrors\n * @return {StringMatch[]}\n */\n\nfunction search(text, str, maxErrors) {\n // Do a fast search for exact matches. The `approx-string-match` library\n // doesn\'t currently incorporate this optimization itself.\n var matchPos = 0;\n var exactMatches = [];\n\n while (matchPos !== -1) {\n matchPos = text.indexOf(str, matchPos);\n\n if (matchPos !== -1) {\n exactMatches.push({\n start: matchPos,\n end: matchPos + str.length,\n errors: 0\n });\n matchPos += 1;\n }\n }\n\n if (exactMatches.length > 0) {\n return exactMatches;\n } // If there are no exact matches, do a more expensive search for matches\n // with errors.\n\n\n return (0,dist/* default */.Z)(text, str, maxErrors);\n}\n/**\n * Compute a score between 0 and 1.0 for the similarity between `text` and `str`.\n *\n * @param {string} text\n * @param {string} str\n */\n\n\nfunction textMatchScore(text, str) {\n /* istanbul ignore next - `scoreMatch` will never pass an empty string */\n if (str.length === 0 || text.length === 0) {\n return 0.0;\n }\n\n var matches = search(text, str, str.length); // prettier-ignore\n\n return 1 - matches[0].errors / str.length;\n}\n/**\n * Find the best approximate match for `quote` in `text`.\n *\n * Returns `null` if no match exceeding the minimum quality threshold was found.\n *\n * @param {string} text - Document text to search\n * @param {string} quote - String to find within `text`\n * @param {Object} context -\n * Context in which the quote originally appeared. This is used to choose the\n * best match.\n * @param {string} [context.prefix] - Expected text before the quote\n * @param {string} [context.suffix] - Expected text after the quote\n * @param {number} [context.hint] - Expected offset of match within text\n * @return {Match|null}\n */\n\n\nfunction matchQuote(text, quote) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (quote.length === 0) {\n return null;\n } // Choose the maximum number of errors to allow for the initial search.\n // This choice involves a tradeoff between:\n //\n // - Recall (proportion of "good" matches found)\n // - Precision (proportion of matches found which are "good")\n // - Cost of the initial search and of processing the candidate matches [1]\n //\n // [1] Specifically, the expected-time complexity of the initial search is\n // `O((maxErrors / 32) * text.length)`. See `approx-string-match` docs.\n\n\n var maxErrors = Math.min(256, quote.length / 2); // Find closest matches for `quote` in `text` based on edit distance.\n\n var matches = search(text, quote, maxErrors);\n\n if (matches.length === 0) {\n return null;\n }\n /**\n * Compute a score between 0 and 1.0 for a match candidate.\n *\n * @param {StringMatch} match\n */\n\n\n var scoreMatch = function scoreMatch(match) {\n var quoteWeight = 50; // Similarity of matched text to quote.\n\n var prefixWeight = 20; // Similarity of text before matched text to `context.prefix`.\n\n var suffixWeight = 20; // Similarity of text after matched text to `context.suffix`.\n\n var posWeight = 2; // Proximity to expected location. Used as a tie-breaker.\n\n var quoteScore = 1 - match.errors / quote.length;\n var prefixScore = context.prefix ? textMatchScore(text.slice(Math.max(0, match.start - context.prefix.length), match.start), context.prefix) : 1.0;\n var suffixScore = context.suffix ? textMatchScore(text.slice(match.end, match.end + context.suffix.length), context.suffix) : 1.0;\n var posScore = 1.0;\n\n if (typeof context.hint === \'number\') {\n var offset = Math.abs(match.start - context.hint);\n posScore = 1.0 - offset / text.length;\n }\n\n var rawScore = quoteWeight * quoteScore + prefixWeight * prefixScore + suffixWeight * suffixScore + posWeight * posScore;\n var maxScore = quoteWeight + prefixWeight + suffixWeight + posWeight;\n var normalizedScore = rawScore / maxScore;\n return normalizedScore;\n }; // Rank matches based on similarity of actual and expected surrounding text\n // and actual/expected offset in the document text.\n\n\n var scoredMatches = matches.map(function (m) {\n return {\n start: m.start,\n end: m.end,\n score: scoreMatch(m)\n };\n }); // Choose match with highest score.\n\n scoredMatches.sort(function (a, b) {\n return b.score - a.score;\n });\n return scoredMatches[0];\n}\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/text-range.js\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Return the combined length of text nodes contained in `node`.\n *\n * @param {Node} node\n */\nfunction nodeTextLength(node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.TEXT_NODE:\n // nb. `textContent` excludes text in comments and processing instructions\n // when called on a parent element, so we don\'t need to subtract that here.\n return (\n /** @type {string} */\n node.textContent.length\n );\n\n default:\n return 0;\n }\n}\n/**\n * Return the total length of the text of all previous siblings of `node`.\n *\n * @param {Node} node\n */\n\n\nfunction previousSiblingsTextLength(node) {\n var sibling = node.previousSibling;\n var length = 0;\n\n while (sibling) {\n length += nodeTextLength(sibling);\n sibling = sibling.previousSibling;\n }\n\n return length;\n}\n/**\n * Resolve one or more character offsets within an element to (text node, position)\n * pairs.\n *\n * @param {Element} element\n * @param {number[]} offsets - Offsets, which must be sorted in ascending order\n * @return {{ node: Text, offset: number }[]}\n */\n\n\nfunction resolveOffsets(element) {\n for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n offsets[_key - 1] = arguments[_key];\n }\n\n var nextOffset = offsets.shift();\n var nodeIter =\n /** @type {Document} */\n element.ownerDocument.createNodeIterator(element, NodeFilter.SHOW_TEXT);\n var results = [];\n var currentNode = nodeIter.nextNode();\n var textNode;\n var length = 0; // Find the text node containing the `nextOffset`th character from the start\n // of `element`.\n\n while (nextOffset !== undefined && currentNode) {\n textNode =\n /** @type {Text} */\n currentNode;\n\n if (length + textNode.data.length > nextOffset) {\n results.push({\n node: textNode,\n offset: nextOffset - length\n });\n nextOffset = offsets.shift();\n } else {\n currentNode = nodeIter.nextNode();\n length += textNode.data.length;\n }\n } // Boundary case.\n\n\n while (nextOffset !== undefined && textNode && length === nextOffset) {\n results.push({\n node: textNode,\n offset: textNode.data.length\n });\n nextOffset = offsets.shift();\n }\n\n if (nextOffset !== undefined) {\n throw new RangeError(\'Offset exceeds text length\');\n }\n\n return results;\n}\n\nvar RESOLVE_FORWARDS = 1;\nvar RESOLVE_BACKWARDS = 2;\n/**\n * Represents an offset within the text content of an element.\n *\n * This position can be resolved to a specific descendant node in the current\n * DOM subtree of the element using the `resolve` method.\n */\n\nvar text_range_TextPosition = /*#__PURE__*/function () {\n /**\n * Construct a `TextPosition` that refers to the text position `offset` within\n * the text content of `element`.\n *\n * @param {Element} element\n * @param {number} offset\n */\n function TextPosition(element, offset) {\n _classCallCheck(this, TextPosition);\n\n if (offset < 0) {\n throw new Error(\'Offset is invalid\');\n }\n /** Element that `offset` is relative to. */\n\n\n this.element = element;\n /** Character offset from the start of the element\'s `textContent`. */\n\n this.offset = offset;\n }\n /**\n * Return a copy of this position with offset relative to a given ancestor\n * element.\n *\n * @param {Element} parent - Ancestor of `this.element`\n * @return {TextPosition}\n */\n\n\n _createClass(TextPosition, [{\n key: "relativeTo",\n value: function relativeTo(parent) {\n if (!parent.contains(this.element)) {\n throw new Error(\'Parent is not an ancestor of current element\');\n }\n\n var el = this.element;\n var offset = this.offset;\n\n while (el !== parent) {\n offset += previousSiblingsTextLength(el);\n el =\n /** @type {Element} */\n el.parentElement;\n }\n\n return new TextPosition(el, offset);\n }\n /**\n * Resolve the position to a specific text node and offset within that node.\n *\n * Throws if `this.offset` exceeds the length of the element\'s text. In the\n * case where the element has no text and `this.offset` is 0, the `direction`\n * option determines what happens.\n *\n * Offsets at the boundary between two nodes are resolved to the start of the\n * node that begins at the boundary.\n *\n * @param {Object} [options]\n * @param {RESOLVE_FORWARDS|RESOLVE_BACKWARDS} [options.direction] -\n * Specifies in which direction to search for the nearest text node if\n * `this.offset` is `0` and `this.element` has no text. If not specified\n * an error is thrown.\n * @return {{ node: Text, offset: number }}\n * @throws {RangeError}\n */\n\n }, {\n key: "resolve",\n value: function resolve() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n try {\n return resolveOffsets(this.element, this.offset)[0];\n } catch (err) {\n if (this.offset === 0 && options.direction !== undefined) {\n var tw = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);\n tw.currentNode = this.element;\n var forwards = options.direction === RESOLVE_FORWARDS;\n var text =\n /** @type {Text|null} */\n forwards ? tw.nextNode() : tw.previousNode();\n\n if (!text) {\n throw err;\n }\n\n return {\n node: text,\n offset: forwards ? 0 : text.data.length\n };\n } else {\n throw err;\n }\n }\n }\n /**\n * Construct a `TextPosition` that refers to the `offset`th character within\n * `node`.\n *\n * @param {Node} node\n * @param {number} offset\n * @return {TextPosition}\n */\n\n }], [{\n key: "fromCharOffset",\n value: function fromCharOffset(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n return TextPosition.fromPoint(node, offset);\n\n case Node.ELEMENT_NODE:\n return new TextPosition(\n /** @type {Element} */\n node, offset);\n\n default:\n throw new Error(\'Node is not an element or text node\');\n }\n }\n /**\n * Construct a `TextPosition` representing the range start or end point (node, offset).\n *\n * @param {Node} node - Text or Element node\n * @param {number} offset - Offset within the node.\n * @return {TextPosition}\n */\n\n }, {\n key: "fromPoint",\n value: function fromPoint(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n {\n if (offset < 0 || offset >\n /** @type {Text} */\n node.data.length) {\n throw new Error(\'Text node offset is out of range\');\n }\n\n if (!node.parentElement) {\n throw new Error(\'Text node has no parent\');\n } // Get the offset from the start of the parent element.\n\n\n var textOffset = previousSiblingsTextLength(node) + offset;\n return new TextPosition(node.parentElement, textOffset);\n }\n\n case Node.ELEMENT_NODE:\n {\n if (offset < 0 || offset > node.childNodes.length) {\n throw new Error(\'Child node offset is out of range\');\n } // Get the text length before the `offset`th child of element.\n\n\n var _textOffset = 0;\n\n for (var i = 0; i < offset; i++) {\n _textOffset += nodeTextLength(node.childNodes[i]);\n }\n\n return new TextPosition(\n /** @type {Element} */\n node, _textOffset);\n }\n\n default:\n throw new Error(\'Point is not in an element or text node\');\n }\n }\n }]);\n\n return TextPosition;\n}();\n/**\n * Represents a region of a document as a (start, end) pair of `TextPosition` points.\n *\n * Representing a range in this way allows for changes in the DOM content of the\n * range which don\'t affect its text content, without affecting the text content\n * of the range itself.\n */\n\nvar text_range_TextRange = /*#__PURE__*/function () {\n /**\n * Construct an immutable `TextRange` from a `start` and `end` point.\n *\n * @param {TextPosition} start\n * @param {TextPosition} end\n */\n function TextRange(start, end) {\n _classCallCheck(this, TextRange);\n\n this.start = start;\n this.end = end;\n }\n /**\n * Return a copy of this range with start and end positions relative to a\n * given ancestor. See `TextPosition.relativeTo`.\n *\n * @param {Element} element\n */\n\n\n _createClass(TextRange, [{\n key: "relativeTo",\n value: function relativeTo(element) {\n return new TextRange(this.start.relativeTo(element), this.end.relativeTo(element));\n }\n /**\n * Resolve the `TextRange` to a DOM range.\n *\n * The resulting DOM Range will always start and end in a `Text` node.\n * Hence `TextRange.fromRange(range).toRange()` can be used to "shrink" a\n * range to the text it contains.\n *\n * May throw if the `start` or `end` positions cannot be resolved to a range.\n *\n * @return {Range}\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var start;\n var end;\n\n if (this.start.element === this.end.element && this.start.offset <= this.end.offset) {\n // Fast path for start and end points in same element.\n var _resolveOffsets = resolveOffsets(this.start.element, this.start.offset, this.end.offset);\n\n var _resolveOffsets2 = _slicedToArray(_resolveOffsets, 2);\n\n start = _resolveOffsets2[0];\n end = _resolveOffsets2[1];\n } else {\n start = this.start.resolve({\n direction: RESOLVE_FORWARDS\n });\n end = this.end.resolve({\n direction: RESOLVE_BACKWARDS\n });\n }\n\n var range = new Range();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range;\n }\n /**\n * Convert an existing DOM `Range` to a `TextRange`\n *\n * @param {Range} range\n * @return {TextRange}\n */\n\n }], [{\n key: "fromRange",\n value: function fromRange(range) {\n var start = text_range_TextPosition.fromPoint(range.startContainer, range.startOffset);\n var end = text_range_TextPosition.fromPoint(range.endContainer, range.endOffset);\n return new TextRange(start, end);\n }\n /**\n * Return a `TextRange` from the `start`th to `end`th characters in `root`.\n *\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n\n }, {\n key: "fromOffsets",\n value: function fromOffsets(root, start, end) {\n return new TextRange(new text_range_TextPosition(root, start), new text_range_TextPosition(root, end));\n }\n }]);\n\n return TextRange;\n}();\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/types.js\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction types_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction types_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction types_createClass(Constructor, protoProps, staticProps) { if (protoProps) types_defineProperties(Constructor.prototype, protoProps); if (staticProps) types_defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This module exports a set of classes for converting between DOM `Range`\n * objects and different types of selectors. It is mostly a thin wrapper around a\n * set of anchoring libraries. It serves two main purposes:\n *\n * 1. Providing a consistent interface across different types of anchors.\n * 2. Insulating the rest of the code from API changes in the underlying anchoring\n * libraries.\n */\n\n\n\n/**\n * @typedef {import(\'../../types/api\').RangeSelector} RangeSelector\n * @typedef {import(\'../../types/api\').TextPositionSelector} TextPositionSelector\n * @typedef {import(\'../../types/api\').TextQuoteSelector} TextQuoteSelector\n */\n\n/**\n * Converts between `RangeSelector` selectors and `Range` objects.\n */\n\nvar RangeAnchor = /*#__PURE__*/(/* unused pure expression or super */ null && (function () {\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n function RangeAnchor(root, range) {\n types_classCallCheck(this, RangeAnchor);\n\n this.root = root;\n this.range = range;\n }\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n\n\n types_createClass(RangeAnchor, [{\n key: "toRange",\n value: function toRange() {\n return this.range;\n }\n /**\n * @return {RangeSelector}\n */\n\n }, {\n key: "toSelector",\n value: function toSelector() {\n // "Shrink" the range so that it tightly wraps its text. This ensures more\n // predictable output for a given text selection.\n var normalizedRange = TextRange.fromRange(this.range).toRange();\n var textRange = TextRange.fromRange(normalizedRange);\n var startContainer = xpathFromNode(textRange.start.element, this.root);\n var endContainer = xpathFromNode(textRange.end.element, this.root);\n return {\n type: \'RangeSelector\',\n startContainer: startContainer,\n startOffset: textRange.start.offset,\n endContainer: endContainer,\n endOffset: textRange.end.offset\n };\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n return new RangeAnchor(root, range);\n }\n /**\n * Create an anchor from a serialized `RangeSelector` selector.\n *\n * @param {Element} root - A root element from which to anchor.\n * @param {RangeSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var startContainer = nodeFromXPath(selector.startContainer, root);\n\n if (!startContainer) {\n throw new Error(\'Failed to resolve startContainer XPath\');\n }\n\n var endContainer = nodeFromXPath(selector.endContainer, root);\n\n if (!endContainer) {\n throw new Error(\'Failed to resolve endContainer XPath\');\n }\n\n var startPos = TextPosition.fromCharOffset(startContainer, selector.startOffset);\n var endPos = TextPosition.fromCharOffset(endContainer, selector.endOffset);\n var range = new TextRange(startPos, endPos).toRange();\n return new RangeAnchor(root, range);\n }\n }]);\n\n return RangeAnchor;\n}()));\n/**\n * Converts between `TextPositionSelector` selectors and `Range` objects.\n */\n\nvar TextPositionAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n function TextPositionAnchor(root, start, end) {\n types_classCallCheck(this, TextPositionAnchor);\n\n this.root = root;\n this.start = start;\n this.end = end;\n }\n /**\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextPositionAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextPositionSelector}\n */\n function toSelector() {\n return {\n type: \'TextPositionSelector\',\n start: this.start,\n end: this.end\n };\n }\n }, {\n key: "toRange",\n value: function toRange() {\n return text_range_TextRange.fromOffsets(this.root, this.start, this.end).toRange();\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n return new TextPositionAnchor(root, textRange.start.offset, textRange.end.offset);\n }\n /**\n * @param {Element} root\n * @param {TextPositionSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n return new TextPositionAnchor(root, selector.start, selector.end);\n }\n }]);\n\n return TextPositionAnchor;\n}();\n/**\n * @typedef QuoteMatchOptions\n * @prop {number} [hint] - Expected position of match in text. See `matchQuote`.\n */\n\n/**\n * Converts between `TextQuoteSelector` selectors and `Range` objects.\n */\n\nvar TextQuoteAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root - A root element from which to anchor.\n * @param {string} exact\n * @param {Object} context\n * @param {string} [context.prefix]\n * @param {string} [context.suffix]\n */\n function TextQuoteAnchor(root, exact) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n types_classCallCheck(this, TextQuoteAnchor);\n\n this.root = root;\n this.exact = exact;\n this.context = context;\n }\n /**\n * Create a `TextQuoteAnchor` from a range.\n *\n * Will throw if `range` does not contain any text nodes.\n *\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextQuoteAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextQuoteSelector}\n */\n function toSelector() {\n return {\n type: \'TextQuoteSelector\',\n exact: this.exact,\n prefix: this.context.prefix,\n suffix: this.context.suffix\n };\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return this.toPositionAnchor(options).toRange();\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toPositionAnchor",\n value: function toPositionAnchor() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var text =\n /** @type {string} */\n this.root.textContent;\n var match = matchQuote(text, this.exact, _objectSpread(_objectSpread({}, this.context), {}, {\n hint: options.hint\n }));\n\n if (!match) {\n throw new Error(\'Quote not found\');\n }\n\n return new TextPositionAnchor(this.root, match.start, match.end);\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var text =\n /** @type {string} */\n root.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n var start = textRange.start.offset;\n var end = textRange.end.offset; // Number of characters around the quote to capture as context. We currently\n // always use a fixed amount, but it would be better if this code was aware\n // of logical boundaries in the document (paragraph, article etc.) to avoid\n // capturing text unrelated to the quote.\n //\n // In regular prose the ideal content would often be the surrounding sentence.\n // This is a natural unit of meaning which enables displaying quotes in\n // context even when the document is not available. We could use `Intl.Segmenter`\n // for this when available.\n\n var contextLen = 32;\n return new TextQuoteAnchor(root, text.slice(start, end), {\n prefix: text.slice(Math.max(0, start - contextLen), start),\n suffix: text.slice(end, Math.min(text.length, end + contextLen))\n });\n }\n /**\n * @param {Element} root\n * @param {TextQuoteSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var prefix = selector.prefix,\n suffix = selector.suffix;\n return new TextQuoteAnchor(root, selector.exact, {\n prefix: prefix,\n suffix: suffix\n });\n }\n }]);\n\n return TextQuoteAnchor;\n}();\n;// CONCATENATED MODULE: ./src/utils.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = utils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction utils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return utils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return utils_arrayLikeToArray(o, minLen); }\n\nfunction utils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n // Catch JS errors to log them in the app.\n\nwindow.addEventListener("error", function (event) {\n Android.logError(event.message, event.filename, event.lineno);\n}, false);\nwindow.addEventListener("load", function () {\n var observer = new ResizeObserver(function () {\n onViewportWidthChanged();\n snapCurrentOffset();\n });\n observer.observe(document.body);\n}, false);\n/**\n * Having an odd number of columns when displaying two columns per screen causes snapping and page\n * turning issues. To fix this, we insert a blank virtual column at the end of the resource.\n */\n\nfunction appendVirtualColumnIfNeeded() {\n var id = "readium-virtual-page";\n var virtualCol = document.getElementById(id);\n\n if (isScrollModeEnabled() || getColumnCountPerScreen() != 2) {\n if (virtualCol) {\n virtualCol.remove();\n }\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var colCount = documentWidth / pageWidth;\n var hasOddColCount = Math.round(colCount * 2) / 2 % 1 > 0.1;\n\n if (hasOddColCount) {\n if (virtualCol) {\n virtualCol.remove();\n } else {\n virtualCol = document.createElement("div");\n virtualCol.setAttribute("id", id);\n virtualCol.style.breakBefore = "column";\n virtualCol.innerHTML = "​"; // zero-width space\n\n document.body.appendChild(virtualCol);\n }\n }\n }\n}\n\nvar pageWidth = 1;\n\nfunction onViewportWidthChanged() {\n // We can\'t rely on window.innerWidth for the pageWidth on Android, because if the\n // device pixel ratio is not an integer, we get rounding issues offsetting the pages.\n //\n // See https://github.com/readium/readium-css/issues/97\n // and https://github.com/readium/r2-navigator-kotlin/issues/146\n var width = Android.getViewportWidth();\n pageWidth = width / window.devicePixelRatio;\n setProperty("--RS__viewportWidth", "calc(" + width + "px / " + window.devicePixelRatio + ")");\n appendVirtualColumnIfNeeded();\n}\n\nfunction getColumnCountPerScreen() {\n return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n}\nfunction isScrollModeEnabled() {\n var style = document.documentElement.style;\n return style.getPropertyValue("--USER__view").trim() == "readium-scroll-on" || // FIXME: Will need to be removed in Readium 3.0, --USER__scroll was incorrect.\n style.getPropertyValue("--USER__scroll").trim() == "readium-scroll-on";\n}\nfunction isRTL() {\n return document.body.dir.toLowerCase() == "rtl";\n} // Scroll to the given TagId in document and snap.\n\nfunction scrollToId(id) {\n var element = document.getElementById(id);\n\n if (!element) {\n return false;\n }\n\n return scrollToRect(element.getBoundingClientRect());\n} // Position must be in the range [0 - 1], 0-100%.\n\nfunction scrollToPosition(position) {\n // Android.log("scrollToPosition " + position);\n if (position < 0 || position > 1) {\n throw "scrollToPosition() must be given a position from 0.0 to 1.0";\n }\n\n var offset;\n\n if (isScrollModeEnabled()) {\n offset = document.scrollingElement.scrollHeight * position;\n document.scrollingElement.scrollTop = offset; // window.scrollTo(0, offset);\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var factor = isRTL() ? -1 : 1;\n offset = documentWidth * position * factor;\n document.scrollingElement.scrollLeft = snapOffset(offset);\n }\n} // Scrolls to the first occurrence of the given text snippet.\n//\n// The expected text argument is a Locator Text object, as defined here:\n// https://readium.org/architecture/models/locators/\n\nfunction scrollToText(text) {\n var range = rangeFromLocator({\n text: text\n });\n\n if (!range) {\n return false;\n }\n\n scrollToRange(range);\n return true;\n}\n\nfunction scrollToRange(range) {\n return scrollToRect(range.getBoundingClientRect());\n}\n\nfunction scrollToRect(rect) {\n if (isScrollModeEnabled()) {\n document.scrollingElement.scrollTop = rect.top + window.scrollY - window.innerHeight / 2;\n } else {\n document.scrollingElement.scrollLeft = snapOffset(rect.left + window.scrollX);\n }\n\n return true;\n}\n\nfunction scrollToStart() {\n // Android.log("scrollToStart");\n if (!isScrollModeEnabled()) {\n document.scrollingElement.scrollLeft = 0;\n } else {\n document.scrollingElement.scrollTop = 0;\n window.scrollTo(0, 0);\n }\n}\nfunction scrollToEnd() {\n // Android.log("scrollToEnd");\n if (!isScrollModeEnabled()) {\n var factor = isRTL() ? -1 : 1;\n document.scrollingElement.scrollLeft = snapOffset(document.scrollingElement.scrollWidth * factor);\n } else {\n document.scrollingElement.scrollTop = document.body.scrollHeight;\n window.scrollTo(0, document.body.scrollHeight);\n }\n} // Returns false if the page is already at the left-most scroll offset.\n\nfunction scrollLeft() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX - pageWidth;\n var minOffset = isRTL() ? -(documentWidth - pageWidth) : 0;\n return scrollToOffset(Math.max(offset, minOffset));\n} // Returns false if the page is already at the right-most scroll offset.\n\nfunction scrollRight() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX + pageWidth;\n var maxOffset = isRTL() ? 0 : documentWidth - pageWidth;\n return scrollToOffset(Math.min(offset, maxOffset));\n} // Scrolls to the given left offset.\n// Returns false if the page scroll position is already close enough to the given offset.\n\nfunction scrollToOffset(offset) {\n // Android.log("scrollToOffset " + offset);\n if (isScrollModeEnabled()) {\n throw "Called scrollToOffset() with scroll mode enabled. This can only be used in paginated mode.";\n }\n\n var currentOffset = window.scrollX;\n document.scrollingElement.scrollLeft = snapOffset(offset); // In some case the scrollX cannot reach the position respecting to innerWidth\n\n var diff = Math.abs(currentOffset - offset) / pageWidth;\n return diff > 0.01;\n} // Snap the offset to the screen width (page width).\n\n\nfunction snapOffset(offset) {\n var value = offset + (isRTL() ? -1 : 1);\n return value - value % pageWidth;\n} // Snaps the current offset to the page width.\n\n\nfunction snapCurrentOffset() {\n // Android.log("snapCurrentOffset");\n if (isScrollModeEnabled()) {\n return;\n }\n\n var currentOffset = window.scrollX; // Adds half a page to make sure we don\'t snap to the previous page.\n\n var factor = isRTL() ? -1 : 1;\n var delta = factor * (pageWidth / 2);\n document.scrollingElement.scrollLeft = snapOffset(currentOffset + delta);\n}\nfunction rangeFromLocator(locator) {\n try {\n var locations = locator.locations;\n var text = locator.text;\n\n if (text && text.highlight) {\n var root;\n\n if (locations && locations.cssSelector) {\n root = document.querySelector(locations.cssSelector);\n }\n\n if (!root) {\n root = document.body;\n }\n\n var anchor = new TextQuoteAnchor(root, text.highlight, {\n prefix: text.before,\n suffix: text.after\n });\n return anchor.toRange();\n }\n\n if (locations) {\n var element = null;\n\n if (!element && locations.cssSelector) {\n element = document.querySelector(locations.cssSelector);\n }\n\n if (!element && locations.fragments) {\n var _iterator = _createForOfIteratorHelper(locations.fragments),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var htmlId = _step.value;\n element = document.getElementById(htmlId);\n\n if (element) {\n break;\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n if (element) {\n var range = document.createRange();\n range.setStartBefore(element);\n range.setEndAfter(element);\n return range;\n }\n }\n } catch (e) {\n logError(e);\n }\n\n return null;\n} /// User Settings.\n\nfunction setCSSProperties(properties) {\n for (var name in properties) {\n setProperty(name, properties[name]);\n }\n} // For setting user setting.\n\nfunction setProperty(key, value) {\n if (value === null || value === "") {\n removeProperty(key);\n } else {\n var root = document.documentElement; // The `!important` annotation is added with `setProperty()` because if it\'s part of the\n // `value`, it will be ignored by the Web View.\n\n root.style.setProperty(key, value, "important");\n }\n} // For removing user setting.\n\nfunction removeProperty(key) {\n var root = document.documentElement;\n root.style.removeProperty(key);\n} /// Toolkit\n\nfunction log() {\n var message = Array.prototype.slice.call(arguments).join(" ");\n Android.log(message);\n}\nfunction logError(message) {\n Android.logError(message, "", 0);\n}\n;// CONCATENATED MODULE: ./src/rect.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction rect_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = rect_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction rect_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return rect_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return rect_arrayLikeToArray(o, minLen); }\n\nfunction rect_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nvar debug = false;\n/**\n * Converts a DOMRect into a JSON object understandable by the native side.\n */\n\nfunction toNativeRect(rect) {\n var pixelRatio = window.devicePixelRatio;\n var width = rect.width * pixelRatio;\n var height = rect.height * pixelRatio;\n var left = rect.left * pixelRatio;\n var top = rect.top * pixelRatio;\n var right = left + width;\n var bottom = top + height;\n return {\n width: width,\n height: height,\n left: left,\n top: top,\n right: right,\n bottom: bottom\n };\n}\nfunction getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var clientRects = range.getClientRects();\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator = rect_createForOfIteratorHelper(clientRects),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var rangeClientRect = _step.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n var mergedRects = mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = removeContainedRects(mergedRects, tolerance);\n var newRects = replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n rect_log("CLIENT RECT: remove small");\n newRects.splice(j, 1);\n } else {\n rect_log("CLIENT RECT: remove small, but keep otherwise empty!");\n break;\n }\n }\n }\n\n rect_log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n return newRects;\n}\n\nfunction mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("mergeTouchingRects rect1 === rect2 ??!");\n return "continue";\n }\n\n var rectsLineUpVertically = almostEqual(rect1.top, rect2.top, tolerance) && almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = almostEqual(rect1.left, rect2.left, tolerance) && almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n rect_log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret = _loop(j);\n\n if (_ret === "continue") continue;\n if (_typeof(_ret) === "object") return _ret.v;\n }\n }\n\n return rects;\n}\n\nfunction getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator2 = rect_createForOfIteratorHelper(rects),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var rect = _step2.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n rect_log("CLIENT RECT: remove tiny");\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator3 = rect_createForOfIteratorHelper(rects),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var possiblyContainingRect = _step3.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (rectContains(possiblyContainingRect, rect, tolerance)) {\n rect_log("CLIENT RECT: remove contained");\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction rectContains(rect1, rect2, tolerance) {\n return rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || almostEqual(rect.left, x, tolerance)) && (rect.right > x || almostEqual(rect.right, x, tolerance)) && (rect.top < y || almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("replaceOverlapingRects rect1 === rect2 ??!");\n continue;\n }\n\n if (rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret2 = function () {\n var toAdd = [];\n var toRemove = void 0;\n var subtractRects1 = rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n var subtractRects2 = rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n }\n }\n\n rect_log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: replaceOverlapingRects(newRects)\n };\n }();\n\n if (_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction rectSubtract(rect1, rect2) {\n var rectIntersected = rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n return {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n}\n\nfunction rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction rect_log() {\n if (debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/decorator.js\nfunction decorator_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = decorator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction decorator_slicedToArray(arr, i) { return decorator_arrayWithHoles(arr) || decorator_iterableToArrayLimit(arr, i) || decorator_unsupportedIterableToArray(arr, i) || decorator_nonIterableRest(); }\n\nfunction decorator_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction decorator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return decorator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return decorator_arrayLikeToArray(o, minLen); }\n\nfunction decorator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction decorator_iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction decorator_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nvar styles = new Map();\nvar groups = new Map();\nvar lastGroupId = 0;\n/**\n * Registers a list of additional supported Decoration Templates.\n *\n * Each template object is indexed by the style ID.\n */\n\nfunction registerTemplates(newStyles) {\n var stylesheet = "";\n\n for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = decorator_slicedToArray(_Object$entries[_i], 2),\n id = _Object$entries$_i[0],\n style = _Object$entries$_i[1];\n\n styles.set(id, style);\n\n if (style.stylesheet) {\n stylesheet += style.stylesheet + "\\n";\n }\n }\n\n if (stylesheet) {\n var styleElement = document.createElement("style");\n styleElement.innerHTML = stylesheet;\n document.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n}\n/**\n * Returns an instance of DecorationGroup for the given group name.\n */\n\nfunction getDecorations(groupName) {\n var group = groups.get(groupName);\n\n if (!group) {\n var id = "r2-decoration-" + lastGroupId++;\n group = DecorationGroup(id, groupName);\n groups.set(groupName, group);\n }\n\n return group;\n}\n/**\n * Handles click events on a Decoration.\n * Returns whether a decoration matched this event.\n */\n\nfunction handleDecorationClickEvent(event, clickEvent) {\n if (groups.size === 0) {\n return false;\n }\n\n function findTarget() {\n var _iterator = decorator_createForOfIteratorHelper(groups),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = decorator_slicedToArray(_step.value, 2),\n group = _step$value[0],\n groupContent = _step$value[1];\n\n var _iterator2 = decorator_createForOfIteratorHelper(groupContent.items.reverse()),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var item = _step2.value;\n\n if (!item.clickableElements) {\n continue;\n }\n\n var _iterator3 = decorator_createForOfIteratorHelper(item.clickableElements),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var element = _step3.value;\n var rect = element.getBoundingClientRect().toJSON();\n\n if (rectContainsPoint(rect, event.clientX, event.clientY, 1)) {\n return {\n group: group,\n item: item,\n element: element,\n rect: rect\n };\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var target = findTarget();\n\n if (!target) {\n return false;\n }\n\n return Android.onDecorationActivated(JSON.stringify({\n id: target.item.decoration.id,\n group: target.group,\n rect: toNativeRect(target.item.range.getBoundingClientRect()),\n click: clickEvent\n }));\n}\n/**\n * Creates a DecorationGroup object from a unique HTML ID and its name.\n */\n\nfunction DecorationGroup(groupId, groupName) {\n var items = [];\n var lastItemId = 0;\n var container = null;\n /**\n * Adds a new decoration to the group.\n */\n\n function add(decoration) {\n var id = groupId + "-" + lastItemId++;\n var range = rangeFromLocator(decoration.locator);\n\n if (!range) {\n log("Can\'t locate DOM range for decoration", decoration);\n return;\n }\n\n var item = {\n id: id,\n decoration: decoration,\n range: range\n };\n items.push(item);\n layout(item);\n }\n /**\n * Removes the decoration with given ID from the group.\n */\n\n\n function remove(decorationId) {\n var index = items.findIndex(function (i) {\n return i.decoration.id === decorationId;\n });\n\n if (index === -1) {\n return;\n }\n\n var item = items[index];\n items.splice(index, 1);\n item.clickableElements = null;\n\n if (item.container) {\n item.container.remove();\n item.container = null;\n }\n }\n /**\n * Notifies that the given decoration was modified and needs to be updated.\n */\n\n\n function update(decoration) {\n remove(decoration.id);\n add(decoration);\n }\n /**\n * Removes all decorations from this group.\n */\n\n\n function clear() {\n clearContainer();\n items.length = 0;\n }\n /**\n * Recreates the decoration elements.\n *\n * To be called after reflowing the resource, for example.\n */\n\n\n function requestLayout() {\n clearContainer();\n items.forEach(function (item) {\n return layout(item);\n });\n }\n /**\n * Layouts a single Decoration item.\n */\n\n\n function layout(item) {\n var groupContainer = requireContainer();\n var style = styles.get(item.decoration.style);\n\n if (!style) {\n logError("Unknown decoration style: ".concat(item.decoration.style));\n return;\n }\n\n var itemContainer = document.createElement("div");\n itemContainer.setAttribute("id", item.id);\n itemContainer.setAttribute("data-style", item.decoration.style);\n itemContainer.style.setProperty("pointer-events", "none");\n var viewportWidth = window.innerWidth;\n var columnCount = parseInt(getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n var pageWidth = viewportWidth / (columnCount || 1);\n var scrollingElement = document.scrollingElement;\n var xOffset = scrollingElement.scrollLeft;\n var yOffset = scrollingElement.scrollTop;\n\n function positionElement(element, rect, boundingRect) {\n element.style.position = "absolute";\n\n if (style.width === "wrap") {\n element.style.width = "".concat(rect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(rect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "viewport") {\n element.style.width = "".concat(viewportWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n var left = Math.floor(rect.left / viewportWidth) * viewportWidth;\n element.style.left = "".concat(left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "bounds") {\n element.style.width = "".concat(boundingRect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(boundingRect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "page") {\n element.style.width = "".concat(pageWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n\n var _left = Math.floor(rect.left / pageWidth) * pageWidth;\n\n element.style.left = "".concat(_left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n }\n }\n\n var boundingRect = item.range.getBoundingClientRect();\n var elementTemplate;\n\n try {\n var template = document.createElement("template");\n template.innerHTML = item.decoration.element.trim();\n elementTemplate = template.content.firstElementChild;\n } catch (error) {\n logError("Invalid decoration element \\"".concat(item.decoration.element, "\\": ").concat(error.message));\n return;\n }\n\n if (style.layout === "boxes") {\n var doNotMergeHorizontallyAlignedRects = true;\n var clientRects = getClientRectsNoOverlap(item.range, doNotMergeHorizontallyAlignedRects);\n clientRects = clientRects.sort(function (r1, r2) {\n if (r1.top < r2.top) {\n return -1;\n } else if (r1.top > r2.top) {\n return 1;\n } else {\n return 0;\n }\n });\n\n var _iterator4 = decorator_createForOfIteratorHelper(clientRects),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var clientRect = _step4.value;\n var line = elementTemplate.cloneNode(true);\n line.style.setProperty("pointer-events", "none");\n positionElement(line, clientRect, boundingRect);\n itemContainer.append(line);\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n } else if (style.layout === "bounds") {\n var bounds = elementTemplate.cloneNode(true);\n bounds.style.setProperty("pointer-events", "none");\n positionElement(bounds, boundingRect, boundingRect);\n itemContainer.append(bounds);\n }\n\n groupContainer.append(itemContainer);\n item.container = itemContainer;\n item.clickableElements = Array.from(itemContainer.querySelectorAll("[data-activable=\'1\']"));\n\n if (item.clickableElements.length === 0) {\n item.clickableElements = Array.from(itemContainer.children);\n }\n }\n /**\n * Returns the group container element, after making sure it exists.\n */\n\n\n function requireContainer() {\n if (!container) {\n container = document.createElement("div");\n container.setAttribute("id", groupId);\n container.setAttribute("data-group", groupName);\n container.style.setProperty("pointer-events", "none");\n document.body.append(container);\n }\n\n return container;\n }\n /**\n * Removes the group container.\n */\n\n\n function clearContainer() {\n if (container) {\n container.remove();\n container = null;\n }\n }\n\n return {\n add: add,\n remove: remove,\n update: update,\n clear: clear,\n items: items,\n requestLayout: requestLayout\n };\n}\nwindow.addEventListener("load", function () {\n // Will relayout all the decorations when the document body is resized.\n var body = document.body;\n var lastSize = {\n width: 0,\n height: 0\n };\n var observer = new ResizeObserver(function () {\n if (lastSize.width === body.clientWidth && lastSize.height === body.clientHeight) {\n return;\n }\n\n lastSize = {\n width: body.clientWidth,\n height: body.clientHeight\n };\n groups.forEach(function (group) {\n group.requestLayout();\n });\n });\n observer.observe(body);\n}, false);\n// EXTERNAL MODULE: ./node_modules/css-selector-generator/build/index.js\nvar build = __webpack_require__(4766);\n;// CONCATENATED MODULE: ./src/dom.js\n//\n// Copyright 2022 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n // See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling\n\nfunction nearestInteractiveElement(element) {\n if (element == null) {\n return null;\n }\n\n var interactiveTags = ["a", "audio", "button", "canvas", "details", "input", "label", "option", "select", "submit", "textarea", "video"];\n\n if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) {\n return element.outerHTML;\n } // Checks whether the element is editable by the user.\n\n\n if (element.hasAttribute("contenteditable") && element.getAttribute("contenteditable").toLowerCase() != "false") {\n return element.outerHTML;\n } // Checks parents recursively because the touch might be for example on an inside a .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n}\n;// CONCATENATED MODULE: ./src/keyboard.js\n//\n// Copyright 2023 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nwindow.addEventListener("keydown", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "down");\n});\nwindow.addEventListener("keyup", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "up");\n});\n\nfunction shouldIgnoreEvent(event) {\n return event.defaultPrevented || nearestInteractiveElement(document.activeElement) != null;\n} // We prevent the default behavior for keyboard events, otherwise the web view\n// might scroll.\n\n\nfunction preventDefault(event) {\n event.stopPropagation();\n event.preventDefault();\n}\n\nfunction sendPressKeyMessage(event, type) {\n if (event.repeat) return;\n var keyEvent = {\n type: type,\n code: event.code,\n characters: String.fromCharCode(event.keyCode),\n alt: event.altKey,\n control: event.ctrlKey,\n shift: event.shiftKey,\n meta: event.metaKey\n };\n Android.onKey(JSON.stringify(keyEvent));\n}\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n};\n;// CONCATENATED MODULE: ./src/index-fixed.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for fixed layouts resources.\n\nwindow.readium.isFixedLayout = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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RTtBQVdmeUQsRUFBQUEsY0FBYyxFQUFFQSxjQVhEO0FBYWY7QUFDQXdOLEVBQUFBLG1CQUFtQixFQUFFQSxtQkFkTjtBQWdCZjtBQUNBa0MsRUFBQUEsMkJBQTJCLEVBQUVoTCxpQkFqQmQ7QUFrQmZRLEVBQUFBLGNBQWMsRUFBRUEsY0FsQkQ7QUFvQmY7QUFDQXVFLEVBQUFBLHVCQUF1QixFQUFFQSx1QkFBdUJBO0FBckJqQyxDQUFqQixDOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBdlAsTUFBTSxDQUFDOFAsT0FBUCxDQUFlQyxhQUFmLEdBQStCLElBQS9CIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvbWF0Y2gtcXVvdGUuanM/ZGQ2YSIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90ZXh0LXJhbmdlLmpzP2ZkZWUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdHlwZXMuanM/NDAwNCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL3V0aWxzLmpzPzAyNWUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9yZWN0LmpzPzRkNWEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kZWNvcmF0b3IuanM/MWIwNCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2RvbS5qcz9jYmYwIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZ2VzdHVyZXMuanM/MTRjMiIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2tleWJvYXJkLmpzPzE4ZTMiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9zZWxlY3Rpb24uanM/NTlhYyIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LmpzP2I2MzUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9pbmRleC1maXhlZC5qcz9kOTlmIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhcHByb3hTZWFyY2ggZnJvbSAnYXBwcm94LXN0cmluZy1tYXRjaCc7XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnYXBwcm94LXN0cmluZy1tYXRjaCcpLk1hdGNofSBTdHJpbmdNYXRjaFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgTWF0Y2hcbiAqIEBwcm9wIHtudW1iZXJ9IHN0YXJ0IC0gU3RhcnQgb2Zmc2V0IG9mIG1hdGNoIGluIHRleHRcbiAqIEBwcm9wIHtudW1iZXJ9IGVuZCAtIEVuZCBvZmZzZXQgb2YgbWF0Y2ggaW4gdGV4dFxuICogQHByb3Age251bWJlcn0gc2NvcmUgLVxuICogICBTY29yZSBmb3IgdGhlIG1hdGNoIGJldHdlZW4gMCBhbmQgMS4wLCB3aGVyZSAxLjAgaW5kaWNhdGVzIGEgcGVyZmVjdCBtYXRjaFxuICogICBmb3IgdGhlIHF1b3RlIGFuZCBjb250ZXh0LlxuICovXG5cbi8qKlxuICogRmluZCB0aGUgYmVzdCBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgc3RyYCBpbiBgdGV4dGAgYWxsb3dpbmcgdXAgdG8gYG1heEVycm9yc2AgZXJyb3JzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4RXJyb3JzXG4gKiBAcmV0dXJuIHtTdHJpbmdNYXRjaFtdfVxuICovXG5mdW5jdGlvbiBzZWFyY2godGV4dCwgc3RyLCBtYXhFcnJvcnMpIHtcbiAgLy8gRG8gYSBmYXN0IHNlYXJjaCBmb3IgZXhhY3QgbWF0Y2hlcy4gVGhlIGBhcHByb3gtc3RyaW5nLW1hdGNoYCBsaWJyYXJ5XG4gIC8vIGRvZXNuJ3QgY3VycmVudGx5IGluY29ycG9yYXRlIHRoaXMgb3B0aW1pemF0aW9uIGl0c2VsZi5cbiAgbGV0IG1hdGNoUG9zID0gMDtcbiAgbGV0IGV4YWN0TWF0Y2hlcyA9IFtdO1xuICB3aGlsZSAobWF0Y2hQb3MgIT09IC0xKSB7XG4gICAgbWF0Y2hQb3MgPSB0ZXh0LmluZGV4T2Yoc3RyLCBtYXRjaFBvcyk7XG4gICAgaWYgKG1hdGNoUG9zICE9PSAtMSkge1xuICAgICAgZXhhY3RNYXRjaGVzLnB1c2goe1xuICAgICAgICBzdGFydDogbWF0Y2hQb3MsXG4gICAgICAgIGVuZDogbWF0Y2hQb3MgKyBzdHIubGVuZ3RoLFxuICAgICAgICBlcnJvcnM6IDAsXG4gICAgICB9KTtcbiAgICAgIG1hdGNoUG9zICs9IDE7XG4gICAgfVxuICB9XG4gIGlmIChleGFjdE1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBleGFjdE1hdGNoZXM7XG4gIH1cblxuICAvLyBJZiB0aGVyZSBhcmUgbm8gZXhhY3QgbWF0Y2hlcywgZG8gYSBtb3JlIGV4cGVuc2l2ZSBzZWFyY2ggZm9yIG1hdGNoZXNcbiAgLy8gd2l0aCBlcnJvcnMuXG4gIHJldHVybiBhcHByb3hTZWFyY2godGV4dCwgc3RyLCBtYXhFcnJvcnMpO1xufVxuXG4vKipcbiAqIENvbXB1dGUgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEuMCBmb3IgdGhlIHNpbWlsYXJpdHkgYmV0d2VlbiBgdGV4dGAgYW5kIGBzdHJgLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKi9cbmZ1bmN0aW9uIHRleHRNYXRjaFNjb3JlKHRleHQsIHN0cikge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAtIGBzY29yZU1hdGNoYCB3aWxsIG5ldmVyIHBhc3MgYW4gZW1wdHkgc3RyaW5nICovXG4gIGlmIChzdHIubGVuZ3RoID09PSAwIHx8IHRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIDAuMDtcbiAgfVxuICBjb25zdCBtYXRjaGVzID0gc2VhcmNoKHRleHQsIHN0ciwgc3RyLmxlbmd0aCk7XG5cbiAgLy8gcHJldHRpZXItaWdub3JlXG4gIHJldHVybiAxIC0gKG1hdGNoZXNbMF0uZXJyb3JzIC8gc3RyLmxlbmd0aCk7XG59XG5cbi8qKlxuICogRmluZCB0aGUgYmVzdCBhcHByb3hpbWF0ZSBtYXRjaCBmb3IgYHF1b3RlYCBpbiBgdGV4dGAuXG4gKlxuICogUmV0dXJucyBgbnVsbGAgaWYgbm8gbWF0Y2ggZXhjZWVkaW5nIHRoZSBtaW5pbXVtIHF1YWxpdHkgdGhyZXNob2xkIHdhcyBmb3VuZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIERvY3VtZW50IHRleHQgdG8gc2VhcmNoXG4gKiBAcGFyYW0ge3N0cmluZ30gcXVvdGUgLSBTdHJpbmcgdG8gZmluZCB3aXRoaW4gYHRleHRgXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCAtXG4gKiAgIENvbnRleHQgaW4gd2hpY2ggdGhlIHF1b3RlIG9yaWdpbmFsbHkgYXBwZWFyZWQuIFRoaXMgaXMgdXNlZCB0byBjaG9vc2UgdGhlXG4gKiAgIGJlc3QgbWF0Y2guXG4gKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5wcmVmaXhdIC0gRXhwZWN0ZWQgdGV4dCBiZWZvcmUgdGhlIHF1b3RlXG4gKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5zdWZmaXhdIC0gRXhwZWN0ZWQgdGV4dCBhZnRlciB0aGUgcXVvdGVcbiAqICAgQHBhcmFtIHtudW1iZXJ9IFtjb250ZXh0LmhpbnRdIC0gRXhwZWN0ZWQgb2Zmc2V0IG9mIG1hdGNoIHdpdGhpbiB0ZXh0XG4gKiBAcmV0dXJuIHtNYXRjaHxudWxsfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hRdW90ZSh0ZXh0LCBxdW90ZSwgY29udGV4dCA9IHt9KSB7XG4gIGlmIChxdW90ZS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIENob29zZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIHRvIGFsbG93IGZvciB0aGUgaW5pdGlhbCBzZWFyY2guXG4gIC8vIFRoaXMgY2hvaWNlIGludm9sdmVzIGEgdHJhZGVvZmYgYmV0d2VlbjpcbiAgLy9cbiAgLy8gIC0gUmVjYWxsIChwcm9wb3J0aW9uIG9mIFwiZ29vZFwiIG1hdGNoZXMgZm91bmQpXG4gIC8vICAtIFByZWNpc2lvbiAocHJvcG9ydGlvbiBvZiBtYXRjaGVzIGZvdW5kIHdoaWNoIGFyZSBcImdvb2RcIilcbiAgLy8gIC0gQ29zdCBvZiB0aGUgaW5pdGlhbCBzZWFyY2ggYW5kIG9mIHByb2Nlc3NpbmcgdGhlIGNhbmRpZGF0ZSBtYXRjaGVzIFsxXVxuICAvL1xuICAvLyBbMV0gU3BlY2lmaWNhbGx5LCB0aGUgZXhwZWN0ZWQtdGltZSBjb21wbGV4aXR5IG9mIHRoZSBpbml0aWFsIHNlYXJjaCBpc1xuICAvLyAgICAgYE8oKG1heEVycm9ycyAvIDMyKSAqIHRleHQubGVuZ3RoKWAuIFNlZSBgYXBwcm94LXN0cmluZy1tYXRjaGAgZG9jcy5cbiAgY29uc3QgbWF4RXJyb3JzID0gTWF0aC5taW4oMjU2LCBxdW90ZS5sZW5ndGggLyAyKTtcblxuICAvLyBGaW5kIGNsb3Nlc3QgbWF0Y2hlcyBmb3IgYHF1b3RlYCBpbiBgdGV4dGAgYmFzZWQgb24gZWRpdCBkaXN0YW5jZS5cbiAgY29uc3QgbWF0Y2hlcyA9IHNlYXJjaCh0ZXh0LCBxdW90ZSwgbWF4RXJyb3JzKTtcblxuICBpZiAobWF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGEgc2NvcmUgYmV0d2VlbiAwIGFuZCAxLjAgZm9yIGEgbWF0Y2ggY2FuZGlkYXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ01hdGNofSBtYXRjaFxuICAgKi9cbiAgY29uc3Qgc2NvcmVNYXRjaCA9IG1hdGNoID0+IHtcbiAgICBjb25zdCBxdW90ZVdlaWdodCA9IDUwOyAvLyBTaW1pbGFyaXR5IG9mIG1hdGNoZWQgdGV4dCB0byBxdW90ZS5cbiAgICBjb25zdCBwcmVmaXhXZWlnaHQgPSAyMDsgLy8gU2ltaWxhcml0eSBvZiB0ZXh0IGJlZm9yZSBtYXRjaGVkIHRleHQgdG8gYGNvbnRleHQucHJlZml4YC5cbiAgICBjb25zdCBzdWZmaXhXZWlnaHQgPSAyMDsgLy8gU2ltaWxhcml0eSBvZiB0ZXh0IGFmdGVyIG1hdGNoZWQgdGV4dCB0byBgY29udGV4dC5zdWZmaXhgLlxuICAgIGNvbnN0IHBvc1dlaWdodCA9IDI7IC8vIFByb3hpbWl0eSB0byBleHBlY3RlZCBsb2NhdGlvbi4gVXNlZCBhcyBhIHRpZS1icmVha2VyLlxuXG4gICAgY29uc3QgcXVvdGVTY29yZSA9IDEgLSBtYXRjaC5lcnJvcnMgLyBxdW90ZS5sZW5ndGg7XG5cbiAgICBjb25zdCBwcmVmaXhTY29yZSA9IGNvbnRleHQucHJlZml4XG4gICAgICA/IHRleHRNYXRjaFNjb3JlKFxuICAgICAgICAgIHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgbWF0Y2guc3RhcnQgLSBjb250ZXh0LnByZWZpeC5sZW5ndGgpLCBtYXRjaC5zdGFydCksXG4gICAgICAgICAgY29udGV4dC5wcmVmaXhcbiAgICAgICAgKVxuICAgICAgOiAxLjA7XG4gICAgY29uc3Qgc3VmZml4U2NvcmUgPSBjb250ZXh0LnN1ZmZpeFxuICAgICAgPyB0ZXh0TWF0Y2hTY29yZShcbiAgICAgICAgICB0ZXh0LnNsaWNlKG1hdGNoLmVuZCwgbWF0Y2guZW5kICsgY29udGV4dC5zdWZmaXgubGVuZ3RoKSxcbiAgICAgICAgICBjb250ZXh0LnN1ZmZpeFxuICAgICAgICApXG4gICAgICA6IDEuMDtcblxuICAgIGxldCBwb3NTY29yZSA9IDEuMDtcbiAgICBpZiAodHlwZW9mIGNvbnRleHQuaGludCA9PT0gJ251bWJlcicpIHtcbiAgICAgIGNvbnN0IG9mZnNldCA9IE1hdGguYWJzKG1hdGNoLnN0YXJ0IC0gY29udGV4dC5oaW50KTtcbiAgICAgIHBvc1Njb3JlID0gMS4wIC0gb2Zmc2V0IC8gdGV4dC5sZW5ndGg7XG4gICAgfVxuXG4gICAgY29uc3QgcmF3U2NvcmUgPVxuICAgICAgcXVvdGVXZWlnaHQgKiBxdW90ZVNjb3JlICtcbiAgICAgIHByZWZpeFdlaWdodCAqIHByZWZpeFNjb3JlICtcbiAgICAgIHN1ZmZpeFdlaWdodCAqIHN1ZmZpeFNjb3JlICtcbiAgICAgIHBvc1dlaWdodCAqIHBvc1Njb3JlO1xuICAgIGNvbnN0IG1heFNjb3JlID0gcXVvdGVXZWlnaHQgKyBwcmVmaXhXZWlnaHQgKyBzdWZmaXhXZWlnaHQgKyBwb3NXZWlnaHQ7XG4gICAgY29uc3Qgbm9ybWFsaXplZFNjb3JlID0gcmF3U2NvcmUgLyBtYXhTY29yZTtcblxuICAgIHJldHVybiBub3JtYWxpemVkU2NvcmU7XG4gIH07XG5cbiAgLy8gUmFuayBtYXRjaGVzIGJhc2VkIG9uIHNpbWlsYXJpdHkgb2YgYWN0dWFsIGFuZCBleHBlY3RlZCBzdXJyb3VuZGluZyB0ZXh0XG4gIC8vIGFuZCBhY3R1YWwvZXhwZWN0ZWQgb2Zmc2V0IGluIHRoZSBkb2N1bWVudCB0ZXh0LlxuICBjb25zdCBzY29yZWRNYXRjaGVzID0gbWF0Y2hlcy5tYXAobSA9PiAoe1xuICAgIHN0YXJ0OiBtLnN0YXJ0LFxuICAgIGVuZDogbS5lbmQsXG4gICAgc2NvcmU6IHNjb3JlTWF0Y2gobSksXG4gIH0pKTtcblxuICAvLyBDaG9vc2UgbWF0Y2ggd2l0aCBoaWdoZXN0IHNjb3JlLlxuICBzY29yZWRNYXRjaGVzLnNvcnQoKGEsIGIpID0+IGIuc2NvcmUgLSBhLnNjb3JlKTtcbiAgcmV0dXJuIHNjb3JlZE1hdGNoZXNbMF07XG59XG4iLCIvKipcbiAqIFJldHVybiB0aGUgY29tYmluZWQgbGVuZ3RoIG9mIHRleHQgbm9kZXMgY29udGFpbmVkIGluIGBub2RlYC5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqL1xuZnVuY3Rpb24gbm9kZVRleHRMZW5ndGgobm9kZSkge1xuICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOlxuICAgIGNhc2UgTm9kZS5URVhUX05PREU6XG4gICAgICAvLyBuYi4gYHRleHRDb250ZW50YCBleGNsdWRlcyB0ZXh0IGluIGNvbW1lbnRzIGFuZCBwcm9jZXNzaW5nIGluc3RydWN0aW9uc1xuICAgICAgLy8gd2hlbiBjYWxsZWQgb24gYSBwYXJlbnQgZWxlbWVudCwgc28gd2UgZG9uJ3QgbmVlZCB0byBzdWJ0cmFjdCB0aGF0IGhlcmUuXG5cbiAgICAgIHJldHVybiAvKiogQHR5cGUge3N0cmluZ30gKi8gKG5vZGUudGV4dENvbnRlbnQpLmxlbmd0aDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgdGV4dCBvZiBhbGwgcHJldmlvdXMgc2libGluZ3Mgb2YgYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICovXG5mdW5jdGlvbiBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChub2RlKSB7XG4gIGxldCBzaWJsaW5nID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gIGxldCBsZW5ndGggPSAwO1xuICB3aGlsZSAoc2libGluZykge1xuICAgIGxlbmd0aCArPSBub2RlVGV4dExlbmd0aChzaWJsaW5nKTtcbiAgICBzaWJsaW5nID0gc2libGluZy5wcmV2aW91c1NpYmxpbmc7XG4gIH1cbiAgcmV0dXJuIGxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIG9uZSBvciBtb3JlIGNoYXJhY3RlciBvZmZzZXRzIHdpdGhpbiBhbiBlbGVtZW50IHRvICh0ZXh0IG5vZGUsIHBvc2l0aW9uKVxuICogcGFpcnMuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge251bWJlcltdfSBvZmZzZXRzIC0gT2Zmc2V0cywgd2hpY2ggbXVzdCBiZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyXG4gKiBAcmV0dXJuIHt7IG5vZGU6IFRleHQsIG9mZnNldDogbnVtYmVyIH1bXX1cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZU9mZnNldHMoZWxlbWVudCwgLi4ub2Zmc2V0cykge1xuICBsZXQgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgY29uc3Qgbm9kZUl0ZXIgPSAvKiogQHR5cGUge0RvY3VtZW50fSAqLyAoXG4gICAgZWxlbWVudC5vd25lckRvY3VtZW50XG4gICkuY3JlYXRlTm9kZUl0ZXJhdG9yKGVsZW1lbnQsIE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gIGxldCBjdXJyZW50Tm9kZSA9IG5vZGVJdGVyLm5leHROb2RlKCk7XG4gIGxldCB0ZXh0Tm9kZTtcbiAgbGV0IGxlbmd0aCA9IDA7XG5cbiAgLy8gRmluZCB0aGUgdGV4dCBub2RlIGNvbnRhaW5pbmcgdGhlIGBuZXh0T2Zmc2V0YHRoIGNoYXJhY3RlciBmcm9tIHRoZSBzdGFydFxuICAvLyBvZiBgZWxlbWVudGAuXG4gIHdoaWxlIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgY3VycmVudE5vZGUpIHtcbiAgICB0ZXh0Tm9kZSA9IC8qKiBAdHlwZSB7VGV4dH0gKi8gKGN1cnJlbnROb2RlKTtcbiAgICBpZiAobGVuZ3RoICsgdGV4dE5vZGUuZGF0YS5sZW5ndGggPiBuZXh0T2Zmc2V0KSB7XG4gICAgICByZXN1bHRzLnB1c2goeyBub2RlOiB0ZXh0Tm9kZSwgb2Zmc2V0OiBuZXh0T2Zmc2V0IC0gbGVuZ3RoIH0pO1xuICAgICAgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudE5vZGUgPSBub2RlSXRlci5uZXh0Tm9kZSgpO1xuICAgICAgbGVuZ3RoICs9IHRleHROb2RlLmRhdGEubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJvdW5kYXJ5IGNhc2UuXG4gIHdoaWxlIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgdGV4dE5vZGUgJiYgbGVuZ3RoID09PSBuZXh0T2Zmc2V0KSB7XG4gICAgcmVzdWx0cy5wdXNoKHsgbm9kZTogdGV4dE5vZGUsIG9mZnNldDogdGV4dE5vZGUuZGF0YS5sZW5ndGggfSk7XG4gICAgbmV4dE9mZnNldCA9IG9mZnNldHMuc2hpZnQoKTtcbiAgfVxuXG4gIGlmIChuZXh0T2Zmc2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT2Zmc2V0IGV4Y2VlZHMgdGV4dCBsZW5ndGgnKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5leHBvcnQgbGV0IFJFU09MVkVfRk9SV0FSRFMgPSAxO1xuZXhwb3J0IGxldCBSRVNPTFZFX0JBQ0tXQVJEUyA9IDI7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBvZmZzZXQgd2l0aGluIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYW4gZWxlbWVudC5cbiAqXG4gKiBUaGlzIHBvc2l0aW9uIGNhbiBiZSByZXNvbHZlZCB0byBhIHNwZWNpZmljIGRlc2NlbmRhbnQgbm9kZSBpbiB0aGUgY3VycmVudFxuICogRE9NIHN1YnRyZWUgb2YgdGhlIGVsZW1lbnQgdXNpbmcgdGhlIGByZXNvbHZlYCBtZXRob2QuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UG9zaXRpb24ge1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgdGhhdCByZWZlcnMgdG8gdGhlIHRleHQgcG9zaXRpb24gYG9mZnNldGAgd2l0aGluXG4gICAqIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYGVsZW1lbnRgLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKi9cbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb2Zmc2V0KSB7XG4gICAgaWYgKG9mZnNldCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT2Zmc2V0IGlzIGludmFsaWQnKTtcbiAgICB9XG5cbiAgICAvKiogRWxlbWVudCB0aGF0IGBvZmZzZXRgIGlzIHJlbGF0aXZlIHRvLiAqL1xuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgICAvKiogQ2hhcmFjdGVyIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgZWxlbWVudCdzIGB0ZXh0Q29udGVudGAuICovXG4gICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGlzIHBvc2l0aW9uIHdpdGggb2Zmc2V0IHJlbGF0aXZlIHRvIGEgZ2l2ZW4gYW5jZXN0b3JcbiAgICogZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSBwYXJlbnQgLSBBbmNlc3RvciBvZiBgdGhpcy5lbGVtZW50YFxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb259XG4gICAqL1xuICByZWxhdGl2ZVRvKHBhcmVudCkge1xuICAgIGlmICghcGFyZW50LmNvbnRhaW5zKHRoaXMuZWxlbWVudCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyZW50IGlzIG5vdCBhbiBhbmNlc3RvciBvZiBjdXJyZW50IGVsZW1lbnQnKTtcbiAgICB9XG5cbiAgICBsZXQgZWwgPSB0aGlzLmVsZW1lbnQ7XG4gICAgbGV0IG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgIHdoaWxlIChlbCAhPT0gcGFyZW50KSB7XG4gICAgICBvZmZzZXQgKz0gcHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgoZWwpO1xuICAgICAgZWwgPSAvKiogQHR5cGUge0VsZW1lbnR9ICovIChlbC5wYXJlbnRFbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbihlbCwgb2Zmc2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBwb3NpdGlvbiB0byBhIHNwZWNpZmljIHRleHQgbm9kZSBhbmQgb2Zmc2V0IHdpdGhpbiB0aGF0IG5vZGUuXG4gICAqXG4gICAqIFRocm93cyBpZiBgdGhpcy5vZmZzZXRgIGV4Y2VlZHMgdGhlIGxlbmd0aCBvZiB0aGUgZWxlbWVudCdzIHRleHQuIEluIHRoZVxuICAgKiBjYXNlIHdoZXJlIHRoZSBlbGVtZW50IGhhcyBubyB0ZXh0IGFuZCBgdGhpcy5vZmZzZXRgIGlzIDAsIHRoZSBgZGlyZWN0aW9uYFxuICAgKiBvcHRpb24gZGV0ZXJtaW5lcyB3aGF0IGhhcHBlbnMuXG4gICAqXG4gICAqIE9mZnNldHMgYXQgdGhlIGJvdW5kYXJ5IGJldHdlZW4gdHdvIG5vZGVzIGFyZSByZXNvbHZlZCB0byB0aGUgc3RhcnQgb2YgdGhlXG4gICAqIG5vZGUgdGhhdCBiZWdpbnMgYXQgdGhlIGJvdW5kYXJ5LlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgQHBhcmFtIHtSRVNPTFZFX0ZPUldBUkRTfFJFU09MVkVfQkFDS1dBUkRTfSBbb3B0aW9ucy5kaXJlY3Rpb25dIC1cbiAgICogICAgIFNwZWNpZmllcyBpbiB3aGljaCBkaXJlY3Rpb24gdG8gc2VhcmNoIGZvciB0aGUgbmVhcmVzdCB0ZXh0IG5vZGUgaWZcbiAgICogICAgIGB0aGlzLm9mZnNldGAgaXMgYDBgIGFuZCBgdGhpcy5lbGVtZW50YCBoYXMgbm8gdGV4dC4gSWYgbm90IHNwZWNpZmllZFxuICAgKiAgICAgYW4gZXJyb3IgaXMgdGhyb3duLlxuICAgKiBAcmV0dXJuIHt7IG5vZGU6IFRleHQsIG9mZnNldDogbnVtYmVyIH19XG4gICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9XG4gICAqL1xuICByZXNvbHZlKG9wdGlvbnMgPSB7fSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZU9mZnNldHModGhpcy5lbGVtZW50LCB0aGlzLm9mZnNldClbMF07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAodGhpcy5vZmZzZXQgPT09IDAgJiYgb3B0aW9ucy5kaXJlY3Rpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB0dyA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIoXG4gICAgICAgICAgdGhpcy5lbGVtZW50LmdldFJvb3ROb2RlKCksXG4gICAgICAgICAgTm9kZUZpbHRlci5TSE9XX1RFWFRcbiAgICAgICAgKTtcbiAgICAgICAgdHcuY3VycmVudE5vZGUgPSB0aGlzLmVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGZvcndhcmRzID0gb3B0aW9ucy5kaXJlY3Rpb24gPT09IFJFU09MVkVfRk9SV0FSRFM7XG4gICAgICAgIGNvbnN0IHRleHQgPSAvKiogQHR5cGUge1RleHR8bnVsbH0gKi8gKFxuICAgICAgICAgIGZvcndhcmRzID8gdHcubmV4dE5vZGUoKSA6IHR3LnByZXZpb3VzTm9kZSgpXG4gICAgICAgICk7XG4gICAgICAgIGlmICghdGV4dCkge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBub2RlOiB0ZXh0LCBvZmZzZXQ6IGZvcndhcmRzID8gMCA6IHRleHQuZGF0YS5sZW5ndGggfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgdGhhdCByZWZlcnMgdG8gdGhlIGBvZmZzZXRgdGggY2hhcmFjdGVyIHdpdGhpblxuICAgKiBgbm9kZWAuXG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tQ2hhck9mZnNldChub2RlLCBvZmZzZXQpIHtcbiAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6XG4gICAgICAgIHJldHVybiBUZXh0UG9zaXRpb24uZnJvbVBvaW50KG5vZGUsIG9mZnNldCk7XG4gICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOlxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbigvKiogQHR5cGUge0VsZW1lbnR9ICovIChub2RlKSwgb2Zmc2V0KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm9kZSBpcyBub3QgYW4gZWxlbWVudCBvciB0ZXh0IG5vZGUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgYFRleHRQb3NpdGlvbmAgcmVwcmVzZW50aW5nIHRoZSByYW5nZSBzdGFydCBvciBlbmQgcG9pbnQgKG5vZGUsIG9mZnNldCkuXG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSAtIFRleHQgb3IgRWxlbWVudCBub2RlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgLSBPZmZzZXQgd2l0aGluIHRoZSBub2RlLlxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb259XG4gICAqL1xuICBzdGF0aWMgZnJvbVBvaW50KG5vZGUsIG9mZnNldCkge1xuICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERToge1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiAvKiogQHR5cGUge1RleHR9ICovIChub2RlKS5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGV4dCBub2RlIG9mZnNldCBpcyBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbm9kZS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IG5vZGUgaGFzIG5vIHBhcmVudCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHRoZSBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHBhcmVudCBlbGVtZW50LlxuICAgICAgICBjb25zdCB0ZXh0T2Zmc2V0ID0gcHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgobm9kZSkgKyBvZmZzZXQ7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb24obm9kZS5wYXJlbnRFbGVtZW50LCB0ZXh0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6IHtcbiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hpbGQgbm9kZSBvZmZzZXQgaXMgb3V0IG9mIHJhbmdlJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIHRleHQgbGVuZ3RoIGJlZm9yZSB0aGUgYG9mZnNldGB0aCBjaGlsZCBvZiBlbGVtZW50LlxuICAgICAgICBsZXQgdGV4dE9mZnNldCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2Zmc2V0OyBpKyspIHtcbiAgICAgICAgICB0ZXh0T2Zmc2V0ICs9IG5vZGVUZXh0TGVuZ3RoKG5vZGUuY2hpbGROb2Rlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbigvKiogQHR5cGUge0VsZW1lbnR9ICovIChub2RlKSwgdGV4dE9mZnNldCk7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvaW50IGlzIG5vdCBpbiBhbiBlbGVtZW50IG9yIHRleHQgbm9kZScpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSByZWdpb24gb2YgYSBkb2N1bWVudCBhcyBhIChzdGFydCwgZW5kKSBwYWlyIG9mIGBUZXh0UG9zaXRpb25gIHBvaW50cy5cbiAqXG4gKiBSZXByZXNlbnRpbmcgYSByYW5nZSBpbiB0aGlzIHdheSBhbGxvd3MgZm9yIGNoYW5nZXMgaW4gdGhlIERPTSBjb250ZW50IG9mIHRoZVxuICogcmFuZ2Ugd2hpY2ggZG9uJ3QgYWZmZWN0IGl0cyB0ZXh0IGNvbnRlbnQsIHdpdGhvdXQgYWZmZWN0aW5nIHRoZSB0ZXh0IGNvbnRlbnRcbiAqIG9mIHRoZSByYW5nZSBpdHNlbGYuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UmFuZ2Uge1xuICAvKipcbiAgICogQ29uc3RydWN0IGFuIGltbXV0YWJsZSBgVGV4dFJhbmdlYCBmcm9tIGEgYHN0YXJ0YCBhbmQgYGVuZGAgcG9pbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9ufSBzdGFydFxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvbn0gZW5kXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzdGFydCwgZW5kKSB7XG4gICAgdGhpcy5zdGFydCA9IHN0YXJ0O1xuICAgIHRoaXMuZW5kID0gZW5kO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGNvcHkgb2YgdGhpcyByYW5nZSB3aXRoIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIHJlbGF0aXZlIHRvIGFcbiAgICogZ2l2ZW4gYW5jZXN0b3IuIFNlZSBgVGV4dFBvc2l0aW9uLnJlbGF0aXZlVG9gLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgICovXG4gIHJlbGF0aXZlVG8oZWxlbWVudCkge1xuICAgIHJldHVybiBuZXcgVGV4dFJhbmdlKFxuICAgICAgdGhpcy5zdGFydC5yZWxhdGl2ZVRvKGVsZW1lbnQpLFxuICAgICAgdGhpcy5lbmQucmVsYXRpdmVUbyhlbGVtZW50KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGUgYFRleHRSYW5nZWAgdG8gYSBET00gcmFuZ2UuXG4gICAqXG4gICAqIFRoZSByZXN1bHRpbmcgRE9NIFJhbmdlIHdpbGwgYWx3YXlzIHN0YXJ0IGFuZCBlbmQgaW4gYSBgVGV4dGAgbm9kZS5cbiAgICogSGVuY2UgYFRleHRSYW5nZS5mcm9tUmFuZ2UocmFuZ2UpLnRvUmFuZ2UoKWAgY2FuIGJlIHVzZWQgdG8gXCJzaHJpbmtcIiBhXG4gICAqIHJhbmdlIHRvIHRoZSB0ZXh0IGl0IGNvbnRhaW5zLlxuICAgKlxuICAgKiBNYXkgdGhyb3cgaWYgdGhlIGBzdGFydGAgb3IgYGVuZGAgcG9zaXRpb25zIGNhbm5vdCBiZSByZXNvbHZlZCB0byBhIHJhbmdlLlxuICAgKlxuICAgKiBAcmV0dXJuIHtSYW5nZX1cbiAgICovXG4gIHRvUmFuZ2UoKSB7XG4gICAgbGV0IHN0YXJ0O1xuICAgIGxldCBlbmQ7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXJ0LmVsZW1lbnQgPT09IHRoaXMuZW5kLmVsZW1lbnQgJiZcbiAgICAgIHRoaXMuc3RhcnQub2Zmc2V0IDw9IHRoaXMuZW5kLm9mZnNldFxuICAgICkge1xuICAgICAgLy8gRmFzdCBwYXRoIGZvciBzdGFydCBhbmQgZW5kIHBvaW50cyBpbiBzYW1lIGVsZW1lbnQuXG4gICAgICBbc3RhcnQsIGVuZF0gPSByZXNvbHZlT2Zmc2V0cyhcbiAgICAgICAgdGhpcy5zdGFydC5lbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXJ0Lm9mZnNldCxcbiAgICAgICAgdGhpcy5lbmQub2Zmc2V0XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGFydCA9IHRoaXMuc3RhcnQucmVzb2x2ZSh7IGRpcmVjdGlvbjogUkVTT0xWRV9GT1JXQVJEUyB9KTtcbiAgICAgIGVuZCA9IHRoaXMuZW5kLnJlc29sdmUoeyBkaXJlY3Rpb246IFJFU09MVkVfQkFDS1dBUkRTIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnQubm9kZSwgc3RhcnQub2Zmc2V0KTtcbiAgICByYW5nZS5zZXRFbmQoZW5kLm5vZGUsIGVuZC5vZmZzZXQpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGV4aXN0aW5nIERPTSBgUmFuZ2VgIHRvIGEgYFRleHRSYW5nZWBcbiAgICpcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICogQHJldHVybiB7VGV4dFJhbmdlfVxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyYW5nZSkge1xuICAgIGNvbnN0IHN0YXJ0ID0gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXRcbiAgICApO1xuICAgIGNvbnN0IGVuZCA9IFRleHRQb3NpdGlvbi5mcm9tUG9pbnQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpO1xuICAgIHJldHVybiBuZXcgVGV4dFJhbmdlKHN0YXJ0LCBlbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGBUZXh0UmFuZ2VgIGZyb20gdGhlIGBzdGFydGB0aCB0byBgZW5kYHRoIGNoYXJhY3RlcnMgaW4gYHJvb3RgLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRcbiAgICovXG4gIHN0YXRpYyBmcm9tT2Zmc2V0cyhyb290LCBzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2UoXG4gICAgICBuZXcgVGV4dFBvc2l0aW9uKHJvb3QsIHN0YXJ0KSxcbiAgICAgIG5ldyBUZXh0UG9zaXRpb24ocm9vdCwgZW5kKVxuICAgICk7XG4gIH1cbn1cbiIsIi8qKlxuICogVGhpcyBtb2R1bGUgZXhwb3J0cyBhIHNldCBvZiBjbGFzc2VzIGZvciBjb252ZXJ0aW5nIGJldHdlZW4gRE9NIGBSYW5nZWBcbiAqIG9iamVjdHMgYW5kIGRpZmZlcmVudCB0eXBlcyBvZiBzZWxlY3RvcnMuIEl0IGlzIG1vc3RseSBhIHRoaW4gd3JhcHBlciBhcm91bmQgYVxuICogc2V0IG9mIGFuY2hvcmluZyBsaWJyYXJpZXMuIEl0IHNlcnZlcyB0d28gbWFpbiBwdXJwb3NlczpcbiAqXG4gKiAgMS4gUHJvdmlkaW5nIGEgY29uc2lzdGVudCBpbnRlcmZhY2UgYWNyb3NzIGRpZmZlcmVudCB0eXBlcyBvZiBhbmNob3JzLlxuICogIDIuIEluc3VsYXRpbmcgdGhlIHJlc3Qgb2YgdGhlIGNvZGUgZnJvbSBBUEkgY2hhbmdlcyBpbiB0aGUgdW5kZXJseWluZyBhbmNob3JpbmdcbiAqICAgICBsaWJyYXJpZXMuXG4gKi9cblxuaW1wb3J0IHsgbWF0Y2hRdW90ZSB9IGZyb20gJy4vbWF0Y2gtcXVvdGUnO1xuaW1wb3J0IHsgVGV4dFJhbmdlLCBUZXh0UG9zaXRpb24gfSBmcm9tICcuL3RleHQtcmFuZ2UnO1xuaW1wb3J0IHsgbm9kZUZyb21YUGF0aCwgeHBhdGhGcm9tTm9kZSB9IGZyb20gJy4veHBhdGgnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uLy4uL3R5cGVzL2FwaScpLlJhbmdlU2VsZWN0b3J9IFJhbmdlU2VsZWN0b3JcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uLy4uL3R5cGVzL2FwaScpLlRleHRQb3NpdGlvblNlbGVjdG9yfSBUZXh0UG9zaXRpb25TZWxlY3RvclxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuVGV4dFF1b3RlU2VsZWN0b3J9IFRleHRRdW90ZVNlbGVjdG9yXG4gKi9cblxuLyoqXG4gKiBDb252ZXJ0cyBiZXR3ZWVuIGBSYW5nZVNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFJhbmdlQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Tm9kZX0gcm9vdCAtIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtICBBIHJhbmdlIGRlc2NyaWJpbmcgdGhlIGFuY2hvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIHJhbmdlKSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLnJhbmdlID0gcmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtOb2RlfSByb290IC0gIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtICBBIHJhbmdlIGRlc2NyaWJpbmcgdGhlIGFuY2hvci5cbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlQW5jaG9yKHJvb3QsIHJhbmdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gYW5jaG9yIGZyb20gYSBzZXJpYWxpemVkIGBSYW5nZVNlbGVjdG9yYCBzZWxlY3Rvci5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290IC0gIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge1JhbmdlU2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBzdGF0aWMgZnJvbVNlbGVjdG9yKHJvb3QsIHNlbGVjdG9yKSB7XG4gICAgY29uc3Qgc3RhcnRDb250YWluZXIgPSBub2RlRnJvbVhQYXRoKHNlbGVjdG9yLnN0YXJ0Q29udGFpbmVyLCByb290KTtcbiAgICBpZiAoIXN0YXJ0Q29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIHN0YXJ0Q29udGFpbmVyIFhQYXRoJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZW5kQ29udGFpbmVyID0gbm9kZUZyb21YUGF0aChzZWxlY3Rvci5lbmRDb250YWluZXIsIHJvb3QpO1xuICAgIGlmICghZW5kQ29udGFpbmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIGVuZENvbnRhaW5lciBYUGF0aCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0UG9zID0gVGV4dFBvc2l0aW9uLmZyb21DaGFyT2Zmc2V0KFxuICAgICAgc3RhcnRDb250YWluZXIsXG4gICAgICBzZWxlY3Rvci5zdGFydE9mZnNldFxuICAgICk7XG4gICAgY29uc3QgZW5kUG9zID0gVGV4dFBvc2l0aW9uLmZyb21DaGFyT2Zmc2V0KFxuICAgICAgZW5kQ29udGFpbmVyLFxuICAgICAgc2VsZWN0b3IuZW5kT2Zmc2V0XG4gICAgKTtcblxuICAgIGNvbnN0IHJhbmdlID0gbmV3IFRleHRSYW5nZShzdGFydFBvcywgZW5kUG9zKS50b1JhbmdlKCk7XG4gICAgcmV0dXJuIG5ldyBSYW5nZUFuY2hvcihyb290LCByYW5nZSk7XG4gIH1cblxuICB0b1JhbmdlKCkge1xuICAgIHJldHVybiB0aGlzLnJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1JhbmdlU2VsZWN0b3J9XG4gICAqL1xuICB0b1NlbGVjdG9yKCkge1xuICAgIC8vIFwiU2hyaW5rXCIgdGhlIHJhbmdlIHNvIHRoYXQgaXQgdGlnaHRseSB3cmFwcyBpdHMgdGV4dC4gVGhpcyBlbnN1cmVzIG1vcmVcbiAgICAvLyBwcmVkaWN0YWJsZSBvdXRwdXQgZm9yIGEgZ2l2ZW4gdGV4dCBzZWxlY3Rpb24uXG4gICAgY29uc3Qgbm9ybWFsaXplZFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZSh0aGlzLnJhbmdlKS50b1JhbmdlKCk7XG5cbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKG5vcm1hbGl6ZWRSYW5nZSk7XG4gICAgY29uc3Qgc3RhcnRDb250YWluZXIgPSB4cGF0aEZyb21Ob2RlKHRleHRSYW5nZS5zdGFydC5lbGVtZW50LCB0aGlzLnJvb3QpO1xuICAgIGNvbnN0IGVuZENvbnRhaW5lciA9IHhwYXRoRnJvbU5vZGUodGV4dFJhbmdlLmVuZC5lbGVtZW50LCB0aGlzLnJvb3QpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdSYW5nZVNlbGVjdG9yJyxcbiAgICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgICAgc3RhcnRPZmZzZXQ6IHRleHRSYW5nZS5zdGFydC5vZmZzZXQsXG4gICAgICBlbmRDb250YWluZXIsXG4gICAgICBlbmRPZmZzZXQ6IHRleHRSYW5nZS5lbmQub2Zmc2V0LFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBiZXR3ZWVuIGBUZXh0UG9zaXRpb25TZWxlY3RvcmAgc2VsZWN0b3JzIGFuZCBgUmFuZ2VgIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0UG9zaXRpb25BbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydFxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCBzdGFydCwgZW5kKSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5lbmQgPSBlbmQ7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJvb3QsIHJhbmdlKSB7XG4gICAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhyb290KTtcbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbkFuY2hvcihcbiAgICAgIHJvb3QsXG4gICAgICB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0LFxuICAgICAgdGV4dFJhbmdlLmVuZC5vZmZzZXRcbiAgICApO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb25TZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbkFuY2hvcihyb290LCBzZWxlY3Rvci5zdGFydCwgc2VsZWN0b3IuZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUZXh0UG9zaXRpb25TZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdUZXh0UG9zaXRpb25TZWxlY3RvcicsXG4gICAgICBzdGFydDogdGhpcy5zdGFydCxcbiAgICAgIGVuZDogdGhpcy5lbmQsXG4gICAgfTtcbiAgfVxuXG4gIHRvUmFuZ2UoKSB7XG4gICAgcmV0dXJuIFRleHRSYW5nZS5mcm9tT2Zmc2V0cyh0aGlzLnJvb3QsIHRoaXMuc3RhcnQsIHRoaXMuZW5kKS50b1JhbmdlKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAdHlwZWRlZiBRdW90ZU1hdGNoT3B0aW9uc1xuICogQHByb3Age251bWJlcn0gW2hpbnRdIC0gRXhwZWN0ZWQgcG9zaXRpb24gb2YgbWF0Y2ggaW4gdGV4dC4gU2VlIGBtYXRjaFF1b3RlYC5cbiAqL1xuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFRleHRRdW90ZVNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRRdW90ZUFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3QgLSBBIHJvb3QgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGFuY2hvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGV4YWN0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gICAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnByZWZpeF1cbiAgICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQuc3VmZml4XVxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgZXhhY3QsIGNvbnRleHQgPSB7fSkge1xuICAgIHRoaXMucm9vdCA9IHJvb3Q7XG4gICAgdGhpcy5leGFjdCA9IGV4YWN0O1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgYFRleHRRdW90ZUFuY2hvcmAgZnJvbSBhIHJhbmdlLlxuICAgKlxuICAgKiBXaWxsIHRocm93IGlmIGByYW5nZWAgZG9lcyBub3QgY29udGFpbiBhbnkgdGV4dCBub2Rlcy5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fSByb290XG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJvb3QsIHJhbmdlKSB7XG4gICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocm9vdC50ZXh0Q29udGVudCk7XG4gICAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhyb290KTtcblxuICAgIGNvbnN0IHN0YXJ0ID0gdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldDtcbiAgICBjb25zdCBlbmQgPSB0ZXh0UmFuZ2UuZW5kLm9mZnNldDtcblxuICAgIC8vIE51bWJlciBvZiBjaGFyYWN0ZXJzIGFyb3VuZCB0aGUgcXVvdGUgdG8gY2FwdHVyZSBhcyBjb250ZXh0LiBXZSBjdXJyZW50bHlcbiAgICAvLyBhbHdheXMgdXNlIGEgZml4ZWQgYW1vdW50LCBidXQgaXQgd291bGQgYmUgYmV0dGVyIGlmIHRoaXMgY29kZSB3YXMgYXdhcmVcbiAgICAvLyBvZiBsb2dpY2FsIGJvdW5kYXJpZXMgaW4gdGhlIGRvY3VtZW50IChwYXJhZ3JhcGgsIGFydGljbGUgZXRjLikgdG8gYXZvaWRcbiAgICAvLyBjYXB0dXJpbmcgdGV4dCB1bnJlbGF0ZWQgdG8gdGhlIHF1b3RlLlxuICAgIC8vXG4gICAgLy8gSW4gcmVndWxhciBwcm9zZSB0aGUgaWRlYWwgY29udGVudCB3b3VsZCBvZnRlbiBiZSB0aGUgc3Vycm91bmRpbmcgc2VudGVuY2UuXG4gICAgLy8gVGhpcyBpcyBhIG5hdHVyYWwgdW5pdCBvZiBtZWFuaW5nIHdoaWNoIGVuYWJsZXMgZGlzcGxheWluZyBxdW90ZXMgaW5cbiAgICAvLyBjb250ZXh0IGV2ZW4gd2hlbiB0aGUgZG9jdW1lbnQgaXMgbm90IGF2YWlsYWJsZS4gV2UgY291bGQgdXNlIGBJbnRsLlNlZ21lbnRlcmBcbiAgICAvLyBmb3IgdGhpcyB3aGVuIGF2YWlsYWJsZS5cbiAgICBjb25zdCBjb250ZXh0TGVuID0gMzI7XG5cbiAgICByZXR1cm4gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCB0ZXh0LnNsaWNlKHN0YXJ0LCBlbmQpLCB7XG4gICAgICBwcmVmaXg6IHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgc3RhcnQgLSBjb250ZXh0TGVuKSwgc3RhcnQpLFxuICAgICAgc3VmZml4OiB0ZXh0LnNsaWNlKGVuZCwgTWF0aC5taW4odGV4dC5sZW5ndGgsIGVuZCArIGNvbnRleHRMZW4pKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtUZXh0UXVvdGVTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCB7IHByZWZpeCwgc3VmZml4IH0gPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCBzZWxlY3Rvci5leGFjdCwgeyBwcmVmaXgsIHN1ZmZpeCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUZXh0UXVvdGVTZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdUZXh0UXVvdGVTZWxlY3RvcicsXG4gICAgICBleGFjdDogdGhpcy5leGFjdCxcbiAgICAgIHByZWZpeDogdGhpcy5jb250ZXh0LnByZWZpeCxcbiAgICAgIHN1ZmZpeDogdGhpcy5jb250ZXh0LnN1ZmZpeCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVvdGVNYXRjaE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKi9cbiAgdG9SYW5nZShvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy50b1Bvc2l0aW9uQW5jaG9yKG9wdGlvbnMpLnRvUmFuZ2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1b3RlTWF0Y2hPcHRpb25zfSBbb3B0aW9uc11cbiAgICovXG4gIHRvUG9zaXRpb25BbmNob3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAodGhpcy5yb290LnRleHRDb250ZW50KTtcbiAgICBjb25zdCBtYXRjaCA9IG1hdGNoUXVvdGUodGV4dCwgdGhpcy5leGFjdCwge1xuICAgICAgLi4udGhpcy5jb250ZXh0LFxuICAgICAgaGludDogb3B0aW9ucy5oaW50LFxuICAgIH0pO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUXVvdGUgbm90IGZvdW5kJyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKHRoaXMucm9vdCwgbWF0Y2guc3RhcnQsIG1hdGNoLmVuZCk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IFRleHRRdW90ZUFuY2hvciB9IGZyb20gXCIuL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90eXBlc1wiO1xuXG4vLyBDYXRjaCBKUyBlcnJvcnMgdG8gbG9nIHRoZW0gaW4gdGhlIGFwcC5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImVycm9yXCIsXG4gIGZ1bmN0aW9uIChldmVudCkge1xuICAgIEFuZHJvaWQubG9nRXJyb3IoZXZlbnQubWVzc2FnZSwgZXZlbnQuZmlsZW5hbWUsIGV2ZW50LmxpbmVubyk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICBvblZpZXdwb3J0V2lkdGhDaGFuZ2VkKCk7XG4gICAgICBzbmFwQ3VycmVudE9mZnNldCgpO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuYm9keSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG4vKipcbiAqIEhhdmluZyBhbiBvZGQgbnVtYmVyIG9mIGNvbHVtbnMgd2hlbiBkaXNwbGF5aW5nIHR3byBjb2x1bW5zIHBlciBzY3JlZW4gY2F1c2VzIHNuYXBwaW5nIGFuZCBwYWdlXG4gKiB0dXJuaW5nIGlzc3Vlcy4gVG8gZml4IHRoaXMsIHdlIGluc2VydCBhIGJsYW5rIHZpcnR1YWwgY29sdW1uIGF0IHRoZSBlbmQgb2YgdGhlIHJlc291cmNlLlxuICovXG5mdW5jdGlvbiBhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQoKSB7XG4gIGNvbnN0IGlkID0gXCJyZWFkaXVtLXZpcnR1YWwtcGFnZVwiO1xuICB2YXIgdmlydHVhbENvbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSB8fCBnZXRDb2x1bW5Db3VudFBlclNjcmVlbigpICE9IDIpIHtcbiAgICBpZiAodmlydHVhbENvbCkge1xuICAgICAgdmlydHVhbENvbC5yZW1vdmUoKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICAgIHZhciBjb2xDb3VudCA9IGRvY3VtZW50V2lkdGggLyBwYWdlV2lkdGg7XG4gICAgdmFyIGhhc09kZENvbENvdW50ID0gKE1hdGgucm91bmQoY29sQ291bnQgKiAyKSAvIDIpICUgMSA+IDAuMTtcbiAgICBpZiAoaGFzT2RkQ29sQ291bnQpIHtcbiAgICAgIGlmICh2aXJ0dWFsQ29sKSB7XG4gICAgICAgIHZpcnR1YWxDb2wucmVtb3ZlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aXJ0dWFsQ29sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgdmlydHVhbENvbC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBpZCk7XG4gICAgICAgIHZpcnR1YWxDb2wuc3R5bGUuYnJlYWtCZWZvcmUgPSBcImNvbHVtblwiO1xuICAgICAgICB2aXJ0dWFsQ29sLmlubmVySFRNTCA9IFwiJiM4MjAzO1wiOyAvLyB6ZXJvLXdpZHRoIHNwYWNlXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodmlydHVhbENvbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB2YXIgcGFnZVdpZHRoID0gMTtcblxuZnVuY3Rpb24gb25WaWV3cG9ydFdpZHRoQ2hhbmdlZCgpIHtcbiAgLy8gV2UgY2FuJ3QgcmVseSBvbiB3aW5kb3cuaW5uZXJXaWR0aCBmb3IgdGhlIHBhZ2VXaWR0aCBvbiBBbmRyb2lkLCBiZWNhdXNlIGlmIHRoZVxuICAvLyBkZXZpY2UgcGl4ZWwgcmF0aW8gaXMgbm90IGFuIGludGVnZXIsIHdlIGdldCByb3VuZGluZyBpc3N1ZXMgb2Zmc2V0dGluZyB0aGUgcGFnZXMuXG4gIC8vXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vcmVhZGl1bS9yZWFkaXVtLWNzcy9pc3N1ZXMvOTdcbiAgLy8gYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFkaXVtL3IyLW5hdmlnYXRvci1rb3RsaW4vaXNzdWVzLzE0NlxuICB2YXIgd2lkdGggPSBBbmRyb2lkLmdldFZpZXdwb3J0V2lkdGgoKTtcbiAgcGFnZVdpZHRoID0gd2lkdGggLyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgc2V0UHJvcGVydHkoXG4gICAgXCItLVJTX192aWV3cG9ydFdpZHRoXCIsXG4gICAgXCJjYWxjKFwiICsgd2lkdGggKyBcInB4IC8gXCIgKyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyArIFwiKVwiXG4gICk7XG5cbiAgYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2x1bW5Db3VudFBlclNjcmVlbigpIHtcbiAgcmV0dXJuIHBhcnNlSW50KFxuICAgIHdpbmRvd1xuICAgICAgLmdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KVxuICAgICAgLmdldFByb3BlcnR5VmFsdWUoXCJjb2x1bW4tY291bnRcIilcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSB7XG4gIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlO1xuICByZXR1cm4gKFxuICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLVVTRVJfX3ZpZXdcIikudHJpbSgpID09IFwicmVhZGl1bS1zY3JvbGwtb25cIiB8fFxuICAgIC8vIEZJWE1FOiBXaWxsIG5lZWQgdG8gYmUgcmVtb3ZlZCBpbiBSZWFkaXVtIDMuMCwgLS1VU0VSX19zY3JvbGwgd2FzIGluY29ycmVjdC5cbiAgICBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1VU0VSX19zY3JvbGxcIikudHJpbSgpID09IFwicmVhZGl1bS1zY3JvbGwtb25cIlxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSVEwoKSB7XG4gIHJldHVybiBkb2N1bWVudC5ib2R5LmRpci50b0xvd2VyQ2FzZSgpID09IFwicnRsXCI7XG59XG5cbi8vIFNjcm9sbCB0byB0aGUgZ2l2ZW4gVGFnSWQgaW4gZG9jdW1lbnQgYW5kIHNuYXAuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9JZChpZCkge1xuICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHNjcm9sbFRvUmVjdChlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbn1cblxuLy8gUG9zaXRpb24gbXVzdCBiZSBpbiB0aGUgcmFuZ2UgWzAgLSAxXSwgMC0xMDAlLlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvUG9zaXRpb24ocG9zaXRpb24pIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9Qb3NpdGlvbiBcIiArIHBvc2l0aW9uKTtcbiAgaWYgKHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+IDEpIHtcbiAgICB0aHJvdyBcInNjcm9sbFRvUG9zaXRpb24oKSBtdXN0IGJlIGdpdmVuIGEgcG9zaXRpb24gZnJvbSAwLjAgdG8gIDEuMFwiO1xuICB9XG5cbiAgbGV0IG9mZnNldDtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIG9mZnNldCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsSGVpZ2h0ICogcG9zaXRpb247XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSBvZmZzZXQ7XG4gICAgLy8gd2luZG93LnNjcm9sbFRvKDAsIG9mZnNldCk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICAgIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICAgIG9mZnNldCA9IGRvY3VtZW50V2lkdGggKiBwb3NpdGlvbiAqIGZhY3RvcjtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KG9mZnNldCk7XG4gIH1cbn1cblxuLy8gU2Nyb2xscyB0byB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgZ2l2ZW4gdGV4dCBzbmlwcGV0LlxuLy9cbi8vIFRoZSBleHBlY3RlZCB0ZXh0IGFyZ3VtZW50IGlzIGEgTG9jYXRvciBUZXh0IG9iamVjdCwgYXMgZGVmaW5lZCBoZXJlOlxuLy8gaHR0cHM6Ly9yZWFkaXVtLm9yZy9hcmNoaXRlY3R1cmUvbW9kZWxzL2xvY2F0b3JzL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvVGV4dCh0ZXh0KSB7XG4gIGxldCByYW5nZSA9IHJhbmdlRnJvbUxvY2F0b3IoeyB0ZXh0IH0pO1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHNjcm9sbFRvUmFuZ2UocmFuZ2UpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gc2Nyb2xsVG9SYW5nZShyYW5nZSkge1xuICByZXR1cm4gc2Nyb2xsVG9SZWN0KHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbn1cblxuZnVuY3Rpb24gc2Nyb2xsVG9SZWN0KHJlY3QpIHtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID1cbiAgICAgIHJlY3QudG9wICsgd2luZG93LnNjcm9sbFkgLSB3aW5kb3cuaW5uZXJIZWlnaHQgLyAyO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoXG4gICAgICByZWN0LmxlZnQgKyB3aW5kb3cuc2Nyb2xsWFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvU3RhcnQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvU3RhcnRcIik7XG4gIGlmICghaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IDA7XG4gICAgd2luZG93LnNjcm9sbFRvKDAsIDApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb0VuZCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9FbmRcIik7XG4gIGlmICghaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChcbiAgICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGggKiBmYWN0b3JcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQ7XG4gICAgd2luZG93LnNjcm9sbFRvKDAsIGRvY3VtZW50LmJvZHkuc2Nyb2xsSGVpZ2h0KTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIGlzIGFscmVhZHkgYXQgdGhlIGxlZnQtbW9zdCBzY3JvbGwgb2Zmc2V0LlxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbExlZnQoKSB7XG4gIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgdmFyIG9mZnNldCA9IHdpbmRvdy5zY3JvbGxYIC0gcGFnZVdpZHRoO1xuICB2YXIgbWluT2Zmc2V0ID0gaXNSVEwoKSA/IC0oZG9jdW1lbnRXaWR0aCAtIHBhZ2VXaWR0aCkgOiAwO1xuICByZXR1cm4gc2Nyb2xsVG9PZmZzZXQoTWF0aC5tYXgob2Zmc2V0LCBtaW5PZmZzZXQpKTtcbn1cblxuLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgcGFnZSBpcyBhbHJlYWR5IGF0IHRoZSByaWdodC1tb3N0IHNjcm9sbCBvZmZzZXQuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsUmlnaHQoKSB7XG4gIHZhciBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgdmFyIG9mZnNldCA9IHdpbmRvdy5zY3JvbGxYICsgcGFnZVdpZHRoO1xuICB2YXIgbWF4T2Zmc2V0ID0gaXNSVEwoKSA/IDAgOiBkb2N1bWVudFdpZHRoIC0gcGFnZVdpZHRoO1xuICByZXR1cm4gc2Nyb2xsVG9PZmZzZXQoTWF0aC5taW4ob2Zmc2V0LCBtYXhPZmZzZXQpKTtcbn1cblxuLy8gU2Nyb2xscyB0byB0aGUgZ2l2ZW4gbGVmdCBvZmZzZXQuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIHNjcm9sbCBwb3NpdGlvbiBpcyBhbHJlYWR5IGNsb3NlIGVub3VnaCB0byB0aGUgZ2l2ZW4gb2Zmc2V0LlxuZnVuY3Rpb24gc2Nyb2xsVG9PZmZzZXQob2Zmc2V0KSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNjcm9sbFRvT2Zmc2V0IFwiICsgb2Zmc2V0KTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHRocm93IFwiQ2FsbGVkIHNjcm9sbFRvT2Zmc2V0KCkgd2l0aCBzY3JvbGwgbW9kZSBlbmFibGVkLiBUaGlzIGNhbiBvbmx5IGJlIHVzZWQgaW4gcGFnaW5hdGVkIG1vZGUuXCI7XG4gIH1cblxuICB2YXIgY3VycmVudE9mZnNldCA9IHdpbmRvdy5zY3JvbGxYO1xuICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KG9mZnNldCk7XG4gIC8vIEluIHNvbWUgY2FzZSB0aGUgc2Nyb2xsWCBjYW5ub3QgcmVhY2ggdGhlIHBvc2l0aW9uIHJlc3BlY3RpbmcgdG8gaW5uZXJXaWR0aFxuICB2YXIgZGlmZiA9IE1hdGguYWJzKGN1cnJlbnRPZmZzZXQgLSBvZmZzZXQpIC8gcGFnZVdpZHRoO1xuICByZXR1cm4gZGlmZiA+IDAuMDE7XG59XG5cbi8vIFNuYXAgdGhlIG9mZnNldCB0byB0aGUgc2NyZWVuIHdpZHRoIChwYWdlIHdpZHRoKS5cbmZ1bmN0aW9uIHNuYXBPZmZzZXQob2Zmc2V0KSB7XG4gIHZhciB2YWx1ZSA9IG9mZnNldCArIChpc1JUTCgpID8gLTEgOiAxKTtcbiAgcmV0dXJuIHZhbHVlIC0gKHZhbHVlICUgcGFnZVdpZHRoKTtcbn1cblxuLy8gU25hcHMgdGhlIGN1cnJlbnQgb2Zmc2V0IHRvIHRoZSBwYWdlIHdpZHRoLlxuZXhwb3J0IGZ1bmN0aW9uIHNuYXBDdXJyZW50T2Zmc2V0KCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzbmFwQ3VycmVudE9mZnNldFwiKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgY3VycmVudE9mZnNldCA9IHdpbmRvdy5zY3JvbGxYO1xuICAvLyBBZGRzIGhhbGYgYSBwYWdlIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndCBzbmFwIHRvIHRoZSBwcmV2aW91cyBwYWdlLlxuICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgdmFyIGRlbHRhID0gZmFjdG9yICogKHBhZ2VXaWR0aCAvIDIpO1xuICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KGN1cnJlbnRPZmZzZXQgKyBkZWx0YSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByYW5nZUZyb21Mb2NhdG9yKGxvY2F0b3IpIHtcbiAgdHJ5IHtcbiAgICBsZXQgbG9jYXRpb25zID0gbG9jYXRvci5sb2NhdGlvbnM7XG4gICAgbGV0IHRleHQgPSBsb2NhdG9yLnRleHQ7XG4gICAgaWYgKHRleHQgJiYgdGV4dC5oaWdobGlnaHQpIHtcbiAgICAgIHZhciByb290O1xuICAgICAgaWYgKGxvY2F0aW9ucyAmJiBsb2NhdGlvbnMuY3NzU2VsZWN0b3IpIHtcbiAgICAgICAgcm9vdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobG9jYXRpb25zLmNzc1NlbGVjdG9yKTtcbiAgICAgIH1cbiAgICAgIGlmICghcm9vdCkge1xuICAgICAgICByb290ID0gZG9jdW1lbnQuYm9keTtcbiAgICAgIH1cblxuICAgICAgbGV0IGFuY2hvciA9IG5ldyBUZXh0UXVvdGVBbmNob3Iocm9vdCwgdGV4dC5oaWdobGlnaHQsIHtcbiAgICAgICAgcHJlZml4OiB0ZXh0LmJlZm9yZSxcbiAgICAgICAgc3VmZml4OiB0ZXh0LmFmdGVyLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gYW5jaG9yLnRvUmFuZ2UoKTtcbiAgICB9XG5cbiAgICBpZiAobG9jYXRpb25zKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IG51bGw7XG5cbiAgICAgIGlmICghZWxlbWVudCAmJiBsb2NhdGlvbnMuY3NzU2VsZWN0b3IpIHtcbiAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobG9jYXRpb25zLmNzc1NlbGVjdG9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50ICYmIGxvY2F0aW9ucy5mcmFnbWVudHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBodG1sSWQgb2YgbG9jYXRpb25zLmZyYWdtZW50cykge1xuICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChodG1sSWQpO1xuICAgICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgbGV0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnRCZWZvcmUoZWxlbWVudCk7XG4gICAgICAgIHJhbmdlLnNldEVuZEFmdGVyKGVsZW1lbnQpO1xuICAgICAgICByZXR1cm4gcmFuZ2U7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nRXJyb3IoZSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8vIFVzZXIgU2V0dGluZ3MuXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRDU1NQcm9wZXJ0aWVzKHByb3BlcnRpZXMpIHtcbiAgZm9yIChjb25zdCBuYW1lIGluIHByb3BlcnRpZXMpIHtcbiAgICBzZXRQcm9wZXJ0eShuYW1lLCBwcm9wZXJ0aWVzW25hbWVdKTtcbiAgfVxufVxuXG4vLyBGb3Igc2V0dGluZyB1c2VyIHNldHRpbmcuXG5leHBvcnQgZnVuY3Rpb24gc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCIpIHtcbiAgICByZW1vdmVQcm9wZXJ0eShrZXkpO1xuICB9IGVsc2Uge1xuICAgIHZhciByb290ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgIC8vIFRoZSBgIWltcG9ydGFudGAgYW5ub3RhdGlvbiBpcyBhZGRlZCB3aXRoIGBzZXRQcm9wZXJ0eSgpYCBiZWNhdXNlIGlmIGl0J3MgcGFydCBvZiB0aGVcbiAgICAvLyBgdmFsdWVgLCBpdCB3aWxsIGJlIGlnbm9yZWQgYnkgdGhlIFdlYiBWaWV3LlxuICAgIHJvb3Quc3R5bGUuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSwgXCJpbXBvcnRhbnRcIik7XG4gIH1cbn1cblxuLy8gRm9yIHJlbW92aW5nIHVzZXIgc2V0dGluZy5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVQcm9wZXJ0eShrZXkpIHtcbiAgdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cbiAgcm9vdC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShrZXkpO1xufVxuXG4vLy8gVG9vbGtpdFxuXG5leHBvcnQgZnVuY3Rpb24gbG9nKCkge1xuICB2YXIgbWVzc2FnZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykuam9pbihcIiBcIik7XG4gIEFuZHJvaWQubG9nKG1lc3NhZ2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9nRXJyb3IobWVzc2FnZSkge1xuICBBbmRyb2lkLmxvZ0Vycm9yKG1lc3NhZ2UsIFwiXCIsIDApO1xufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgbG9nIGFzIGxvZ05hdGl2ZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmNvbnN0IGRlYnVnID0gZmFsc2U7XG5cbi8qKlxuICogQ29udmVydHMgYSBET01SZWN0IGludG8gYSBKU09OIG9iamVjdCB1bmRlcnN0YW5kYWJsZSBieSB0aGUgbmF0aXZlIHNpZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b05hdGl2ZVJlY3QocmVjdCkge1xuICBjb25zdCBwaXhlbFJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gIGNvbnN0IHdpZHRoID0gcmVjdC53aWR0aCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IGhlaWdodCA9IHJlY3QuaGVpZ2h0ICogcGl4ZWxSYXRpbztcbiAgY29uc3QgbGVmdCA9IHJlY3QubGVmdCAqIHBpeGVsUmF0aW87XG4gIGNvbnN0IHRvcCA9IHJlY3QudG9wICogcGl4ZWxSYXRpbztcbiAgY29uc3QgcmlnaHQgPSBsZWZ0ICsgd2lkdGg7XG4gIGNvbnN0IGJvdHRvbSA9IHRvcCArIGhlaWdodDtcbiAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCwgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChcbiAgcmFuZ2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBsZXQgY2xpZW50UmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xuXG4gIGNvbnN0IHRvbGVyYW5jZSA9IDE7XG4gIGNvbnN0IG9yaWdpbmFsUmVjdHMgPSBbXTtcbiAgZm9yIChjb25zdCByYW5nZUNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBvcmlnaW5hbFJlY3RzLnB1c2goe1xuICAgICAgYm90dG9tOiByYW5nZUNsaWVudFJlY3QuYm90dG9tLFxuICAgICAgaGVpZ2h0OiByYW5nZUNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgbGVmdDogcmFuZ2VDbGllbnRSZWN0LmxlZnQsXG4gICAgICByaWdodDogcmFuZ2VDbGllbnRSZWN0LnJpZ2h0LFxuICAgICAgdG9wOiByYW5nZUNsaWVudFJlY3QudG9wLFxuICAgICAgd2lkdGg6IHJhbmdlQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9KTtcbiAgfVxuICBjb25zdCBtZXJnZWRSZWN0cyA9IG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICBvcmlnaW5hbFJlY3RzLFxuICAgIHRvbGVyYW5jZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG4gIGNvbnN0IG5vQ29udGFpbmVkUmVjdHMgPSByZW1vdmVDb250YWluZWRSZWN0cyhtZXJnZWRSZWN0cywgdG9sZXJhbmNlKTtcbiAgY29uc3QgbmV3UmVjdHMgPSByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5vQ29udGFpbmVkUmVjdHMpO1xuICBjb25zdCBtaW5BcmVhID0gMiAqIDI7XG4gIGZvciAobGV0IGogPSBuZXdSZWN0cy5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgIGNvbnN0IHJlY3QgPSBuZXdSZWN0c1tqXTtcbiAgICBjb25zdCBiaWdFbm91Z2ggPSByZWN0LndpZHRoICogcmVjdC5oZWlnaHQgPiBtaW5BcmVhO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBpZiAobmV3UmVjdHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsXCIpO1xuICAgICAgICBuZXdSZWN0cy5zcGxpY2UoaiwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsLCBidXQga2VlcCBvdGhlcndpc2UgZW1wdHkhXCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgbG9nKGBDTElFTlQgUkVDVDogcmVkdWNlZCAke29yaWdpbmFsUmVjdHMubGVuZ3RofSAtLT4gJHtuZXdSZWN0cy5sZW5ndGh9YCk7XG4gIHJldHVybiBuZXdSZWN0cztcbn1cblxuZnVuY3Rpb24gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICByZWN0cyxcbiAgdG9sZXJhbmNlLFxuICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgbG9nKFwibWVyZ2VUb3VjaGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVjdHNMaW5lVXBWZXJ0aWNhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCByZWN0c0xpbmVVcEhvcml6b250YWxseSA9XG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQsIHRvbGVyYW5jZSkgJiZcbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0LCB0b2xlcmFuY2UpO1xuICAgICAgY29uc3QgaG9yaXpvbnRhbEFsbG93ZWQgPSAhZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cztcbiAgICAgIGNvbnN0IGFsaWduZWQgPVxuICAgICAgICAocmVjdHNMaW5lVXBIb3Jpem9udGFsbHkgJiYgaG9yaXpvbnRhbEFsbG93ZWQpIHx8XG4gICAgICAgIChyZWN0c0xpbmVVcFZlcnRpY2FsbHkgJiYgIXJlY3RzTGluZVVwSG9yaXpvbnRhbGx5KTtcbiAgICAgIGNvbnN0IGNhbk1lcmdlID0gYWxpZ25lZCAmJiByZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKTtcbiAgICAgIGlmIChjYW5NZXJnZSkge1xuICAgICAgICBsb2coXG4gICAgICAgICAgYENMSUVOVCBSRUNUOiBtZXJnaW5nIHR3byBpbnRvIG9uZSwgVkVSVElDQUw6ICR7cmVjdHNMaW5lVXBWZXJ0aWNhbGx5fSBIT1JJWk9OVEFMOiAke3JlY3RzTGluZVVwSG9yaXpvbnRhbGx5fSAoJHtkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzfSlgXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHJlY3QxICYmIHJlY3QgIT09IHJlY3QyO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVwbGFjZW1lbnRDbGllbnRSZWN0ID0gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIG5ld1JlY3RzLnB1c2gocmVwbGFjZW1lbnRDbGllbnRSZWN0KTtcbiAgICAgICAgcmV0dXJuIG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICAgICAgICBuZXdSZWN0cyxcbiAgICAgICAgICB0b2xlcmFuY2UsXG4gICAgICAgICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbGVmdCA9IE1hdGgubWluKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCByaWdodCA9IE1hdGgubWF4KHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IHRvcCA9IE1hdGgubWluKHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgYm90dG9tID0gTWF0aC5tYXgocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbSxcbiAgICBoZWlnaHQ6IGJvdHRvbSAtIHRvcCxcbiAgICBsZWZ0LFxuICAgIHJpZ2h0LFxuICAgIHRvcCxcbiAgICB3aWR0aDogcmlnaHQgLSBsZWZ0LFxuICB9O1xufVxuXG5mdW5jdGlvbiByZW1vdmVDb250YWluZWRSZWN0cyhyZWN0cywgdG9sZXJhbmNlKSB7XG4gIGNvbnN0IHJlY3RzVG9LZWVwID0gbmV3IFNldChyZWN0cyk7XG4gIGZvciAoY29uc3QgcmVjdCBvZiByZWN0cykge1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggPiAxICYmIHJlY3QuaGVpZ2h0ID4gMTtcbiAgICBpZiAoIWJpZ0Vub3VnaCkge1xuICAgICAgbG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSB0aW55XCIpO1xuICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcG9zc2libHlDb250YWluaW5nUmVjdCBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QgPT09IHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIXJlY3RzVG9LZWVwLmhhcyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0Q29udGFpbnMocG9zc2libHlDb250YWluaW5nUmVjdCwgcmVjdCwgdG9sZXJhbmNlKSkge1xuICAgICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIGNvbnRhaW5lZFwiKTtcbiAgICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20ocmVjdHNUb0tlZXApO1xufVxuXG5mdW5jdGlvbiByZWN0Q29udGFpbnMocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIubGVmdCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLnJpZ2h0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY3RDb250YWluc1BvaW50KHJlY3QsIHgsIHksIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0LmxlZnQgPCB4IHx8IGFsbW9zdEVxdWFsKHJlY3QubGVmdCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC5yaWdodCA+IHggfHwgYWxtb3N0RXF1YWwocmVjdC5yaWdodCwgeCwgdG9sZXJhbmNlKSkgJiZcbiAgICAocmVjdC50b3AgPCB5IHx8IGFsbW9zdEVxdWFsKHJlY3QudG9wLCB5LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LmJvdHRvbSA+IHkgfHwgYWxtb3N0RXF1YWwocmVjdC5ib3R0b20sIHksIHRvbGVyYW5jZSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMocmVjdHMpIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCByZWN0MSA9IHJlY3RzW2ldO1xuICAgICAgY29uc3QgcmVjdDIgPSByZWN0c1tqXTtcbiAgICAgIGlmIChyZWN0MSA9PT0gcmVjdDIpIHtcbiAgICAgICAgbG9nKFwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyByZWN0MSA9PT0gcmVjdDIgPz8hXCIpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgLTEpKSB7XG4gICAgICAgIGxldCB0b0FkZCA9IFtdO1xuICAgICAgICBsZXQgdG9SZW1vdmU7XG4gICAgICAgIGNvbnN0IHN1YnRyYWN0UmVjdHMxID0gcmVjdFN1YnRyYWN0KHJlY3QxLCByZWN0Mik7XG4gICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czIgPSByZWN0U3VidHJhY3QocmVjdDIsIHJlY3QxKTtcbiAgICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoIDwgc3VidHJhY3RSZWN0czIubGVuZ3RoKSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMxO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMjtcbiAgICAgICAgICAgIHRvUmVtb3ZlID0gcmVjdDI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxvZyhgQ0xJRU5UIFJFQ1Q6IG92ZXJsYXAsIGN1dCBvbmUgcmVjdCBpbnRvICR7dG9BZGQubGVuZ3RofWApO1xuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSB0b1JlbW92ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KG5ld1JlY3RzLCB0b0FkZCk7XG4gICAgICAgIHJldHVybiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5ld1JlY3RzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IHJlY3RJbnRlcnNlY3RlZCA9IHJlY3RJbnRlcnNlY3QocmVjdDIsIHJlY3QxKTtcbiAgaWYgKHJlY3RJbnRlcnNlY3RlZC5oZWlnaHQgPT09IDAgfHwgcmVjdEludGVyc2VjdGVkLndpZHRoID09PSAwKSB7XG4gICAgcmV0dXJuIFtyZWN0MV07XG4gIH1cbiAgY29uc3QgcmVjdHMgPSBbXTtcbiAge1xuICAgIGNvbnN0IHJlY3RBID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0MS5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RBLndpZHRoID0gcmVjdEEucmlnaHQgLSByZWN0QS5sZWZ0O1xuICAgIHJlY3RBLmhlaWdodCA9IHJlY3RBLmJvdHRvbSAtIHJlY3RBLnRvcDtcbiAgICBpZiAocmVjdEEuaGVpZ2h0ICE9PSAwICYmIHJlY3RBLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RBKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RCID0ge1xuICAgICAgYm90dG9tOiByZWN0SW50ZXJzZWN0ZWQudG9wLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbGVmdDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLnJpZ2h0LFxuICAgICAgdG9wOiByZWN0MS50b3AsXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RCLndpZHRoID0gcmVjdEIucmlnaHQgLSByZWN0Qi5sZWZ0O1xuICAgIHJlY3RCLmhlaWdodCA9IHJlY3RCLmJvdHRvbSAtIHJlY3RCLnRvcDtcbiAgICBpZiAocmVjdEIuaGVpZ2h0ICE9PSAwICYmIHJlY3RCLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RCKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3RDID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3RJbnRlcnNlY3RlZC5ib3R0b20sXG4gICAgICB3aWR0aDogMCxcbiAgICB9O1xuICAgIHJlY3RDLndpZHRoID0gcmVjdEMucmlnaHQgLSByZWN0Qy5sZWZ0O1xuICAgIHJlY3RDLmhlaWdodCA9IHJlY3RDLmJvdHRvbSAtIHJlY3RDLnRvcDtcbiAgICBpZiAocmVjdEMuaGVpZ2h0ICE9PSAwICYmIHJlY3RDLndpZHRoICE9PSAwKSB7XG4gICAgICByZWN0cy5wdXNoKHJlY3RDKTtcbiAgICB9XG4gIH1cbiAge1xuICAgIGNvbnN0IHJlY3REID0ge1xuICAgICAgYm90dG9tOiByZWN0MS5ib3R0b20sXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICByaWdodDogcmVjdDEucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEQud2lkdGggPSByZWN0RC5yaWdodCAtIHJlY3RELmxlZnQ7XG4gICAgcmVjdEQuaGVpZ2h0ID0gcmVjdEQuYm90dG9tIC0gcmVjdEQudG9wO1xuICAgIGlmIChyZWN0RC5oZWlnaHQgIT09IDAgJiYgcmVjdEQud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RJbnRlcnNlY3QocmVjdDEsIHJlY3QyKSB7XG4gIGNvbnN0IG1heExlZnQgPSBNYXRoLm1heChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KTtcbiAgY29uc3QgbWluUmlnaHQgPSBNYXRoLm1pbihyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQpO1xuICBjb25zdCBtYXhUb3AgPSBNYXRoLm1heChyZWN0MS50b3AsIHJlY3QyLnRvcCk7XG4gIGNvbnN0IG1pbkJvdHRvbSA9IE1hdGgubWluKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKTtcbiAgcmV0dXJuIHtcbiAgICBib3R0b206IG1pbkJvdHRvbSxcbiAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIG1pbkJvdHRvbSAtIG1heFRvcCksXG4gICAgbGVmdDogbWF4TGVmdCxcbiAgICByaWdodDogbWluUmlnaHQsXG4gICAgdG9wOiBtYXhUb3AsXG4gICAgd2lkdGg6IE1hdGgubWF4KDAsIG1pblJpZ2h0IC0gbWF4TGVmdCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICAocmVjdDEubGVmdCA8IHJlY3QyLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi5sZWZ0IDwgcmVjdDEucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi5sZWZ0LCByZWN0MS5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QxLnRvcCA8IHJlY3QyLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIudG9wIDwgcmVjdDEuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIudG9wLCByZWN0MS5ib3R0b20sIHRvbGVyYW5jZSkpKVxuICApO1xufVxuXG5mdW5jdGlvbiBhbG1vc3RFcXVhbChhLCBiLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8PSB0b2xlcmFuY2U7XG59XG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgbG9nTmF0aXZlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7XG4gIGdldENsaWVudFJlY3RzTm9PdmVybGFwLFxuICByZWN0Q29udGFpbnNQb2ludCxcbiAgdG9OYXRpdmVSZWN0LFxufSBmcm9tIFwiLi9yZWN0XCI7XG5pbXBvcnQgeyBsb2csIGxvZ0Vycm9yLCByYW5nZUZyb21Mb2NhdG9yIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxubGV0IHN0eWxlcyA9IG5ldyBNYXAoKTtcbmxldCBncm91cHMgPSBuZXcgTWFwKCk7XG52YXIgbGFzdEdyb3VwSWQgPSAwO1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGxpc3Qgb2YgYWRkaXRpb25hbCBzdXBwb3J0ZWQgRGVjb3JhdGlvbiBUZW1wbGF0ZXMuXG4gKlxuICogRWFjaCB0ZW1wbGF0ZSBvYmplY3QgaXMgaW5kZXhlZCBieSB0aGUgc3R5bGUgSUQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclRlbXBsYXRlcyhuZXdTdHlsZXMpIHtcbiAgdmFyIHN0eWxlc2hlZXQgPSBcIlwiO1xuXG4gIGZvciAoY29uc3QgW2lkLCBzdHlsZV0gb2YgT2JqZWN0LmVudHJpZXMobmV3U3R5bGVzKSkge1xuICAgIHN0eWxlcy5zZXQoaWQsIHN0eWxlKTtcbiAgICBpZiAoc3R5bGUuc3R5bGVzaGVldCkge1xuICAgICAgc3R5bGVzaGVldCArPSBzdHlsZS5zdHlsZXNoZWV0ICsgXCJcXG5cIjtcbiAgICB9XG4gIH1cblxuICBpZiAoc3R5bGVzaGVldCkge1xuICAgIGxldCBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG4gICAgc3R5bGVFbGVtZW50LmlubmVySFRNTCA9IHN0eWxlc2hlZXQ7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIERlY29yYXRpb25Hcm91cCBmb3IgdGhlIGdpdmVuIGdyb3VwIG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWNvcmF0aW9ucyhncm91cE5hbWUpIHtcbiAgdmFyIGdyb3VwID0gZ3JvdXBzLmdldChncm91cE5hbWUpO1xuICBpZiAoIWdyb3VwKSB7XG4gICAgbGV0IGlkID0gXCJyMi1kZWNvcmF0aW9uLVwiICsgbGFzdEdyb3VwSWQrKztcbiAgICBncm91cCA9IERlY29yYXRpb25Hcm91cChpZCwgZ3JvdXBOYW1lKTtcbiAgICBncm91cHMuc2V0KGdyb3VwTmFtZSwgZ3JvdXApO1xuICB9XG4gIHJldHVybiBncm91cDtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGNsaWNrIGV2ZW50cyBvbiBhIERlY29yYXRpb24uXG4gKiBSZXR1cm5zIHdoZXRoZXIgYSBkZWNvcmF0aW9uIG1hdGNoZWQgdGhpcyBldmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50KGV2ZW50LCBjbGlja0V2ZW50KSB7XG4gIGlmIChncm91cHMuc2l6ZSA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbmRUYXJnZXQoKSB7XG4gICAgZm9yIChjb25zdCBbZ3JvdXAsIGdyb3VwQ29udGVudF0gb2YgZ3JvdXBzKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZ3JvdXBDb250ZW50Lml0ZW1zLnJldmVyc2UoKSkge1xuICAgICAgICBpZiAoIWl0ZW0uY2xpY2thYmxlRWxlbWVudHMpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgaXRlbS5jbGlja2FibGVFbGVtZW50cykge1xuICAgICAgICAgIGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b0pTT04oKTtcbiAgICAgICAgICBpZiAocmVjdENvbnRhaW5zUG9pbnQocmVjdCwgZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgMSkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGdyb3VwLCBpdGVtLCBlbGVtZW50LCByZWN0IH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHRhcmdldCA9IGZpbmRUYXJnZXQoKTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gQW5kcm9pZC5vbkRlY29yYXRpb25BY3RpdmF0ZWQoXG4gICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgaWQ6IHRhcmdldC5pdGVtLmRlY29yYXRpb24uaWQsXG4gICAgICBncm91cDogdGFyZ2V0Lmdyb3VwLFxuICAgICAgcmVjdDogdG9OYXRpdmVSZWN0KHRhcmdldC5pdGVtLnJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxcbiAgICAgIGNsaWNrOiBjbGlja0V2ZW50LFxuICAgIH0pXG4gICk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIERlY29yYXRpb25Hcm91cCBvYmplY3QgZnJvbSBhIHVuaXF1ZSBIVE1MIElEIGFuZCBpdHMgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIERlY29yYXRpb25Hcm91cChncm91cElkLCBncm91cE5hbWUpIHtcbiAgdmFyIGl0ZW1zID0gW107XG4gIHZhciBsYXN0SXRlbUlkID0gMDtcbiAgdmFyIGNvbnRhaW5lciA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBuZXcgZGVjb3JhdGlvbiB0byB0aGUgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiBhZGQoZGVjb3JhdGlvbikge1xuICAgIGxldCBpZCA9IGdyb3VwSWQgKyBcIi1cIiArIGxhc3RJdGVtSWQrKztcblxuICAgIGxldCByYW5nZSA9IHJhbmdlRnJvbUxvY2F0b3IoZGVjb3JhdGlvbi5sb2NhdG9yKTtcbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICBsb2coXCJDYW4ndCBsb2NhdGUgRE9NIHJhbmdlIGZvciBkZWNvcmF0aW9uXCIsIGRlY29yYXRpb24pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtID0geyBpZCwgZGVjb3JhdGlvbiwgcmFuZ2UgfTtcbiAgICBpdGVtcy5wdXNoKGl0ZW0pO1xuICAgIGxheW91dChpdGVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBkZWNvcmF0aW9uIHdpdGggZ2l2ZW4gSUQgZnJvbSB0aGUgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiByZW1vdmUoZGVjb3JhdGlvbklkKSB7XG4gICAgbGV0IGluZGV4ID0gaXRlbXMuZmluZEluZGV4KChpKSA9PiBpLmRlY29yYXRpb24uaWQgPT09IGRlY29yYXRpb25JZCk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtID0gaXRlbXNbaW5kZXhdO1xuICAgIGl0ZW1zLnNwbGljZShpbmRleCwgMSk7XG4gICAgaXRlbS5jbGlja2FibGVFbGVtZW50cyA9IG51bGw7XG4gICAgaWYgKGl0ZW0uY29udGFpbmVyKSB7XG4gICAgICBpdGVtLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGl0ZW0uY29udGFpbmVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTm90aWZpZXMgdGhhdCB0aGUgZ2l2ZW4gZGVjb3JhdGlvbiB3YXMgbW9kaWZpZWQgYW5kIG5lZWRzIHRvIGJlIHVwZGF0ZWQuXG4gICAqL1xuICBmdW5jdGlvbiB1cGRhdGUoZGVjb3JhdGlvbikge1xuICAgIHJlbW92ZShkZWNvcmF0aW9uLmlkKTtcbiAgICBhZGQoZGVjb3JhdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgZGVjb3JhdGlvbnMgZnJvbSB0aGlzIGdyb3VwLlxuICAgKi9cbiAgZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgY2xlYXJDb250YWluZXIoKTtcbiAgICBpdGVtcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY3JlYXRlcyB0aGUgZGVjb3JhdGlvbiBlbGVtZW50cy5cbiAgICpcbiAgICogVG8gYmUgY2FsbGVkIGFmdGVyIHJlZmxvd2luZyB0aGUgcmVzb3VyY2UsIGZvciBleGFtcGxlLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVxdWVzdExheW91dCgpIHtcbiAgICBjbGVhckNvbnRhaW5lcigpO1xuICAgIGl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IGxheW91dChpdGVtKSk7XG4gIH1cblxuICAvKipcbiAgICogTGF5b3V0cyBhIHNpbmdsZSBEZWNvcmF0aW9uIGl0ZW0uXG4gICAqL1xuICBmdW5jdGlvbiBsYXlvdXQoaXRlbSkge1xuICAgIGxldCBncm91cENvbnRhaW5lciA9IHJlcXVpcmVDb250YWluZXIoKTtcblxuICAgIGxldCBzdHlsZSA9IHN0eWxlcy5nZXQoaXRlbS5kZWNvcmF0aW9uLnN0eWxlKTtcbiAgICBpZiAoIXN0eWxlKSB7XG4gICAgICBsb2dFcnJvcihgVW5rbm93biBkZWNvcmF0aW9uIHN0eWxlOiAke2l0ZW0uZGVjb3JhdGlvbi5zdHlsZX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgaXRlbUNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgaXRlbUNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBpdGVtLmlkKTtcbiAgICBpdGVtQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImRhdGEtc3R5bGVcIiwgaXRlbS5kZWNvcmF0aW9uLnN0eWxlKTtcbiAgICBpdGVtQ29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuXG4gICAgbGV0IHZpZXdwb3J0V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICBsZXQgY29sdW1uQ291bnQgPSBwYXJzZUludChcbiAgICAgIGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKFxuICAgICAgICBcImNvbHVtbi1jb3VudFwiXG4gICAgICApXG4gICAgKTtcbiAgICBsZXQgcGFnZVdpZHRoID0gdmlld3BvcnRXaWR0aCAvIChjb2x1bW5Db3VudCB8fCAxKTtcbiAgICBsZXQgc2Nyb2xsaW5nRWxlbWVudCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQ7XG4gICAgbGV0IHhPZmZzZXQgPSBzY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgbGV0IHlPZmZzZXQgPSBzY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcDtcblxuICAgIGZ1bmN0aW9uIHBvc2l0aW9uRWxlbWVudChlbGVtZW50LCByZWN0LCBib3VuZGluZ1JlY3QpIHtcbiAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG5cbiAgICAgIGlmIChzdHlsZS53aWR0aCA9PT0gXCJ3cmFwXCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke3JlY3Qud2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7cmVjdC5sZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwidmlld3BvcnRcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7dmlld3BvcnRXaWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBsZXQgbGVmdCA9IE1hdGguZmxvb3IocmVjdC5sZWZ0IC8gdmlld3BvcnRXaWR0aCkgKiB2aWV3cG9ydFdpZHRoO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtsZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwiYm91bmRzXCIpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke2JvdW5kaW5nUmVjdC53aWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtib3VuZGluZ1JlY3QubGVmdCArIHhPZmZzZXR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3JlY3QudG9wICsgeU9mZnNldH1weGA7XG4gICAgICB9IGVsc2UgaWYgKHN0eWxlLndpZHRoID09PSBcInBhZ2VcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7cGFnZVdpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGxldCBsZWZ0ID0gTWF0aC5mbG9vcihyZWN0LmxlZnQgLyBwYWdlV2lkdGgpICogcGFnZVdpZHRoO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtsZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgYm91bmRpbmdSZWN0ID0gaXRlbS5yYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGxldCBlbGVtZW50VGVtcGxhdGU7XG4gICAgdHJ5IHtcbiAgICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtcbiAgICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGl0ZW0uZGVjb3JhdGlvbi5lbGVtZW50LnRyaW0oKTtcbiAgICAgIGVsZW1lbnRUZW1wbGF0ZSA9IHRlbXBsYXRlLmNvbnRlbnQuZmlyc3RFbGVtZW50Q2hpbGQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ0Vycm9yKFxuICAgICAgICBgSW52YWxpZCBkZWNvcmF0aW9uIGVsZW1lbnQgXCIke2l0ZW0uZGVjb3JhdGlvbi5lbGVtZW50fVwiOiAke2Vycm9yLm1lc3NhZ2V9YFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc3R5bGUubGF5b3V0ID09PSBcImJveGVzXCIpIHtcbiAgICAgIGxldCBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzID0gdHJ1ZTtcbiAgICAgIGxldCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgICAgICBpdGVtLnJhbmdlLFxuICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICApO1xuXG4gICAgICBjbGllbnRSZWN0cyA9IGNsaWVudFJlY3RzLnNvcnQoKHIxLCByMikgPT4ge1xuICAgICAgICBpZiAocjEudG9wIDwgcjIudG9wKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9IGVsc2UgaWYgKHIxLnRvcCA+IHIyLnRvcCkge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZm9yIChsZXQgY2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgICAgICBjb25zdCBsaW5lID0gZWxlbWVudFRlbXBsYXRlLmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgbGluZS5zdHlsZS5zZXRQcm9wZXJ0eShcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICAgICAgcG9zaXRpb25FbGVtZW50KGxpbmUsIGNsaWVudFJlY3QsIGJvdW5kaW5nUmVjdCk7XG4gICAgICAgIGl0ZW1Db250YWluZXIuYXBwZW5kKGxpbmUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc3R5bGUubGF5b3V0ID09PSBcImJvdW5kc1wiKSB7XG4gICAgICBjb25zdCBib3VuZHMgPSBlbGVtZW50VGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgYm91bmRzLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgcG9zaXRpb25FbGVtZW50KGJvdW5kcywgYm91bmRpbmdSZWN0LCBib3VuZGluZ1JlY3QpO1xuXG4gICAgICBpdGVtQ29udGFpbmVyLmFwcGVuZChib3VuZHMpO1xuICAgIH1cblxuICAgIGdyb3VwQ29udGFpbmVyLmFwcGVuZChpdGVtQ29udGFpbmVyKTtcbiAgICBpdGVtLmNvbnRhaW5lciA9IGl0ZW1Db250YWluZXI7XG4gICAgaXRlbS5jbGlja2FibGVFbGVtZW50cyA9IEFycmF5LmZyb20oXG4gICAgICBpdGVtQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1hY3RpdmFibGU9JzEnXVwiKVxuICAgICk7XG4gICAgaWYgKGl0ZW0uY2xpY2thYmxlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gQXJyYXkuZnJvbShpdGVtQ29udGFpbmVyLmNoaWxkcmVuKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZ3JvdXAgY29udGFpbmVyIGVsZW1lbnQsIGFmdGVyIG1ha2luZyBzdXJlIGl0IGV4aXN0cy5cbiAgICovXG4gIGZ1bmN0aW9uIHJlcXVpcmVDb250YWluZXIoKSB7XG4gICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgZ3JvdXBJZCk7XG4gICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKFwiZGF0YS1ncm91cFwiLCBncm91cE5hbWUpO1xuICAgICAgY29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoY29udGFpbmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRhaW5lcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBncm91cCBjb250YWluZXIuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhckNvbnRhaW5lcigpIHtcbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIucmVtb3ZlKCk7XG4gICAgICBjb250YWluZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGFkZCwgcmVtb3ZlLCB1cGRhdGUsIGNsZWFyLCBpdGVtcywgcmVxdWVzdExheW91dCB9O1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBXaWxsIHJlbGF5b3V0IGFsbCB0aGUgZGVjb3JhdGlvbnMgd2hlbiB0aGUgZG9jdW1lbnQgYm9keSBpcyByZXNpemVkLlxuICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgIHZhciBsYXN0U2l6ZSA9IHsgd2lkdGg6IDAsIGhlaWdodDogMCB9O1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgbGFzdFNpemUud2lkdGggPT09IGJvZHkuY2xpZW50V2lkdGggJiZcbiAgICAgICAgbGFzdFNpemUuaGVpZ2h0ID09PSBib2R5LmNsaWVudEhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxhc3RTaXplID0ge1xuICAgICAgICB3aWR0aDogYm9keS5jbGllbnRXaWR0aCxcbiAgICAgICAgaGVpZ2h0OiBib2R5LmNsaWVudEhlaWdodCxcbiAgICAgIH07XG5cbiAgICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICBncm91cC5yZXF1ZXN0TGF5b3V0KCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGJvZHkpO1xuICB9LFxuICBmYWxzZVxuKTtcbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjIgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IGlzU2Nyb2xsTW9kZUVuYWJsZWQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgZ2V0Q3NzU2VsZWN0b3IgfSBmcm9tIFwiY3NzLXNlbGVjdG9yLWdlbmVyYXRvclwiO1xuXG4vLyBTZWUuIGh0dHBzOi8vZ2l0aHViLmNvbS9KYXlQYW5vei9hcmNoaXRlY3R1cmUvdHJlZS90b3VjaC1oYW5kbGluZy9taXNjL3RvdWNoLWhhbmRsaW5nXG5leHBvcnQgZnVuY3Rpb24gbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChlbGVtZW50KSB7XG4gIGlmIChlbGVtZW50ID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2YXIgaW50ZXJhY3RpdmVUYWdzID0gW1xuICAgIFwiYVwiLFxuICAgIFwiYXVkaW9cIixcbiAgICBcImJ1dHRvblwiLFxuICAgIFwiY2FudmFzXCIsXG4gICAgXCJkZXRhaWxzXCIsXG4gICAgXCJpbnB1dFwiLFxuICAgIFwibGFiZWxcIixcbiAgICBcIm9wdGlvblwiLFxuICAgIFwic2VsZWN0XCIsXG4gICAgXCJzdWJtaXRcIixcbiAgICBcInRleHRhcmVhXCIsXG4gICAgXCJ2aWRlb1wiLFxuICBdO1xuICBpZiAoaW50ZXJhY3RpdmVUYWdzLmluZGV4T2YoZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSAhPSAtMSkge1xuICAgIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgfVxuXG4gIC8vIENoZWNrcyB3aGV0aGVyIHRoZSBlbGVtZW50IGlzIGVkaXRhYmxlIGJ5IHRoZSB1c2VyLlxuICBpZiAoXG4gICAgZWxlbWVudC5oYXNBdHRyaWJ1dGUoXCJjb250ZW50ZWRpdGFibGVcIikgJiZcbiAgICBlbGVtZW50LmdldEF0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKS50b0xvd2VyQ2FzZSgpICE9IFwiZmFsc2VcIlxuICApIHtcbiAgICByZXR1cm4gZWxlbWVudC5vdXRlckhUTUw7XG4gIH1cblxuICAvLyBDaGVja3MgcGFyZW50cyByZWN1cnNpdmVseSBiZWNhdXNlIHRoZSB0b3VjaCBtaWdodCBiZSBmb3IgZXhhbXBsZSBvbiBhbiA8ZW0+IGluc2lkZSBhIDxhPi5cbiAgaWYgKGVsZW1lbnQucGFyZW50RWxlbWVudCkge1xuICAgIHJldHVybiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQucGFyZW50RWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRGaXJzdFZpc2libGVMb2NhdG9yKCkge1xuICBjb25zdCBlbGVtZW50ID0gZmluZEVsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gIHJldHVybiB7XG4gICAgaHJlZjogXCIjXCIsXG4gICAgdHlwZTogXCJhcHBsaWNhdGlvbi94aHRtbCt4bWxcIixcbiAgICBsb2NhdGlvbnM6IHtcbiAgICAgIGNzc1NlbGVjdG9yOiBnZXRDc3NTZWxlY3RvcihlbGVtZW50KSxcbiAgICB9LFxuICAgIHRleHQ6IHtcbiAgICAgIGhpZ2hsaWdodDogZWxlbWVudC50ZXh0Q29udGVudCxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBmaW5kRWxlbWVudChyb290RWxlbWVudCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJvb3RFbGVtZW50LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGQgPSByb290RWxlbWVudC5jaGlsZHJlbltpXTtcbiAgICBpZiAoIXNob3VsZElnbm9yZUVsZW1lbnQoY2hpbGQpICYmIGlzRWxlbWVudFZpc2libGUoY2hpbGQpKSB7XG4gICAgICByZXR1cm4gZmluZEVsZW1lbnQoY2hpbGQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcm9vdEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzRWxlbWVudFZpc2libGUoZWxlbWVudCkge1xuICBpZiAocmVhZGl1bS5pc0ZpeGVkTGF5b3V0KSByZXR1cm4gdHJ1ZTtcblxuICBpZiAoZWxlbWVudCA9PT0gZG9jdW1lbnQuYm9keSB8fCBlbGVtZW50ID09PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoIWRvY3VtZW50IHx8ICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgIWRvY3VtZW50LmJvZHkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgaWYgKGlzU2Nyb2xsTW9kZUVuYWJsZWQoKSkge1xuICAgIHJldHVybiByZWN0LmJvdHRvbSA+IDAgJiYgcmVjdC50b3AgPCB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHJlY3QucmlnaHQgPiAwICYmIHJlY3QubGVmdCA8IHdpbmRvdy5pbm5lcldpZHRoO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNob3VsZElnbm9yZUVsZW1lbnQoZWxlbWVudCkge1xuICBjb25zdCBlbFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgaWYgKGVsU3R5bGUpIHtcbiAgICBjb25zdCBkaXNwbGF5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiZGlzcGxheVwiKTtcbiAgICBpZiAoZGlzcGxheSAhPSBcImJsb2NrXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDYW5ub3QgYmUgcmVsaWVkIHVwb24sIGJlY2F1c2Ugd2ViIGJyb3dzZXIgZW5naW5lIHJlcG9ydHMgaW52aXNpYmxlIHdoZW4gb3V0IG9mIHZpZXcgaW5cbiAgICAvLyBzY3JvbGxlZCBjb2x1bW5zIVxuICAgIC8vIGNvbnN0IHZpc2liaWxpdHkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJ2aXNpYmlsaXR5XCIpO1xuICAgIC8vIGlmICh2aXNpYmlsaXR5ID09PSBcImhpZGRlblwiKSB7XG4gICAgLy8gICAgIHJldHVybiBmYWxzZTtcbiAgICAvLyB9XG4gICAgY29uc3Qgb3BhY2l0eSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIm9wYWNpdHlcIik7XG4gICAgaWYgKG9wYWNpdHkgPT09IFwiMFwiKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcbmltcG9ydCB7IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQgfSBmcm9tIFwiLi9kb21cIjtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIG9uQ2xpY2ssIGZhbHNlKTtcbiAgYmluZERyYWdHZXN0dXJlKGRvY3VtZW50KTtcbn0pO1xuXG5mdW5jdGlvbiBvbkNsaWNrKGV2ZW50KSB7XG4gIGlmICghd2luZG93LmdldFNlbGVjdGlvbigpLmlzQ29sbGFwc2VkKSB7XG4gICAgLy8gVGhlcmUncyBhbiBvbi1nb2luZyBzZWxlY3Rpb24sIHRoZSB0YXAgd2lsbCBkaXNtaXNzIGl0IHNvIHdlIGRvbid0IGZvcndhcmQgaXQuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgbGV0IGNsaWNrRXZlbnQgPSB7XG4gICAgZGVmYXVsdFByZXZlbnRlZDogZXZlbnQuZGVmYXVsdFByZXZlbnRlZCxcbiAgICB4OiBldmVudC5jbGllbnRYICogcGl4ZWxSYXRpbyxcbiAgICB5OiBldmVudC5jbGllbnRZICogcGl4ZWxSYXRpbyxcbiAgICB0YXJnZXRFbGVtZW50OiBldmVudC50YXJnZXQub3V0ZXJIVE1MLFxuICAgIGludGVyYWN0aXZlRWxlbWVudDogbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChldmVudC50YXJnZXQpLFxuICB9O1xuXG4gIGlmIChoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudChldmVudCwgY2xpY2tFdmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBTZW5kIHRoZSB0YXAgZGF0YSBvdmVyIHRoZSBKUyBicmlkZ2UgZXZlbiBpZiBpdCdzIGJlZW4gaGFuZGxlZCB3aXRoaW4gdGhlIHdlYiB2aWV3LCBzbyB0aGF0XG4gIC8vIGl0IGNhbiBiZSBwcmVzZXJ2ZWQgYW5kIHVzZWQgYnkgdGhlIHRvb2xraXQgaWYgbmVlZGVkLlxuICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uVGFwKEpTT04uc3RyaW5naWZ5KGNsaWNrRXZlbnQpKTtcblxuICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJpbmREcmFnR2VzdHVyZShlbGVtZW50KSB7XG4gIC8vIHBhc3NpdmU6IGZhbHNlIGlzIG5lY2Vzc2FyeSB0byBiZSBhYmxlIHRvIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IuXG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIiwgb25TdGFydCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgb25FbmQsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCBvbk1vdmUsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG5cbiAgdmFyIHN0YXRlID0gdW5kZWZpbmVkO1xuICB2YXIgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgY29uc3QgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuXG4gIGZ1bmN0aW9uIG9uU3RhcnQoZXZlbnQpIHtcbiAgICBpc1N0YXJ0aW5nRHJhZyA9IHRydWU7XG5cbiAgICBjb25zdCBzdGFydFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIGNvbnN0IHN0YXJ0WSA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUgPSB7XG4gICAgICBkZWZhdWx0UHJldmVudGVkOiBldmVudC5kZWZhdWx0UHJldmVudGVkLFxuICAgICAgc3RhcnRYOiBzdGFydFgsXG4gICAgICBzdGFydFk6IHN0YXJ0WSxcbiAgICAgIGN1cnJlbnRYOiBzdGFydFgsXG4gICAgICBjdXJyZW50WTogc3RhcnRZLFxuICAgICAgb2Zmc2V0WDogMCxcbiAgICAgIG9mZnNldFk6IDAsXG4gICAgICBpbnRlcmFjdGl2ZUVsZW1lbnQ6IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSxcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gb25Nb3ZlKGV2ZW50KSB7XG4gICAgaWYgKCFzdGF0ZSkgcmV0dXJuO1xuXG4gICAgc3RhdGUuY3VycmVudFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlLmN1cnJlbnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZS5vZmZzZXRYID0gc3RhdGUuY3VycmVudFggLSBzdGF0ZS5zdGFydFg7XG4gICAgc3RhdGUub2Zmc2V0WSA9IHN0YXRlLmN1cnJlbnRZIC0gc3RhdGUuc3RhcnRZO1xuXG4gICAgdmFyIHNob3VsZFByZXZlbnREZWZhdWx0ID0gZmFsc2U7XG4gICAgLy8gV2FpdCBmb3IgYSBtb3ZlbWVudCBvZiBhdCBsZWFzdCA2IHBpeGVscyBiZWZvcmUgcmVwb3J0aW5nIGEgZHJhZy5cbiAgICBpZiAoaXNTdGFydGluZ0RyYWcpIHtcbiAgICAgIGlmIChNYXRoLmFicyhzdGF0ZS5vZmZzZXRYKSA+PSA2IHx8IE1hdGguYWJzKHN0YXRlLm9mZnNldFkpID49IDYpIHtcbiAgICAgICAgaXNTdGFydGluZ0RyYWcgPSBmYWxzZTtcbiAgICAgICAgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ1N0YXJ0KEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdNb3ZlKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25FbmQoZXZlbnQpIHtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG5cbiAgICBjb25zdCBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnRW5kKEpTT04uc3RyaW5naWZ5KHN0YXRlKSk7XG4gICAgaWYgKHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHN0YXRlID0gdW5kZWZpbmVkO1xuICB9XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIzIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50IH0gZnJvbSBcIi4vZG9tXCI7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCAoZXZlbnQpID0+IHtcbiAgaWYgKHNob3VsZElnbm9yZUV2ZW50KGV2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcbiAgc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgXCJkb3duXCIpO1xufSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5dXBcIiwgKGV2ZW50KSA9PiB7XG4gIGlmIChzaG91bGRJZ25vcmVFdmVudChldmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwcmV2ZW50RGVmYXVsdChldmVudCk7XG4gIHNlbmRQcmVzc0tleU1lc3NhZ2UoZXZlbnQsIFwidXBcIik7XG59KTtcblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlRXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIChcbiAgICBldmVudC5kZWZhdWx0UHJldmVudGVkIHx8XG4gICAgbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChkb2N1bWVudC5hY3RpdmVFbGVtZW50KSAhPSBudWxsXG4gICk7XG59XG5cbi8vIFdlIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIGtleWJvYXJkIGV2ZW50cywgb3RoZXJ3aXNlIHRoZSB3ZWIgdmlld1xuLy8gbWlnaHQgc2Nyb2xsLlxuZnVuY3Rpb24gcHJldmVudERlZmF1bHQoZXZlbnQpIHtcbiAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59XG5cbmZ1bmN0aW9uIHNlbmRQcmVzc0tleU1lc3NhZ2UoZXZlbnQsIHR5cGUpIHtcbiAgaWYgKGV2ZW50LnJlcGVhdCkgcmV0dXJuO1xuXG4gIGxldCBrZXlFdmVudCA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGNvZGU6IGV2ZW50LmNvZGUsXG4gICAgY2hhcmFjdGVyczogU3RyaW5nLmZyb21DaGFyQ29kZShldmVudC5rZXlDb2RlKSxcbiAgICBhbHQ6IGV2ZW50LmFsdEtleSxcbiAgICBjb250cm9sOiBldmVudC5jdHJsS2V5LFxuICAgIHNoaWZ0OiBldmVudC5zaGlmdEtleSxcbiAgICBtZXRhOiBldmVudC5tZXRhS2V5LFxuICB9O1xuXG4gIEFuZHJvaWQub25LZXkoSlNPTi5zdHJpbmdpZnkoa2V5RXZlbnQpKTtcbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IGxvZyBhcyBsb2dOYXRpdmUsIGxvZ0Vycm9yLCBzbmFwQ3VycmVudE9mZnNldCB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyB0b05hdGl2ZVJlY3QgfSBmcm9tIFwiLi9yZWN0XCI7XG5pbXBvcnQgeyBUZXh0UmFuZ2UgfSBmcm9tIFwiLi92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZVwiO1xuXG4vLyBQb2x5ZmlsbCBmb3IgQW5kcm9pZCBBUEkgMjZcbmltcG9ydCBtYXRjaEFsbCBmcm9tIFwic3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbFwiO1xubWF0Y2hBbGwuc2hpbSgpO1xuXG5jb25zdCBkZWJ1ZyA9IHRydWU7XG5cbi8vIE5vdGlmeSBuYXRpdmUgY29kZSB0aGF0IHRoZSBzZWxlY3Rpb24gY2hhbmdlcy5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIHZhciBpc1NlbGVjdGluZyA9IGZhbHNlO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzZWxlY3Rpb25jaGFuZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29sbGFwc2VkID0gd2luZG93LmdldFNlbGVjdGlvbigpLmlzQ29sbGFwc2VkO1xuXG4gICAgICBpZiAoY29sbGFwc2VkICYmIGlzU2VsZWN0aW5nKSB7XG4gICAgICAgIGlzU2VsZWN0aW5nID0gZmFsc2U7XG4gICAgICAgIEFuZHJvaWQub25TZWxlY3Rpb25FbmQoKTtcbiAgICAgICAgLy8gU25hcHMgdGhlIGN1cnJlbnQgY29sdW1uIGluIGNhc2UgdGhlIHVzZXIgc2hpZnRlZCB0aGUgc2Nyb2xsIGJ5IGRyYWdnaW5nIHRoZSB0ZXh0IHNlbGVjdGlvbi5cbiAgICAgICAgc25hcEN1cnJlbnRPZmZzZXQoKTtcbiAgICAgIH0gZWxzZSBpZiAoIWNvbGxhcHNlZCAmJiAhaXNTZWxlY3RpbmcpIHtcbiAgICAgICAgaXNTZWxlY3RpbmcgPSB0cnVlO1xuICAgICAgICBBbmRyb2lkLm9uU2VsZWN0aW9uU3RhcnQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDdXJyZW50U2VsZWN0aW9uKCkge1xuICBjb25zdCB0ZXh0ID0gZ2V0Q3VycmVudFNlbGVjdGlvblRleHQoKTtcbiAgaWYgKCF0ZXh0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3QgcmVjdCA9IGdldFNlbGVjdGlvblJlY3QoKTtcbiAgcmV0dXJuIHsgdGV4dCwgcmVjdCB9O1xufVxuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb25SZWN0KCkge1xuICB0cnkge1xuICAgIGxldCBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCk7XG5cbiAgICByZXR1cm4gdG9OYXRpdmVSZWN0KHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ0Vycm9yKGUpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb25UZXh0KCkge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmICghc2VsZWN0aW9uKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBoaWdobGlnaHQgPSBzZWxlY3Rpb24udG9TdHJpbmcoKTtcbiAgY29uc3QgY2xlYW5IaWdobGlnaHQgPSBoaWdobGlnaHRcbiAgICAudHJpbSgpXG4gICAgLnJlcGxhY2UoL1xcbi9nLCBcIiBcIilcbiAgICAucmVwbGFjZSgvXFxzXFxzKy9nLCBcIiBcIik7XG4gIGlmIChjbGVhbkhpZ2hsaWdodC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmICghc2VsZWN0aW9uLmFuY2hvck5vZGUgfHwgIXNlbGVjdGlvbi5mb2N1c05vZGUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJhbmdlID1cbiAgICBzZWxlY3Rpb24ucmFuZ2VDb3VudCA9PT0gMVxuICAgICAgPyBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKVxuICAgICAgOiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck5vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c09mZnNldFxuICAgICAgICApO1xuICBpZiAoIXJhbmdlIHx8IHJhbmdlLmNvbGxhcHNlZCkge1xuICAgIGxvZyhcIiQkJCQkJCQkJCQkJCQkJCQkIENBTk5PVCBHRVQgTk9OLUNPTExBUFNFRCBTRUxFQ1RJT04gUkFOR0U/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmJvZHkudGV4dENvbnRlbnQ7XG4gIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2UocmFuZ2UpLnJlbGF0aXZlVG8oZG9jdW1lbnQuYm9keSk7XG4gIGNvbnN0IHN0YXJ0ID0gdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldDtcbiAgY29uc3QgZW5kID0gdGV4dFJhbmdlLmVuZC5vZmZzZXQ7XG5cbiAgY29uc3Qgc25pcHBldExlbmd0aCA9IDIwMDtcblxuICAvLyBDb21wdXRlIHRoZSB0ZXh0IGJlZm9yZSB0aGUgaGlnaGxpZ2h0LCBpZ25vcmluZyB0aGUgZmlyc3QgXCJ3b3JkXCIsIHdoaWNoIG1pZ2h0IGJlIGN1dC5cbiAgbGV0IGJlZm9yZSA9IHRleHQuc2xpY2UoTWF0aC5tYXgoMCwgc3RhcnQgLSBzbmlwcGV0TGVuZ3RoKSwgc3RhcnQpO1xuICBsZXQgZmlyc3RXb3JkU3RhcnQgPSBiZWZvcmUuc2VhcmNoKC9cXFB7TH1cXHB7TH0vZ3UpO1xuICBpZiAoZmlyc3RXb3JkU3RhcnQgIT09IC0xKSB7XG4gICAgYmVmb3JlID0gYmVmb3JlLnNsaWNlKGZpcnN0V29yZFN0YXJ0ICsgMSk7XG4gIH1cblxuICAvLyBDb21wdXRlIHRoZSB0ZXh0IGFmdGVyIHRoZSBoaWdobGlnaHQsIGlnbm9yaW5nIHRoZSBsYXN0IFwid29yZFwiLCB3aGljaCBtaWdodCBiZSBjdXQuXG4gIGxldCBhZnRlciA9IHRleHQuc2xpY2UoZW5kLCBNYXRoLm1pbih0ZXh0Lmxlbmd0aCwgZW5kICsgc25pcHBldExlbmd0aCkpO1xuICBsZXQgbGFzdFdvcmRFbmQgPSBBcnJheS5mcm9tKGFmdGVyLm1hdGNoQWxsKC9cXHB7TH1cXFB7TH0vZ3UpKS5wb3AoKTtcbiAgaWYgKGxhc3RXb3JkRW5kICE9PSB1bmRlZmluZWQgJiYgbGFzdFdvcmRFbmQuaW5kZXggPiAxKSB7XG4gICAgYWZ0ZXIgPSBhZnRlci5zbGljZSgwLCBsYXN0V29yZEVuZC5pbmRleCArIDEpO1xuICB9XG5cbiAgcmV0dXJuIHsgaGlnaGxpZ2h0LCBiZWZvcmUsIGFmdGVyIH07XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9yZGVyZWRSYW5nZShzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0LCBlbmROb2RlLCBlbmRPZmZzZXQpIHtcbiAgY29uc3QgcmFuZ2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIHJhbmdlLnNldEVuZChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICBpZiAoIXJhbmdlLmNvbGxhcHNlZCkge1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIENPTExBUFNFRCAuLi4gUkFOR0UgUkVWRVJTRT9cIik7XG4gIGNvbnN0IHJhbmdlUmV2ZXJzZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZVJldmVyc2Uuc2V0U3RhcnQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgcmFuZ2VSZXZlcnNlLnNldEVuZChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgaWYgKCFyYW5nZVJldmVyc2UuY29sbGFwc2VkKSB7XG4gICAgbG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIE9LLlwiKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgbG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBSQU5HRSBSRVZFUlNFIEFMU08gQ09MTEFQU0VEPyFcIik7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCByYW5nZUluZm8pIHtcbiAgY29uc3Qgc3RhcnRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFzdGFydEVsZW1lbnQpIHtcbiAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBTVEFSVCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IHN0YXJ0Q29udGFpbmVyID0gc3RhcnRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgbG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBzdGFydEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgc3RhcnRDb250YWluZXIgPVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4XTtcbiAgICBpZiAoc3RhcnRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIGNvbnN0IGVuZEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFlbmRFbGVtZW50KSB7XG4gICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gRU5EIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgZW5kQ29udGFpbmVyID0gZW5kRWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgbG9nKFxuICAgICAgICBcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHJhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gZW5kRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBlbmRDb250YWluZXIgPVxuICAgICAgZW5kRWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChlbmRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBlbmRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFPyFcIik7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5zdGFydE9mZnNldCxcbiAgICBlbmRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLmVuZE9mZnNldFxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9jYXRpb24yUmFuZ2VJbmZvKGxvY2F0aW9uKSB7XG4gIGNvbnN0IGxvY2F0aW9ucyA9IGxvY2F0aW9uLmxvY2F0aW9ucztcbiAgY29uc3QgZG9tUmFuZ2UgPSBsb2NhdGlvbnMuZG9tUmFuZ2U7XG4gIGNvbnN0IHN0YXJ0ID0gZG9tUmFuZ2Uuc3RhcnQ7XG4gIGNvbnN0IGVuZCA9IGRvbVJhbmdlLmVuZDtcblxuICByZXR1cm4ge1xuICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogZW5kLnRleHROb2RlSW5kZXgsXG4gICAgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBlbmQuY3NzU2VsZWN0b3IsXG4gICAgZW5kT2Zmc2V0OiBlbmQub2Zmc2V0LFxuICAgIHN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBzdGFydC50ZXh0Tm9kZUluZGV4LFxuICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yOiBzdGFydC5jc3NTZWxlY3RvcixcbiAgICBzdGFydE9mZnNldDogc3RhcnQub2Zmc2V0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBsb2coKSB7XG4gIGlmIChkZWJ1Zykge1xuICAgIGxvZ05hdGl2ZS5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICB9XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG4vLyBCYXNlIHNjcmlwdCB1c2VkIGJ5IGJvdGggcmVmbG93YWJsZSBhbmQgZml4ZWQgbGF5b3V0IHJlc291cmNlcy5cblxuaW1wb3J0IFwiLi9nZXN0dXJlc1wiO1xuaW1wb3J0IFwiLi9rZXlib2FyZFwiO1xuaW1wb3J0IHtcbiAgcmVtb3ZlUHJvcGVydHksXG4gIHNjcm9sbExlZnQsXG4gIHNjcm9sbFJpZ2h0LFxuICBzY3JvbGxUb0VuZCxcbiAgc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9Qb3NpdGlvbixcbiAgc2Nyb2xsVG9TdGFydCxcbiAgc2Nyb2xsVG9UZXh0LFxuICBzZXRQcm9wZXJ0eSxcbiAgc2V0Q1NTUHJvcGVydGllcyxcbn0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yIH0gZnJvbSBcIi4vZG9tXCI7XG5pbXBvcnQgeyBnZXRDdXJyZW50U2VsZWN0aW9uIH0gZnJvbSBcIi4vc2VsZWN0aW9uXCI7XG5pbXBvcnQgeyBnZXREZWNvcmF0aW9ucywgcmVnaXN0ZXJUZW1wbGF0ZXMgfSBmcm9tIFwiLi9kZWNvcmF0b3JcIjtcblxuLy8gUHVibGljIEFQSSB1c2VkIGJ5IHRoZSBuYXZpZ2F0b3IuXG53aW5kb3cucmVhZGl1bSA9IHtcbiAgLy8gdXRpbHNcbiAgc2Nyb2xsVG9JZDogc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9Qb3NpdGlvbjogc2Nyb2xsVG9Qb3NpdGlvbixcbiAgc2Nyb2xsVG9UZXh0OiBzY3JvbGxUb1RleHQsXG4gIHNjcm9sbExlZnQ6IHNjcm9sbExlZnQsXG4gIHNjcm9sbFJpZ2h0OiBzY3JvbGxSaWdodCxcbiAgc2Nyb2xsVG9TdGFydDogc2Nyb2xsVG9TdGFydCxcbiAgc2Nyb2xsVG9FbmQ6IHNjcm9sbFRvRW5kLFxuICBzZXRDU1NQcm9wZXJ0aWVzOiBzZXRDU1NQcm9wZXJ0aWVzLFxuICBzZXRQcm9wZXJ0eTogc2V0UHJvcGVydHksXG4gIHJlbW92ZVByb3BlcnR5OiByZW1vdmVQcm9wZXJ0eSxcblxuICAvLyBzZWxlY3Rpb25cbiAgZ2V0Q3VycmVudFNlbGVjdGlvbjogZ2V0Q3VycmVudFNlbGVjdGlvbixcblxuICAvLyBkZWNvcmF0aW9uXG4gIHJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlczogcmVnaXN0ZXJUZW1wbGF0ZXMsXG4gIGdldERlY29yYXRpb25zOiBnZXREZWNvcmF0aW9ucyxcblxuICAvLyBET01cbiAgZmluZEZpcnN0VmlzaWJsZUxvY2F0b3I6IGZpbmRGaXJzdFZpc2libGVMb2NhdG9yLFxufTtcbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIFNjcmlwdCB1c2VkIGZvciBmaXhlZCBsYXlvdXRzIHJlc291cmNlcy5cblxuaW1wb3J0IFwiLi9pbmRleFwiO1xuXG53aW5kb3cucmVhZGl1bS5pc0ZpeGVkTGF5b3V0ID0gdHJ1ZTtcbiJdLCJuYW1lcyI6WyJhcHByb3hTZWFyY2giLCJzZWFyY2giLCJ0ZXh0Iiwic3RyIiwibWF4RXJyb3JzIiwibWF0Y2hQb3MiLCJleGFjdE1hdGNoZXMiLCJpbmRleE9mIiwicHVzaCIsInN0YXJ0IiwiZW5kIiwibGVuZ3RoIiwiZXJyb3JzIiwidGV4dE1hdGNoU2NvcmUiLCJtYXRjaGVzIiwibWF0Y2hRdW90ZSIsInF1b3RlIiwiY29udGV4dCIsIk1hdGgiLCJtaW4iLCJzY29yZU1hdGNoIiwibWF0Y2giLCJxdW90ZVdlaWdodCIsInByZWZpeFdlaWdodCIsInN1ZmZpeFdlaWdodCIsInBvc1dlaWdodCIsInF1b3RlU2NvcmUiLCJwcmVmaXhTY29yZSIsInByZWZpeCIsInNsaWNlIiwibWF4Iiwic3VmZml4U2NvcmUiLCJzdWZmaXgiLCJwb3NTY29yZSIsImhpbnQiLCJvZmZzZXQiLCJhYnMiLCJyYXdTY29yZSIsIm1heFNjb3JlIiwibm9ybWFsaXplZFNjb3JlIiwic2NvcmVkTWF0Y2hlcyIsIm1hcCIsIm0iLCJzY29yZSIsInNvcnQiLCJhIiwiYiIsIm5vZGVUZXh0TGVuZ3RoIiwibm9kZSIsIm5vZGVUeXBlIiwiTm9kZSIsIkVMRU1FTlRfTk9ERSIsIlRFWFRfTk9ERSIsInRleHRDb250ZW50IiwicHJldmlvdXNTaWJsaW5nc1RleHRMZW5ndGgiLCJzaWJsaW5nIiwicHJldmlvdXNTaWJsaW5nIiwicmVzb2x2ZU9mZnNldHMiLCJlbGVtZW50Iiwib2Zmc2V0cyIsIm5leHRPZmZzZXQiLCJzaGlmdCIsIm5vZGVJdGVyIiwib3duZXJEb2N1bWVudCIsImNyZWF0ZU5vZGVJdGVyYXRvciIsIk5vZGVGaWx0ZXIiLCJTSE9XX1RFWFQiLCJyZXN1bHRzIiwiY3VycmVudE5vZGUiLCJuZXh0Tm9kZSIsInRleHROb2RlIiwidW5kZWZpbmVkIiwiZGF0YSIsIlJhbmdlRXJyb3IiLCJSRVNPTFZFX0ZPUldBUkRTIiwiUkVTT0xWRV9CQUNLV0FSRFMiLCJUZXh0UG9zaXRpb24iLCJFcnJvciIsInBhcmVudCIsImNvbnRhaW5zIiwiZWwiLCJwYXJlbnRFbGVtZW50Iiwib3B0aW9ucyIsImVyciIsImRpcmVjdGlvbiIsInR3IiwiZG9jdW1lbnQiLCJjcmVhdGVUcmVlV2Fsa2VyIiwiZ2V0Um9vdE5vZGUiLCJmb3J3YXJkcyIsInByZXZpb3VzTm9kZSIsImZyb21Qb2ludCIsInRleHRPZmZzZXQiLCJjaGlsZE5vZGVzIiwiaSIsIlRleHRSYW5nZSIsInJlbGF0aXZlVG8iLCJyZXNvbHZlIiwicmFuZ2UiLCJSYW5nZSIsInNldFN0YXJ0Iiwic2V0RW5kIiwic3RhcnRDb250YWluZXIiLCJzdGFydE9mZnNldCIsImVuZENvbnRhaW5lciIsImVuZE9mZnNldCIsInJvb3QiLCJub2RlRnJvbVhQYXRoIiwieHBhdGhGcm9tTm9kZSIsIlJhbmdlQW5jaG9yIiwibm9ybWFsaXplZFJhbmdlIiwiZnJvbVJhbmdlIiwidG9SYW5nZSIsInRleHRSYW5nZSIsInR5cGUiLCJzZWxlY3RvciIsInN0YXJ0UG9zIiwiZnJvbUNoYXJPZmZzZXQiLCJlbmRQb3MiLCJUZXh0UG9zaXRpb25BbmNob3IiLCJmcm9tT2Zmc2V0cyIsIlRleHRRdW90ZUFuY2hvciIsImV4YWN0IiwidG9Qb3NpdGlvbkFuY2hvciIsImNvbnRleHRMZW4iLCJ3aW5kb3ciLCJhZGRFdmVudExpc3RlbmVyIiwiZXZlbnQiLCJBbmRyb2lkIiwibG9nRXJyb3IiLCJtZXNzYWdlIiwiZmlsZW5hbWUiLCJsaW5lbm8iLCJvYnNlcnZlciIsIlJlc2l6ZU9ic2VydmVyIiwib25WaWV3cG9ydFdpZHRoQ2hhbmdlZCIsInNuYXBDdXJyZW50T2Zmc2V0Iiwib2JzZXJ2ZSIsImJvZHkiLCJhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQiLCJpZCIsInZpcnR1YWxDb2wiLCJnZXRFbGVtZW50QnlJZCIsImlzU2Nyb2xsTW9kZUVuYWJsZWQiLCJnZXRDb2x1bW5Db3VudFBlclNjcmVlbiIsInJlbW92ZSIsImRvY3VtZW50V2lkdGgiLCJzY3JvbGxpbmdFbGVtZW50Iiwic2Nyb2xsV2lkdGgiLCJjb2xDb3VudCIsInBhZ2VXaWR0aCIsImhhc09kZENvbENvdW50Iiwicm91bmQiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwic3R5bGUiLCJicmVha0JlZm9yZSIsImlubmVySFRNTCIsImFwcGVuZENoaWxkIiwid2lkdGgiLCJnZXRWaWV3cG9ydFdpZHRoIiwiZGV2aWNlUGl4ZWxSYXRpbyIsInNldFByb3BlcnR5IiwicGFyc2VJbnQiLCJnZXRDb21wdXRlZFN0eWxlIiwiZG9jdW1lbnRFbGVtZW50IiwiZ2V0UHJvcGVydHlWYWx1ZSIsInRyaW0iLCJpc1JUTCIsImRpciIsInRvTG93ZXJDYXNlIiwic2Nyb2xsVG9JZCIsInNjcm9sbFRvUmVjdCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInNjcm9sbFRvUG9zaXRpb24iLCJwb3NpdGlvbiIsInNjcm9sbEhlaWdodCIsInNjcm9sbFRvcCIsImZhY3RvciIsInNjcm9sbExlZnQiLCJzbmFwT2Zmc2V0Iiwic2Nyb2xsVG9UZXh0IiwicmFuZ2VGcm9tTG9jYXRvciIsInNjcm9sbFRvUmFuZ2UiLCJyZWN0IiwidG9wIiwic2Nyb2xsWSIsImlubmVySGVpZ2h0IiwibGVmdCIsInNjcm9sbFgiLCJzY3JvbGxUb1N0YXJ0Iiwic2Nyb2xsVG8iLCJzY3JvbGxUb0VuZCIsIm1pbk9mZnNldCIsInNjcm9sbFRvT2Zmc2V0Iiwic2Nyb2xsUmlnaHQiLCJtYXhPZmZzZXQiLCJjdXJyZW50T2Zmc2V0IiwiZGlmZiIsInZhbHVlIiwiZGVsdGEiLCJsb2NhdG9yIiwibG9jYXRpb25zIiwiaGlnaGxpZ2h0IiwiY3NzU2VsZWN0b3IiLCJxdWVyeVNlbGVjdG9yIiwiYW5jaG9yIiwiYmVmb3JlIiwiYWZ0ZXIiLCJmcmFnbWVudHMiLCJodG1sSWQiLCJjcmVhdGVSYW5nZSIsInNldFN0YXJ0QmVmb3JlIiwic2V0RW5kQWZ0ZXIiLCJlIiwic2V0Q1NTUHJvcGVydGllcyIsInByb3BlcnRpZXMiLCJuYW1lIiwia2V5IiwicmVtb3ZlUHJvcGVydHkiLCJsb2ciLCJBcnJheSIsInByb3RvdHlwZSIsImNhbGwiLCJhcmd1bWVudHMiLCJqb2luIiwibG9nTmF0aXZlIiwiZGVidWciLCJ0b05hdGl2ZVJlY3QiLCJwaXhlbFJhdGlvIiwiaGVpZ2h0IiwicmlnaHQiLCJib3R0b20iLCJnZXRDbGllbnRSZWN0c05vT3ZlcmxhcCIsImRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMiLCJjbGllbnRSZWN0cyIsImdldENsaWVudFJlY3RzIiwidG9sZXJhbmNlIiwib3JpZ2luYWxSZWN0cyIsInJhbmdlQ2xpZW50UmVjdCIsIm1lcmdlZFJlY3RzIiwibWVyZ2VUb3VjaGluZ1JlY3RzIiwibm9Db250YWluZWRSZWN0cyIsInJlbW92ZUNvbnRhaW5lZFJlY3RzIiwibmV3UmVjdHMiLCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIiwibWluQXJlYSIsImoiLCJiaWdFbm91Z2giLCJzcGxpY2UiLCJyZWN0cyIsInJlY3QxIiwicmVjdDIiLCJyZWN0c0xpbmVVcFZlcnRpY2FsbHkiLCJhbG1vc3RFcXVhbCIsInJlY3RzTGluZVVwSG9yaXpvbnRhbGx5IiwiaG9yaXpvbnRhbEFsbG93ZWQiLCJhbGlnbmVkIiwiY2FuTWVyZ2UiLCJyZWN0c1RvdWNoT3JPdmVybGFwIiwiZmlsdGVyIiwicmVwbGFjZW1lbnRDbGllbnRSZWN0IiwiZ2V0Qm91bmRpbmdSZWN0IiwicmVjdHNUb0tlZXAiLCJTZXQiLCJkZWxldGUiLCJwb3NzaWJseUNvbnRhaW5pbmdSZWN0IiwiaGFzIiwicmVjdENvbnRhaW5zIiwiZnJvbSIsInJlY3RDb250YWluc1BvaW50IiwieCIsInkiLCJ0b0FkZCIsInRvUmVtb3ZlIiwic3VidHJhY3RSZWN0czEiLCJyZWN0U3VidHJhY3QiLCJzdWJ0cmFjdFJlY3RzMiIsImFwcGx5IiwicmVjdEludGVyc2VjdGVkIiwicmVjdEludGVyc2VjdCIsInJlY3RBIiwicmVjdEIiLCJyZWN0QyIsInJlY3REIiwibWF4TGVmdCIsIm1pblJpZ2h0IiwibWF4VG9wIiwibWluQm90dG9tIiwic3R5bGVzIiwiTWFwIiwiZ3JvdXBzIiwibGFzdEdyb3VwSWQiLCJyZWdpc3RlclRlbXBsYXRlcyIsIm5ld1N0eWxlcyIsInN0eWxlc2hlZXQiLCJPYmplY3QiLCJlbnRyaWVzIiwic2V0Iiwic3R5bGVFbGVtZW50IiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJnZXREZWNvcmF0aW9ucyIsImdyb3VwTmFtZSIsImdyb3VwIiwiZ2V0IiwiRGVjb3JhdGlvbkdyb3VwIiwiaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQiLCJjbGlja0V2ZW50Iiwic2l6ZSIsImZpbmRUYXJnZXQiLCJncm91cENvbnRlbnQiLCJpdGVtcyIsInJldmVyc2UiLCJpdGVtIiwiY2xpY2thYmxlRWxlbWVudHMiLCJ0b0pTT04iLCJjbGllbnRYIiwiY2xpZW50WSIsInRhcmdldCIsIm9uRGVjb3JhdGlvbkFjdGl2YXRlZCIsIkpTT04iLCJzdHJpbmdpZnkiLCJkZWNvcmF0aW9uIiwiY2xpY2siLCJncm91cElkIiwibGFzdEl0ZW1JZCIsImNvbnRhaW5lciIsImFkZCIsImxheW91dCIsImRlY29yYXRpb25JZCIsImluZGV4IiwiZmluZEluZGV4IiwidXBkYXRlIiwiY2xlYXIiLCJjbGVhckNvbnRhaW5lciIsInJlcXVlc3RMYXlvdXQiLCJmb3JFYWNoIiwiZ3JvdXBDb250YWluZXIiLCJyZXF1aXJlQ29udGFpbmVyIiwiaXRlbUNvbnRhaW5lciIsInZpZXdwb3J0V2lkdGgiLCJpbm5lcldpZHRoIiwiY29sdW1uQ291bnQiLCJ4T2Zmc2V0IiwieU9mZnNldCIsInBvc2l0aW9uRWxlbWVudCIsImJvdW5kaW5nUmVjdCIsImZsb29yIiwiZWxlbWVudFRlbXBsYXRlIiwidGVtcGxhdGUiLCJjb250ZW50IiwiZmlyc3RFbGVtZW50Q2hpbGQiLCJlcnJvciIsInIxIiwicjIiLCJjbGllbnRSZWN0IiwibGluZSIsImNsb25lTm9kZSIsImFwcGVuZCIsImJvdW5kcyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJjaGlsZHJlbiIsImxhc3RTaXplIiwiY2xpZW50V2lkdGgiLCJjbGllbnRIZWlnaHQiLCJnZXRDc3NTZWxlY3RvciIsIm5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQiLCJpbnRlcmFjdGl2ZVRhZ3MiLCJub2RlTmFtZSIsIm91dGVySFRNTCIsImhhc0F0dHJpYnV0ZSIsImdldEF0dHJpYnV0ZSIsImZpbmRGaXJzdFZpc2libGVMb2NhdG9yIiwiZmluZEVsZW1lbnQiLCJocmVmIiwicm9vdEVsZW1lbnQiLCJjaGlsZCIsInNob3VsZElnbm9yZUVsZW1lbnQiLCJpc0VsZW1lbnRWaXNpYmxlIiwicmVhZGl1bSIsImlzRml4ZWRMYXlvdXQiLCJlbFN0eWxlIiwiZGlzcGxheSIsIm9wYWNpdHkiLCJvbkNsaWNrIiwiYmluZERyYWdHZXN0dXJlIiwiZ2V0U2VsZWN0aW9uIiwiaXNDb2xsYXBzZWQiLCJkZWZhdWx0UHJldmVudGVkIiwidGFyZ2V0RWxlbWVudCIsImludGVyYWN0aXZlRWxlbWVudCIsInNob3VsZFByZXZlbnREZWZhdWx0Iiwib25UYXAiLCJzdG9wUHJvcGFnYXRpb24iLCJwcmV2ZW50RGVmYXVsdCIsIm9uU3RhcnQiLCJwYXNzaXZlIiwib25FbmQiLCJvbk1vdmUiLCJzdGF0ZSIsImlzU3RhcnRpbmdEcmFnIiwic3RhcnRYIiwidG91Y2hlcyIsInN0YXJ0WSIsImN1cnJlbnRYIiwiY3VycmVudFkiLCJvZmZzZXRYIiwib2Zmc2V0WSIsIm9uRHJhZ1N0YXJ0Iiwib25EcmFnTW92ZSIsIm9uRHJhZ0VuZCIsInNob3VsZElnbm9yZUV2ZW50Iiwic2VuZFByZXNzS2V5TWVzc2FnZSIsImFjdGl2ZUVsZW1lbnQiLCJyZXBlYXQiLCJrZXlFdmVudCIsImNvZGUiLCJjaGFyYWN0ZXJzIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwia2V5Q29kZSIsImFsdCIsImFsdEtleSIsImNvbnRyb2wiLCJjdHJsS2V5Iiwic2hpZnRLZXkiLCJtZXRhIiwibWV0YUtleSIsIm9uS2V5IiwibWF0Y2hBbGwiLCJzaGltIiwiaXNTZWxlY3RpbmciLCJjb2xsYXBzZWQiLCJvblNlbGVjdGlvbkVuZCIsIm9uU2VsZWN0aW9uU3RhcnQiLCJnZXRDdXJyZW50U2VsZWN0aW9uIiwiZ2V0Q3VycmVudFNlbGVjdGlvblRleHQiLCJnZXRTZWxlY3Rpb25SZWN0Iiwic2VsIiwiZ2V0UmFuZ2VBdCIsInNlbGVjdGlvbiIsInRvU3RyaW5nIiwiY2xlYW5IaWdobGlnaHQiLCJyZXBsYWNlIiwiYW5jaG9yTm9kZSIsImZvY3VzTm9kZSIsInJhbmdlQ291bnQiLCJjcmVhdGVPcmRlcmVkUmFuZ2UiLCJhbmNob3JPZmZzZXQiLCJmb2N1c09mZnNldCIsInNuaXBwZXRMZW5ndGgiLCJmaXJzdFdvcmRTdGFydCIsImxhc3RXb3JkRW5kIiwicG9wIiwic3RhcnROb2RlIiwiZW5kTm9kZSIsInJhbmdlUmV2ZXJzZSIsImNvbnZlcnRSYW5nZUluZm8iLCJyYW5nZUluZm8iLCJzdGFydEVsZW1lbnQiLCJzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciIsInN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IiwiZW5kRWxlbWVudCIsImVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciIsImVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCIsImxvY2F0aW9uMlJhbmdlSW5mbyIsImxvY2F0aW9uIiwiZG9tUmFuZ2UiLCJ0ZXh0Tm9kZUluZGV4IiwicmVnaXN0ZXJEZWNvcmF0aW9uVGVtcGxhdGVzIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5298\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjEwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsOENBQThDO0FBQ2hGLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1YsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUEsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEMsdURBQXVELHVCQUF1Qjs7QUFFOUU7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRCxHQUFHO0FBQ0gsZ0RBQWdEO0FBQ2hELEdBQUc7QUFDSCxzREFBc0Q7QUFDdEQsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFdBQVcsbUJBQU8sQ0FBQyxJQUFlO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFLO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0Isa0JBQWtCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz81OWY4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz8zNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/MWJmMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzP2I4OGUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NmRiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/ZmI1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz9mMGYzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/YjMwZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz82OTY3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzP2E4ZjciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz83NzYwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/Yjg2MiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzc0OWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz9hYTJiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82ZGMxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz83ZmY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZDJhYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzPzYwOGYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzPzY5NDciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz83YTkyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz80NTY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YjY2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzP2FhYTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz9lZDA1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz9mMTM2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZWVlNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz84MTA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzPzdmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz8zNTA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz9iYTg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz9jZGZlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz8zNGI3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzkxOWUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9jZjY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz8wZjA5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/ZTQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz8zMmFlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzJjNTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/ZThjZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/M2Q3NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9jNmVmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/MGFlMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/MmI4ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/NzczNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzPzViNGEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzPzY4MWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz81NmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzPzUxYTAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/M2JkYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz9iN2UzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzPzA5YmMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZThlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/MDY5OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/ZjhkMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz9lNGZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzPzJhMmYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/MTNkNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9jNjA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(t){var n=__webpack_module_cache__[t];if(void 0!==n)return n.exports;var e=__webpack_module_cache__[t]={exports:{}};return __webpack_modules__[t](e,e.exports,__webpack_require__),e.exports}__webpack_require__.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return __webpack_require__.d(n,{a:n}),n},__webpack_require__.d=function(t,n){for(var e in n)__webpack_require__.o(n,e)&&!__webpack_require__.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:n[e]})},__webpack_require__.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)};var __webpack_exports__=__webpack_require__(5298)})(); \ No newline at end of file diff --git a/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js b/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js index 8deeb4717c..c3b1d58231 100644 --- a/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js +++ b/readium/navigator/src/main/assets/readium/scripts/readium-reflowable.js @@ -1 +1 @@ -(function(){var __webpack_modules__={3089:function(__unused_webpack_module,exports){"use strict";eval('var __webpack_unused_export__;\n\n/**\n * Implementation of Myers\' online approximate string matching algorithm [1],\n * with additional optimizations suggested by [2].\n *\n * This has O((k/w) * n) complexity where `n` is the length of the text, `k` is\n * the maximum number of errors allowed (always <= the pattern length) and `w`\n * is the word size. Because JS only supports bitwise operations on 32 bit\n * integers, `w` is 32.\n *\n * As far as I am aware, there aren\'t any online algorithms which are\n * significantly better for a wide range of input parameters. The problem can be\n * solved faster using "filter then verify" approaches which first filter out\n * regions of the text that cannot match using a "cheap" check and then verify\n * the remaining potential matches. The verify step requires an algorithm such\n * as this one however.\n *\n * The algorithm\'s approach is essentially to optimize the classic dynamic\n * programming solution to the problem by computing columns of the matrix in\n * word-sized chunks (ie. dealing with 32 chars of the pattern at a time) and\n * avoiding calculating regions of the matrix where the minimum error count is\n * guaranteed to exceed the input threshold.\n *\n * The paper consists of two parts, the first describes the core algorithm for\n * matching patterns <= the size of a word (implemented by `advanceBlock` here).\n * The second uses the core algorithm as part of a larger block-based algorithm\n * to handle longer patterns.\n *\n * [1] G. Myers, “A Fast Bit-Vector Algorithm for Approximate String Matching\n * Based on Dynamic Programming,” vol. 46, no. 3, pp. 395–415, 1999.\n *\n * [2] Šošić, M. (2014). An simd dynamic programming c/c++ library (Doctoral\n * dissertation, Fakultet Elektrotehnike i računarstva, Sveučilište u Zagrebu).\n */\n__webpack_unused_export__ = ({ value: true });\nfunction reverse(s) {\n return s\n .split("")\n .reverse()\n .join("");\n}\n/**\n * Given the ends of approximate matches for `pattern` in `text`, find\n * the start of the matches.\n *\n * @param findEndFn - Function for finding the end of matches in\n * text.\n * @return Matches with the `start` property set.\n */\nfunction findMatchStarts(text, pattern, matches) {\n var patRev = reverse(pattern);\n return matches.map(function (m) {\n // Find start of each match by reversing the pattern and matching segment\n // of text and searching for an approx match with the same number of\n // errors.\n var minStart = Math.max(0, m.end - pattern.length - m.errors);\n var textRev = reverse(text.slice(minStart, m.end));\n // If there are multiple possible start points, choose the one that\n // maximizes the length of the match.\n var start = findMatchEnds(textRev, patRev, m.errors).reduce(function (min, rm) {\n if (m.end - rm.end < min) {\n return m.end - rm.end;\n }\n return min;\n }, m.end);\n return {\n start: start,\n end: m.end,\n errors: m.errors\n };\n });\n}\n/**\n * Return 1 if a number is non-zero or zero otherwise, without using\n * conditional operators.\n *\n * This should get inlined into `advanceBlock` below by the JIT.\n *\n * Adapted from https://stackoverflow.com/a/3912218/434243\n */\nfunction oneIfNotZero(n) {\n return ((n | -n) >> 31) & 1;\n}\n/**\n * Block calculation step of the algorithm.\n *\n * From Fig 8. on p. 408 of [1], additionally optimized to replace conditional\n * checks with bitwise operations as per Section 4.2.3 of [2].\n *\n * @param ctx - The pattern context object\n * @param peq - The `peq` array for the current character (`ctx.peq.get(ch)`)\n * @param b - The block level\n * @param hIn - Horizontal input delta ∈ {1,0,-1}\n * @return Horizontal output delta ∈ {1,0,-1}\n */\nfunction advanceBlock(ctx, peq, b, hIn) {\n var pV = ctx.P[b];\n var mV = ctx.M[b];\n var hInIsNegative = hIn >>> 31; // 1 if hIn < 0 or 0 otherwise.\n var eq = peq[b] | hInIsNegative;\n // Step 1: Compute horizontal deltas.\n var xV = eq | mV;\n var xH = (((eq & pV) + pV) ^ pV) | eq;\n var pH = mV | ~(xH | pV);\n var mH = pV & xH;\n // Step 2: Update score (value of last row of this block).\n var hOut = oneIfNotZero(pH & ctx.lastRowMask[b]) -\n oneIfNotZero(mH & ctx.lastRowMask[b]);\n // Step 3: Update vertical deltas for use when processing next char.\n pH <<= 1;\n mH <<= 1;\n mH |= hInIsNegative;\n pH |= oneIfNotZero(hIn) - hInIsNegative; // set pH[0] if hIn > 0\n pV = mH | ~(xV | pH);\n mV = pH & xV;\n ctx.P[b] = pV;\n ctx.M[b] = mV;\n return hOut;\n}\n/**\n * Find the ends and error counts for matches of `pattern` in `text`.\n *\n * Only the matches with the lowest error count are reported. Other matches\n * with error counts <= maxErrors are discarded.\n *\n * This is the block-based search algorithm from Fig. 9 on p.410 of [1].\n */\nfunction findMatchEnds(text, pattern, maxErrors) {\n if (pattern.length === 0) {\n return [];\n }\n // Clamp error count so we can rely on the `maxErrors` and `pattern.length`\n // rows being in the same block below.\n maxErrors = Math.min(maxErrors, pattern.length);\n var matches = [];\n // Word size.\n var w = 32;\n // Index of maximum block level.\n var bMax = Math.ceil(pattern.length / w) - 1;\n // Context used across block calculations.\n var ctx = {\n P: new Uint32Array(bMax + 1),\n M: new Uint32Array(bMax + 1),\n lastRowMask: new Uint32Array(bMax + 1)\n };\n ctx.lastRowMask.fill(1 << 31);\n ctx.lastRowMask[bMax] = 1 << (pattern.length - 1) % w;\n // Dummy "peq" array for chars in the text which do not occur in the pattern.\n var emptyPeq = new Uint32Array(bMax + 1);\n // Map of UTF-16 character code to bit vector indicating positions in the\n // pattern that equal that character.\n var peq = new Map();\n // Version of `peq` that only stores mappings for small characters. This\n // allows faster lookups when iterating through the text because a simple\n // array lookup can be done instead of a hash table lookup.\n var asciiPeq = [];\n for (var i = 0; i < 256; i++) {\n asciiPeq.push(emptyPeq);\n }\n // Calculate `ctx.peq` - a map of character values to bitmasks indicating\n // positions of that character within the pattern, where each bit represents\n // a position in the pattern.\n for (var c = 0; c < pattern.length; c += 1) {\n var val = pattern.charCodeAt(c);\n if (peq.has(val)) {\n // Duplicate char in pattern.\n continue;\n }\n var charPeq = new Uint32Array(bMax + 1);\n peq.set(val, charPeq);\n if (val < asciiPeq.length) {\n asciiPeq[val] = charPeq;\n }\n for (var b = 0; b <= bMax; b += 1) {\n charPeq[b] = 0;\n // Set all the bits where the pattern matches the current char (ch).\n // For indexes beyond the end of the pattern, always set the bit as if the\n // pattern contained a wildcard char in that position.\n for (var r = 0; r < w; r += 1) {\n var idx = b * w + r;\n if (idx >= pattern.length) {\n continue;\n }\n var match = pattern.charCodeAt(idx) === val;\n if (match) {\n charPeq[b] |= 1 << r;\n }\n }\n }\n }\n // Index of last-active block level in the column.\n var y = Math.max(0, Math.ceil(maxErrors / w) - 1);\n // Initialize maximum error count at bottom of each block.\n var score = new Uint32Array(bMax + 1);\n for (var b = 0; b <= y; b += 1) {\n score[b] = (b + 1) * w;\n }\n score[bMax] = pattern.length;\n // Initialize vertical deltas for each block.\n for (var b = 0; b <= y; b += 1) {\n ctx.P[b] = ~0;\n ctx.M[b] = 0;\n }\n // Process each char of the text, computing the error count for `w` chars of\n // the pattern at a time.\n for (var j = 0; j < text.length; j += 1) {\n // Lookup the bitmask representing the positions of the current char from\n // the text within the pattern.\n var charCode = text.charCodeAt(j);\n var charPeq = void 0;\n if (charCode < asciiPeq.length) {\n // Fast array lookup.\n charPeq = asciiPeq[charCode];\n }\n else {\n // Slower hash table lookup.\n charPeq = peq.get(charCode);\n if (typeof charPeq === "undefined") {\n charPeq = emptyPeq;\n }\n }\n // Calculate error count for blocks that we definitely have to process for\n // this column.\n var carry = 0;\n for (var b = 0; b <= y; b += 1) {\n carry = advanceBlock(ctx, charPeq, b, carry);\n score[b] += carry;\n }\n // Check if we also need to compute an additional block, or if we can reduce\n // the number of blocks processed for the next column.\n if (score[y] - carry <= maxErrors &&\n y < bMax &&\n (charPeq[y + 1] & 1 || carry < 0)) {\n // Error count for bottom block is under threshold, increase the number of\n // blocks processed for this column & next by 1.\n y += 1;\n ctx.P[y] = ~0;\n ctx.M[y] = 0;\n var maxBlockScore = y === bMax ? pattern.length % w : w;\n score[y] =\n score[y - 1] +\n maxBlockScore -\n carry +\n advanceBlock(ctx, charPeq, y, carry);\n }\n else {\n // Error count for bottom block exceeds threshold, reduce the number of\n // blocks processed for the next column.\n while (y > 0 && score[y] >= maxErrors + w) {\n y -= 1;\n }\n }\n // If error count is under threshold, report a match.\n if (y === bMax && score[y] <= maxErrors) {\n if (score[y] < maxErrors) {\n // Discard any earlier, worse matches.\n matches.splice(0, matches.length);\n }\n matches.push({\n start: -1,\n end: j + 1,\n errors: score[y]\n });\n // Because `search` only reports the matches with the lowest error count,\n // we can "ratchet down" the max error threshold whenever a match is\n // encountered and thereby save a small amount of work for the remainder\n // of the text.\n maxErrors = score[y];\n }\n }\n return matches;\n}\n/**\n * Search for matches for `pattern` in `text` allowing up to `maxErrors` errors.\n *\n * Returns the start, and end positions and error counts for each lowest-cost\n * match. Only the "best" matches are returned.\n */\nfunction search(text, pattern, maxErrors) {\n var matches = findMatchEnds(text, pattern, maxErrors);\n return findMatchStarts(text, pattern, matches);\n}\nexports.Z = search;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA4OS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkMsRUFBRSxhQUFhLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLE9BQU87QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2FwcHJveC1zdHJpbmctbWF0Y2gvZGlzdC9pbmRleC5qcz83MjMwIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBNeWVycycgb25saW5lIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBhbGdvcml0aG0gWzFdLFxuICogd2l0aCBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgc3VnZ2VzdGVkIGJ5IFsyXS5cbiAqXG4gKiBUaGlzIGhhcyBPKChrL3cpICogbikgY29tcGxleGl0eSB3aGVyZSBgbmAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCwgYGtgIGlzXG4gKiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIGFsbG93ZWQgKGFsd2F5cyA8PSB0aGUgcGF0dGVybiBsZW5ndGgpIGFuZCBgd2BcbiAqIGlzIHRoZSB3b3JkIHNpemUuIEJlY2F1c2UgSlMgb25seSBzdXBwb3J0cyBiaXR3aXNlIG9wZXJhdGlvbnMgb24gMzIgYml0XG4gKiBpbnRlZ2VycywgYHdgIGlzIDMyLlxuICpcbiAqIEFzIGZhciBhcyBJIGFtIGF3YXJlLCB0aGVyZSBhcmVuJ3QgYW55IG9ubGluZSBhbGdvcml0aG1zIHdoaWNoIGFyZVxuICogc2lnbmlmaWNhbnRseSBiZXR0ZXIgZm9yIGEgd2lkZSByYW5nZSBvZiBpbnB1dCBwYXJhbWV0ZXJzLiBUaGUgcHJvYmxlbSBjYW4gYmVcbiAqIHNvbHZlZCBmYXN0ZXIgdXNpbmcgXCJmaWx0ZXIgdGhlbiB2ZXJpZnlcIiBhcHByb2FjaGVzIHdoaWNoIGZpcnN0IGZpbHRlciBvdXRcbiAqIHJlZ2lvbnMgb2YgdGhlIHRleHQgdGhhdCBjYW5ub3QgbWF0Y2ggdXNpbmcgYSBcImNoZWFwXCIgY2hlY2sgYW5kIHRoZW4gdmVyaWZ5XG4gKiB0aGUgcmVtYWluaW5nIHBvdGVudGlhbCBtYXRjaGVzLiBUaGUgdmVyaWZ5IHN0ZXAgcmVxdWlyZXMgYW4gYWxnb3JpdGhtIHN1Y2hcbiAqIGFzIHRoaXMgb25lIGhvd2V2ZXIuXG4gKlxuICogVGhlIGFsZ29yaXRobSdzIGFwcHJvYWNoIGlzIGVzc2VudGlhbGx5IHRvIG9wdGltaXplIHRoZSBjbGFzc2ljIGR5bmFtaWNcbiAqIHByb2dyYW1taW5nIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGJ5IGNvbXB1dGluZyBjb2x1bW5zIG9mIHRoZSBtYXRyaXggaW5cbiAqIHdvcmQtc2l6ZWQgY2h1bmtzIChpZS4gZGVhbGluZyB3aXRoIDMyIGNoYXJzIG9mIHRoZSBwYXR0ZXJuIGF0IGEgdGltZSkgYW5kXG4gKiBhdm9pZGluZyBjYWxjdWxhdGluZyByZWdpb25zIG9mIHRoZSBtYXRyaXggd2hlcmUgdGhlIG1pbmltdW0gZXJyb3IgY291bnQgaXNcbiAqIGd1YXJhbnRlZWQgdG8gZXhjZWVkIHRoZSBpbnB1dCB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHBhcGVyIGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgdGhlIGZpcnN0IGRlc2NyaWJlcyB0aGUgY29yZSBhbGdvcml0aG0gZm9yXG4gKiBtYXRjaGluZyBwYXR0ZXJucyA8PSB0aGUgc2l6ZSBvZiBhIHdvcmQgKGltcGxlbWVudGVkIGJ5IGBhZHZhbmNlQmxvY2tgIGhlcmUpLlxuICogVGhlIHNlY29uZCB1c2VzIHRoZSBjb3JlIGFsZ29yaXRobSBhcyBwYXJ0IG9mIGEgbGFyZ2VyIGJsb2NrLWJhc2VkIGFsZ29yaXRobVxuICogdG8gaGFuZGxlIGxvbmdlciBwYXR0ZXJucy5cbiAqXG4gKiBbMV0gRy4gTXllcnMsIOKAnEEgRmFzdCBCaXQtVmVjdG9yIEFsZ29yaXRobSBmb3IgQXBwcm94aW1hdGUgU3RyaW5nIE1hdGNoaW5nXG4gKiBCYXNlZCBvbiBEeW5hbWljIFByb2dyYW1taW5nLOKAnSB2b2wuIDQ2LCBuby4gMywgcHAuIDM5NeKAkzQxNSwgMTk5OS5cbiAqXG4gKiBbMl0gxaBvxaFpxIcsIE0uICgyMDE0KS4gQW4gc2ltZCBkeW5hbWljIHByb2dyYW1taW5nIGMvYysrIGxpYnJhcnkgKERvY3RvcmFsXG4gKiBkaXNzZXJ0YXRpb24sIEZha3VsdGV0IEVsZWt0cm90ZWhuaWtlIGkgcmHEjXVuYXJzdHZhLCBTdmV1xI1pbGnFoXRlIHUgWmFncmVidSkuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJldmVyc2Uocykge1xuICAgIHJldHVybiBzXG4gICAgICAgIC5zcGxpdChcIlwiKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5qb2luKFwiXCIpO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgZW5kcyBvZiBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHRleHRgLCBmaW5kXG4gKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMuXG4gKlxuICogQHBhcmFtIGZpbmRFbmRGbiAtIEZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBlbmQgb2YgbWF0Y2hlcyBpblxuICogdGV4dC5cbiAqIEByZXR1cm4gTWF0Y2hlcyB3aXRoIHRoZSBgc3RhcnRgIHByb3BlcnR5IHNldC5cbiAqL1xuZnVuY3Rpb24gZmluZE1hdGNoU3RhcnRzKHRleHQsIHBhdHRlcm4sIG1hdGNoZXMpIHtcbiAgICB2YXIgcGF0UmV2ID0gcmV2ZXJzZShwYXR0ZXJuKTtcbiAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgLy8gRmluZCBzdGFydCBvZiBlYWNoIG1hdGNoIGJ5IHJldmVyc2luZyB0aGUgcGF0dGVybiBhbmQgbWF0Y2hpbmcgc2VnbWVudFxuICAgICAgICAvLyBvZiB0ZXh0IGFuZCBzZWFyY2hpbmcgZm9yIGFuIGFwcHJveCBtYXRjaCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZlxuICAgICAgICAvLyBlcnJvcnMuXG4gICAgICAgIHZhciBtaW5TdGFydCA9IE1hdGgubWF4KDAsIG0uZW5kIC0gcGF0dGVybi5sZW5ndGggLSBtLmVycm9ycyk7XG4gICAgICAgIHZhciB0ZXh0UmV2ID0gcmV2ZXJzZSh0ZXh0LnNsaWNlKG1pblN0YXJ0LCBtLmVuZCkpO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgc3RhcnQgcG9pbnRzLCBjaG9vc2UgdGhlIG9uZSB0aGF0XG4gICAgICAgIC8vIG1heGltaXplcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaC5cbiAgICAgICAgdmFyIHN0YXJ0ID0gZmluZE1hdGNoRW5kcyh0ZXh0UmV2LCBwYXRSZXYsIG0uZXJyb3JzKS5yZWR1Y2UoZnVuY3Rpb24gKG1pbiwgcm0pIHtcbiAgICAgICAgICAgIGlmIChtLmVuZCAtIHJtLmVuZCA8IG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmVuZCAtIHJtLmVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtaW47XG4gICAgICAgIH0sIG0uZW5kKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogbS5lbmQsXG4gICAgICAgICAgICBlcnJvcnM6IG0uZXJyb3JzXG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybiAxIGlmIGEgbnVtYmVyIGlzIG5vbi16ZXJvIG9yIHplcm8gb3RoZXJ3aXNlLCB3aXRob3V0IHVzaW5nXG4gKiBjb25kaXRpb25hbCBvcGVyYXRvcnMuXG4gKlxuICogVGhpcyBzaG91bGQgZ2V0IGlubGluZWQgaW50byBgYWR2YW5jZUJsb2NrYCBiZWxvdyBieSB0aGUgSklULlxuICpcbiAqIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzkxMjIxOC80MzQyNDNcbiAqL1xuZnVuY3Rpb24gb25lSWZOb3RaZXJvKG4pIHtcbiAgICByZXR1cm4gKChuIHwgLW4pID4+IDMxKSAmIDE7XG59XG4vKipcbiAqIEJsb2NrIGNhbGN1bGF0aW9uIHN0ZXAgb2YgdGhlIGFsZ29yaXRobS5cbiAqXG4gKiBGcm9tIEZpZyA4LiBvbiBwLiA0MDggb2YgWzFdLCBhZGRpdGlvbmFsbHkgb3B0aW1pemVkIHRvIHJlcGxhY2UgY29uZGl0aW9uYWxcbiAqIGNoZWNrcyB3aXRoIGJpdHdpc2Ugb3BlcmF0aW9ucyBhcyBwZXIgU2VjdGlvbiA0LjIuMyBvZiBbMl0uXG4gKlxuICogQHBhcmFtIGN0eCAtIFRoZSBwYXR0ZXJuIGNvbnRleHQgb2JqZWN0XG4gKiBAcGFyYW0gcGVxIC0gVGhlIGBwZXFgIGFycmF5IGZvciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgKGBjdHgucGVxLmdldChjaClgKVxuICogQHBhcmFtIGIgLSBUaGUgYmxvY2sgbGV2ZWxcbiAqIEBwYXJhbSBoSW4gLSBIb3Jpem9udGFsIGlucHV0IGRlbHRhIOKIiCB7MSwwLC0xfVxuICogQHJldHVybiBIb3Jpem9udGFsIG91dHB1dCBkZWx0YSDiiIggezEsMCwtMX1cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUJsb2NrKGN0eCwgcGVxLCBiLCBoSW4pIHtcbiAgICB2YXIgcFYgPSBjdHguUFtiXTtcbiAgICB2YXIgbVYgPSBjdHguTVtiXTtcbiAgICB2YXIgaEluSXNOZWdhdGl2ZSA9IGhJbiA+Pj4gMzE7IC8vIDEgaWYgaEluIDwgMCBvciAwIG90aGVyd2lzZS5cbiAgICB2YXIgZXEgPSBwZXFbYl0gfCBoSW5Jc05lZ2F0aXZlO1xuICAgIC8vIFN0ZXAgMTogQ29tcHV0ZSBob3Jpem9udGFsIGRlbHRhcy5cbiAgICB2YXIgeFYgPSBlcSB8IG1WO1xuICAgIHZhciB4SCA9ICgoKGVxICYgcFYpICsgcFYpIF4gcFYpIHwgZXE7XG4gICAgdmFyIHBIID0gbVYgfCB+KHhIIHwgcFYpO1xuICAgIHZhciBtSCA9IHBWICYgeEg7XG4gICAgLy8gU3RlcCAyOiBVcGRhdGUgc2NvcmUgKHZhbHVlIG9mIGxhc3Qgcm93IG9mIHRoaXMgYmxvY2spLlxuICAgIHZhciBoT3V0ID0gb25lSWZOb3RaZXJvKHBIICYgY3R4Lmxhc3RSb3dNYXNrW2JdKSAtXG4gICAgICAgIG9uZUlmTm90WmVybyhtSCAmIGN0eC5sYXN0Um93TWFza1tiXSk7XG4gICAgLy8gU3RlcCAzOiBVcGRhdGUgdmVydGljYWwgZGVsdGFzIGZvciB1c2Ugd2hlbiBwcm9jZXNzaW5nIG5leHQgY2hhci5cbiAgICBwSCA8PD0gMTtcbiAgICBtSCA8PD0gMTtcbiAgICBtSCB8PSBoSW5Jc05lZ2F0aXZlO1xuICAgIHBIIHw9IG9uZUlmTm90WmVybyhoSW4pIC0gaEluSXNOZWdhdGl2ZTsgLy8gc2V0IHBIWzBdIGlmIGhJbiA+IDBcbiAgICBwViA9IG1IIHwgfih4ViB8IHBIKTtcbiAgICBtViA9IHBIICYgeFY7XG4gICAgY3R4LlBbYl0gPSBwVjtcbiAgICBjdHguTVtiXSA9IG1WO1xuICAgIHJldHVybiBoT3V0O1xufVxuLyoqXG4gKiBGaW5kIHRoZSBlbmRzIGFuZCBlcnJvciBjb3VudHMgZm9yIG1hdGNoZXMgb2YgYHBhdHRlcm5gIGluIGB0ZXh0YC5cbiAqXG4gKiBPbmx5IHRoZSBtYXRjaGVzIHdpdGggdGhlIGxvd2VzdCBlcnJvciBjb3VudCBhcmUgcmVwb3J0ZWQuIE90aGVyIG1hdGNoZXNcbiAqIHdpdGggZXJyb3IgY291bnRzIDw9IG1heEVycm9ycyBhcmUgZGlzY2FyZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGJsb2NrLWJhc2VkIHNlYXJjaCBhbGdvcml0aG0gZnJvbSBGaWcuIDkgb24gcC40MTAgb2YgWzFdLlxuICovXG5mdW5jdGlvbiBmaW5kTWF0Y2hFbmRzKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIENsYW1wIGVycm9yIGNvdW50IHNvIHdlIGNhbiByZWx5IG9uIHRoZSBgbWF4RXJyb3JzYCBhbmQgYHBhdHRlcm4ubGVuZ3RoYFxuICAgIC8vIHJvd3MgYmVpbmcgaW4gdGhlIHNhbWUgYmxvY2sgYmVsb3cuXG4gICAgbWF4RXJyb3JzID0gTWF0aC5taW4obWF4RXJyb3JzLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgICAvLyBXb3JkIHNpemUuXG4gICAgdmFyIHcgPSAzMjtcbiAgICAvLyBJbmRleCBvZiBtYXhpbXVtIGJsb2NrIGxldmVsLlxuICAgIHZhciBiTWF4ID0gTWF0aC5jZWlsKHBhdHRlcm4ubGVuZ3RoIC8gdykgLSAxO1xuICAgIC8vIENvbnRleHQgdXNlZCBhY3Jvc3MgYmxvY2sgY2FsY3VsYXRpb25zLlxuICAgIHZhciBjdHggPSB7XG4gICAgICAgIFA6IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIE06IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIGxhc3RSb3dNYXNrOiBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpXG4gICAgfTtcbiAgICBjdHgubGFzdFJvd01hc2suZmlsbCgxIDw8IDMxKTtcbiAgICBjdHgubGFzdFJvd01hc2tbYk1heF0gPSAxIDw8IChwYXR0ZXJuLmxlbmd0aCAtIDEpICUgdztcbiAgICAvLyBEdW1teSBcInBlcVwiIGFycmF5IGZvciBjaGFycyBpbiB0aGUgdGV4dCB3aGljaCBkbyBub3Qgb2NjdXIgaW4gdGhlIHBhdHRlcm4uXG4gICAgdmFyIGVtcHR5UGVxID0gbmV3IFVpbnQzMkFycmF5KGJNYXggKyAxKTtcbiAgICAvLyBNYXAgb2YgVVRGLTE2IGNoYXJhY3RlciBjb2RlIHRvIGJpdCB2ZWN0b3IgaW5kaWNhdGluZyBwb3NpdGlvbnMgaW4gdGhlXG4gICAgLy8gcGF0dGVybiB0aGF0IGVxdWFsIHRoYXQgY2hhcmFjdGVyLlxuICAgIHZhciBwZXEgPSBuZXcgTWFwKCk7XG4gICAgLy8gVmVyc2lvbiBvZiBgcGVxYCB0aGF0IG9ubHkgc3RvcmVzIG1hcHBpbmdzIGZvciBzbWFsbCBjaGFyYWN0ZXJzLiBUaGlzXG4gICAgLy8gYWxsb3dzIGZhc3RlciBsb29rdXBzIHdoZW4gaXRlcmF0aW5nIHRocm91Z2ggdGhlIHRleHQgYmVjYXVzZSBhIHNpbXBsZVxuICAgIC8vIGFycmF5IGxvb2t1cCBjYW4gYmUgZG9uZSBpbnN0ZWFkIG9mIGEgaGFzaCB0YWJsZSBsb29rdXAuXG4gICAgdmFyIGFzY2lpUGVxID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgICBhc2NpaVBlcS5wdXNoKGVtcHR5UGVxKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlIGBjdHgucGVxYCAtIGEgbWFwIG9mIGNoYXJhY3RlciB2YWx1ZXMgdG8gYml0bWFza3MgaW5kaWNhdGluZ1xuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGF0IGNoYXJhY3RlciB3aXRoaW4gdGhlIHBhdHRlcm4sIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHNcbiAgICAvLyBhIHBvc2l0aW9uIGluIHRoZSBwYXR0ZXJuLlxuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgcGF0dGVybi5sZW5ndGg7IGMgKz0gMSkge1xuICAgICAgICB2YXIgdmFsID0gcGF0dGVybi5jaGFyQ29kZUF0KGMpO1xuICAgICAgICBpZiAocGVxLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgY2hhciBpbiBwYXR0ZXJuLlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoYXJQZXEgPSBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpO1xuICAgICAgICBwZXEuc2V0KHZhbCwgY2hhclBlcSk7XG4gICAgICAgIGlmICh2YWwgPCBhc2NpaVBlcS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFzY2lpUGVxW3ZhbF0gPSBjaGFyUGVxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGIgPSAwOyBiIDw9IGJNYXg7IGIgKz0gMSkge1xuICAgICAgICAgICAgY2hhclBlcVtiXSA9IDA7XG4gICAgICAgICAgICAvLyBTZXQgYWxsIHRoZSBiaXRzIHdoZXJlIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGN1cnJlbnQgY2hhciAoY2gpLlxuICAgICAgICAgICAgLy8gRm9yIGluZGV4ZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIGFsd2F5cyBzZXQgdGhlIGJpdCBhcyBpZiB0aGVcbiAgICAgICAgICAgIC8vIHBhdHRlcm4gY29udGFpbmVkIGEgd2lsZGNhcmQgY2hhciBpbiB0aGF0IHBvc2l0aW9uLlxuICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCB3OyByICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gYiAqIHcgKyByO1xuICAgICAgICAgICAgICAgIGlmIChpZHggPj0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IHBhdHRlcm4uY2hhckNvZGVBdChpZHgpID09PSB2YWw7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJQZXFbYl0gfD0gMSA8PCByO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJbmRleCBvZiBsYXN0LWFjdGl2ZSBibG9jayBsZXZlbCBpbiB0aGUgY29sdW1uLlxuICAgIHZhciB5ID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKG1heEVycm9ycyAvIHcpIC0gMSk7XG4gICAgLy8gSW5pdGlhbGl6ZSBtYXhpbXVtIGVycm9yIGNvdW50IGF0IGJvdHRvbSBvZiBlYWNoIGJsb2NrLlxuICAgIHZhciBzY29yZSA9IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSk7XG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIHNjb3JlW2JdID0gKGIgKyAxKSAqIHc7XG4gICAgfVxuICAgIHNjb3JlW2JNYXhdID0gcGF0dGVybi5sZW5ndGg7XG4gICAgLy8gSW5pdGlhbGl6ZSB2ZXJ0aWNhbCBkZWx0YXMgZm9yIGVhY2ggYmxvY2suXG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIGN0eC5QW2JdID0gfjA7XG4gICAgICAgIGN0eC5NW2JdID0gMDtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBlYWNoIGNoYXIgb2YgdGhlIHRleHQsIGNvbXB1dGluZyB0aGUgZXJyb3IgY291bnQgZm9yIGB3YCBjaGFycyBvZlxuICAgIC8vIHRoZSBwYXR0ZXJuIGF0IGEgdGltZS5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRleHQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBiaXRtYXNrIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb25zIG9mIHRoZSBjdXJyZW50IGNoYXIgZnJvbVxuICAgICAgICAvLyB0aGUgdGV4dCB3aXRoaW4gdGhlIHBhdHRlcm4uXG4gICAgICAgIHZhciBjaGFyQ29kZSA9IHRleHQuY2hhckNvZGVBdChqKTtcbiAgICAgICAgdmFyIGNoYXJQZXEgPSB2b2lkIDA7XG4gICAgICAgIGlmIChjaGFyQ29kZSA8IGFzY2lpUGVxLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gRmFzdCBhcnJheSBsb29rdXAuXG4gICAgICAgICAgICBjaGFyUGVxID0gYXNjaWlQZXFbY2hhckNvZGVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU2xvd2VyIGhhc2ggdGFibGUgbG9va3VwLlxuICAgICAgICAgICAgY2hhclBlcSA9IHBlcS5nZXQoY2hhckNvZGUpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyUGVxID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgY2hhclBlcSA9IGVtcHR5UGVxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3VudCBmb3IgYmxvY2tzIHRoYXQgd2UgZGVmaW5pdGVseSBoYXZlIHRvIHByb2Nlc3MgZm9yXG4gICAgICAgIC8vIHRoaXMgY29sdW1uLlxuICAgICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBiID0gMDsgYiA8PSB5OyBiICs9IDEpIHtcbiAgICAgICAgICAgIGNhcnJ5ID0gYWR2YW5jZUJsb2NrKGN0eCwgY2hhclBlcSwgYiwgY2FycnkpO1xuICAgICAgICAgICAgc2NvcmVbYl0gKz0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgYWxzbyBuZWVkIHRvIGNvbXB1dGUgYW4gYWRkaXRpb25hbCBibG9jaywgb3IgaWYgd2UgY2FuIHJlZHVjZVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGJsb2NrcyBwcm9jZXNzZWQgZm9yIHRoZSBuZXh0IGNvbHVtbi5cbiAgICAgICAgaWYgKHNjb3JlW3ldIC0gY2FycnkgPD0gbWF4RXJyb3JzICYmXG4gICAgICAgICAgICB5IDwgYk1heCAmJlxuICAgICAgICAgICAgKGNoYXJQZXFbeSArIDFdICYgMSB8fCBjYXJyeSA8IDApKSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGlzIHVuZGVyIHRocmVzaG9sZCwgaW5jcmVhc2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhpcyBjb2x1bW4gJiBuZXh0IGJ5IDEuXG4gICAgICAgICAgICB5ICs9IDE7XG4gICAgICAgICAgICBjdHguUFt5XSA9IH4wO1xuICAgICAgICAgICAgY3R4Lk1beV0gPSAwO1xuICAgICAgICAgICAgdmFyIG1heEJsb2NrU2NvcmUgPSB5ID09PSBiTWF4ID8gcGF0dGVybi5sZW5ndGggJSB3IDogdztcbiAgICAgICAgICAgIHNjb3JlW3ldID1cbiAgICAgICAgICAgICAgICBzY29yZVt5IC0gMV0gK1xuICAgICAgICAgICAgICAgICAgICBtYXhCbG9ja1Njb3JlIC1cbiAgICAgICAgICAgICAgICAgICAgY2FycnkgK1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlQmxvY2soY3R4LCBjaGFyUGVxLCB5LCBjYXJyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGV4Y2VlZHMgdGhyZXNob2xkLCByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhlIG5leHQgY29sdW1uLlxuICAgICAgICAgICAgd2hpbGUgKHkgPiAwICYmIHNjb3JlW3ldID49IG1heEVycm9ycyArIHcpIHtcbiAgICAgICAgICAgICAgICB5IC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZXJyb3IgY291bnQgaXMgdW5kZXIgdGhyZXNob2xkLCByZXBvcnQgYSBtYXRjaC5cbiAgICAgICAgaWYgKHkgPT09IGJNYXggJiYgc2NvcmVbeV0gPD0gbWF4RXJyb3JzKSB7XG4gICAgICAgICAgICBpZiAoc2NvcmVbeV0gPCBtYXhFcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIGFueSBlYXJsaWVyLCB3b3JzZSBtYXRjaGVzLlxuICAgICAgICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKDAsIG1hdGNoZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICAgICAgICAgIGVuZDogaiArIDEsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBzY29yZVt5XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBCZWNhdXNlIGBzZWFyY2hgIG9ubHkgcmVwb3J0cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBsb3dlc3QgZXJyb3IgY291bnQsXG4gICAgICAgICAgICAvLyB3ZSBjYW4gXCJyYXRjaGV0IGRvd25cIiB0aGUgbWF4IGVycm9yIHRocmVzaG9sZCB3aGVuZXZlciBhIG1hdGNoIGlzXG4gICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbmQgdGhlcmVieSBzYXZlIGEgc21hbGwgYW1vdW50IG9mIHdvcmsgZm9yIHRoZSByZW1haW5kZXJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB0ZXh0LlxuICAgICAgICAgICAgbWF4RXJyb3JzID0gc2NvcmVbeV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59XG4vKipcbiAqIFNlYXJjaCBmb3IgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogUmV0dXJucyB0aGUgc3RhcnQsIGFuZCBlbmQgcG9zaXRpb25zIGFuZCBlcnJvciBjb3VudHMgZm9yIGVhY2ggbG93ZXN0LWNvc3RcbiAqIG1hdGNoLiBPbmx5IHRoZSBcImJlc3RcIiBtYXRjaGVzIGFyZSByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoRW5kcyh0ZXh0LCBwYXR0ZXJuLCBtYXhFcnJvcnMpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hTdGFydHModGV4dCwgcGF0dGVybiwgbWF0Y2hlcyk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzZWFyY2g7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3089\n')},6960:function(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__){"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/approx-string-match/dist/index.js\nvar dist = __webpack_require__(3089);\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/match-quote.js\n\n/**\n * @typedef {import(\'approx-string-match\').Match} StringMatch\n */\n\n/**\n * @typedef Match\n * @prop {number} start - Start offset of match in text\n * @prop {number} end - End offset of match in text\n * @prop {number} score -\n * Score for the match between 0 and 1.0, where 1.0 indicates a perfect match\n * for the quote and context.\n */\n\n/**\n * Find the best approximate matches for `str` in `text` allowing up to `maxErrors` errors.\n *\n * @param {string} text\n * @param {string} str\n * @param {number} maxErrors\n * @return {StringMatch[]}\n */\n\nfunction search(text, str, maxErrors) {\n // Do a fast search for exact matches. The `approx-string-match` library\n // doesn\'t currently incorporate this optimization itself.\n var matchPos = 0;\n var exactMatches = [];\n\n while (matchPos !== -1) {\n matchPos = text.indexOf(str, matchPos);\n\n if (matchPos !== -1) {\n exactMatches.push({\n start: matchPos,\n end: matchPos + str.length,\n errors: 0\n });\n matchPos += 1;\n }\n }\n\n if (exactMatches.length > 0) {\n return exactMatches;\n } // If there are no exact matches, do a more expensive search for matches\n // with errors.\n\n\n return (0,dist/* default */.Z)(text, str, maxErrors);\n}\n/**\n * Compute a score between 0 and 1.0 for the similarity between `text` and `str`.\n *\n * @param {string} text\n * @param {string} str\n */\n\n\nfunction textMatchScore(text, str) {\n /* istanbul ignore next - `scoreMatch` will never pass an empty string */\n if (str.length === 0 || text.length === 0) {\n return 0.0;\n }\n\n var matches = search(text, str, str.length); // prettier-ignore\n\n return 1 - matches[0].errors / str.length;\n}\n/**\n * Find the best approximate match for `quote` in `text`.\n *\n * Returns `null` if no match exceeding the minimum quality threshold was found.\n *\n * @param {string} text - Document text to search\n * @param {string} quote - String to find within `text`\n * @param {Object} context -\n * Context in which the quote originally appeared. This is used to choose the\n * best match.\n * @param {string} [context.prefix] - Expected text before the quote\n * @param {string} [context.suffix] - Expected text after the quote\n * @param {number} [context.hint] - Expected offset of match within text\n * @return {Match|null}\n */\n\n\nfunction matchQuote(text, quote) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (quote.length === 0) {\n return null;\n } // Choose the maximum number of errors to allow for the initial search.\n // This choice involves a tradeoff between:\n //\n // - Recall (proportion of "good" matches found)\n // - Precision (proportion of matches found which are "good")\n // - Cost of the initial search and of processing the candidate matches [1]\n //\n // [1] Specifically, the expected-time complexity of the initial search is\n // `O((maxErrors / 32) * text.length)`. See `approx-string-match` docs.\n\n\n var maxErrors = Math.min(256, quote.length / 2); // Find closest matches for `quote` in `text` based on edit distance.\n\n var matches = search(text, quote, maxErrors);\n\n if (matches.length === 0) {\n return null;\n }\n /**\n * Compute a score between 0 and 1.0 for a match candidate.\n *\n * @param {StringMatch} match\n */\n\n\n var scoreMatch = function scoreMatch(match) {\n var quoteWeight = 50; // Similarity of matched text to quote.\n\n var prefixWeight = 20; // Similarity of text before matched text to `context.prefix`.\n\n var suffixWeight = 20; // Similarity of text after matched text to `context.suffix`.\n\n var posWeight = 2; // Proximity to expected location. Used as a tie-breaker.\n\n var quoteScore = 1 - match.errors / quote.length;\n var prefixScore = context.prefix ? textMatchScore(text.slice(Math.max(0, match.start - context.prefix.length), match.start), context.prefix) : 1.0;\n var suffixScore = context.suffix ? textMatchScore(text.slice(match.end, match.end + context.suffix.length), context.suffix) : 1.0;\n var posScore = 1.0;\n\n if (typeof context.hint === \'number\') {\n var offset = Math.abs(match.start - context.hint);\n posScore = 1.0 - offset / text.length;\n }\n\n var rawScore = quoteWeight * quoteScore + prefixWeight * prefixScore + suffixWeight * suffixScore + posWeight * posScore;\n var maxScore = quoteWeight + prefixWeight + suffixWeight + posWeight;\n var normalizedScore = rawScore / maxScore;\n return normalizedScore;\n }; // Rank matches based on similarity of actual and expected surrounding text\n // and actual/expected offset in the document text.\n\n\n var scoredMatches = matches.map(function (m) {\n return {\n start: m.start,\n end: m.end,\n score: scoreMatch(m)\n };\n }); // Choose match with highest score.\n\n scoredMatches.sort(function (a, b) {\n return b.score - a.score;\n });\n return scoredMatches[0];\n}\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/text-range.js\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Return the combined length of text nodes contained in `node`.\n *\n * @param {Node} node\n */\nfunction nodeTextLength(node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.TEXT_NODE:\n // nb. `textContent` excludes text in comments and processing instructions\n // when called on a parent element, so we don\'t need to subtract that here.\n return (\n /** @type {string} */\n node.textContent.length\n );\n\n default:\n return 0;\n }\n}\n/**\n * Return the total length of the text of all previous siblings of `node`.\n *\n * @param {Node} node\n */\n\n\nfunction previousSiblingsTextLength(node) {\n var sibling = node.previousSibling;\n var length = 0;\n\n while (sibling) {\n length += nodeTextLength(sibling);\n sibling = sibling.previousSibling;\n }\n\n return length;\n}\n/**\n * Resolve one or more character offsets within an element to (text node, position)\n * pairs.\n *\n * @param {Element} element\n * @param {number[]} offsets - Offsets, which must be sorted in ascending order\n * @return {{ node: Text, offset: number }[]}\n */\n\n\nfunction resolveOffsets(element) {\n for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n offsets[_key - 1] = arguments[_key];\n }\n\n var nextOffset = offsets.shift();\n var nodeIter =\n /** @type {Document} */\n element.ownerDocument.createNodeIterator(element, NodeFilter.SHOW_TEXT);\n var results = [];\n var currentNode = nodeIter.nextNode();\n var textNode;\n var length = 0; // Find the text node containing the `nextOffset`th character from the start\n // of `element`.\n\n while (nextOffset !== undefined && currentNode) {\n textNode =\n /** @type {Text} */\n currentNode;\n\n if (length + textNode.data.length > nextOffset) {\n results.push({\n node: textNode,\n offset: nextOffset - length\n });\n nextOffset = offsets.shift();\n } else {\n currentNode = nodeIter.nextNode();\n length += textNode.data.length;\n }\n } // Boundary case.\n\n\n while (nextOffset !== undefined && textNode && length === nextOffset) {\n results.push({\n node: textNode,\n offset: textNode.data.length\n });\n nextOffset = offsets.shift();\n }\n\n if (nextOffset !== undefined) {\n throw new RangeError(\'Offset exceeds text length\');\n }\n\n return results;\n}\n\nvar RESOLVE_FORWARDS = 1;\nvar RESOLVE_BACKWARDS = 2;\n/**\n * Represents an offset within the text content of an element.\n *\n * This position can be resolved to a specific descendant node in the current\n * DOM subtree of the element using the `resolve` method.\n */\n\nvar text_range_TextPosition = /*#__PURE__*/function () {\n /**\n * Construct a `TextPosition` that refers to the text position `offset` within\n * the text content of `element`.\n *\n * @param {Element} element\n * @param {number} offset\n */\n function TextPosition(element, offset) {\n _classCallCheck(this, TextPosition);\n\n if (offset < 0) {\n throw new Error(\'Offset is invalid\');\n }\n /** Element that `offset` is relative to. */\n\n\n this.element = element;\n /** Character offset from the start of the element\'s `textContent`. */\n\n this.offset = offset;\n }\n /**\n * Return a copy of this position with offset relative to a given ancestor\n * element.\n *\n * @param {Element} parent - Ancestor of `this.element`\n * @return {TextPosition}\n */\n\n\n _createClass(TextPosition, [{\n key: "relativeTo",\n value: function relativeTo(parent) {\n if (!parent.contains(this.element)) {\n throw new Error(\'Parent is not an ancestor of current element\');\n }\n\n var el = this.element;\n var offset = this.offset;\n\n while (el !== parent) {\n offset += previousSiblingsTextLength(el);\n el =\n /** @type {Element} */\n el.parentElement;\n }\n\n return new TextPosition(el, offset);\n }\n /**\n * Resolve the position to a specific text node and offset within that node.\n *\n * Throws if `this.offset` exceeds the length of the element\'s text. In the\n * case where the element has no text and `this.offset` is 0, the `direction`\n * option determines what happens.\n *\n * Offsets at the boundary between two nodes are resolved to the start of the\n * node that begins at the boundary.\n *\n * @param {Object} [options]\n * @param {RESOLVE_FORWARDS|RESOLVE_BACKWARDS} [options.direction] -\n * Specifies in which direction to search for the nearest text node if\n * `this.offset` is `0` and `this.element` has no text. If not specified\n * an error is thrown.\n * @return {{ node: Text, offset: number }}\n * @throws {RangeError}\n */\n\n }, {\n key: "resolve",\n value: function resolve() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n try {\n return resolveOffsets(this.element, this.offset)[0];\n } catch (err) {\n if (this.offset === 0 && options.direction !== undefined) {\n var tw = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);\n tw.currentNode = this.element;\n var forwards = options.direction === RESOLVE_FORWARDS;\n var text =\n /** @type {Text|null} */\n forwards ? tw.nextNode() : tw.previousNode();\n\n if (!text) {\n throw err;\n }\n\n return {\n node: text,\n offset: forwards ? 0 : text.data.length\n };\n } else {\n throw err;\n }\n }\n }\n /**\n * Construct a `TextPosition` that refers to the `offset`th character within\n * `node`.\n *\n * @param {Node} node\n * @param {number} offset\n * @return {TextPosition}\n */\n\n }], [{\n key: "fromCharOffset",\n value: function fromCharOffset(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n return TextPosition.fromPoint(node, offset);\n\n case Node.ELEMENT_NODE:\n return new TextPosition(\n /** @type {Element} */\n node, offset);\n\n default:\n throw new Error(\'Node is not an element or text node\');\n }\n }\n /**\n * Construct a `TextPosition` representing the range start or end point (node, offset).\n *\n * @param {Node} node - Text or Element node\n * @param {number} offset - Offset within the node.\n * @return {TextPosition}\n */\n\n }, {\n key: "fromPoint",\n value: function fromPoint(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n {\n if (offset < 0 || offset >\n /** @type {Text} */\n node.data.length) {\n throw new Error(\'Text node offset is out of range\');\n }\n\n if (!node.parentElement) {\n throw new Error(\'Text node has no parent\');\n } // Get the offset from the start of the parent element.\n\n\n var textOffset = previousSiblingsTextLength(node) + offset;\n return new TextPosition(node.parentElement, textOffset);\n }\n\n case Node.ELEMENT_NODE:\n {\n if (offset < 0 || offset > node.childNodes.length) {\n throw new Error(\'Child node offset is out of range\');\n } // Get the text length before the `offset`th child of element.\n\n\n var _textOffset = 0;\n\n for (var i = 0; i < offset; i++) {\n _textOffset += nodeTextLength(node.childNodes[i]);\n }\n\n return new TextPosition(\n /** @type {Element} */\n node, _textOffset);\n }\n\n default:\n throw new Error(\'Point is not in an element or text node\');\n }\n }\n }]);\n\n return TextPosition;\n}();\n/**\n * Represents a region of a document as a (start, end) pair of `TextPosition` points.\n *\n * Representing a range in this way allows for changes in the DOM content of the\n * range which don\'t affect its text content, without affecting the text content\n * of the range itself.\n */\n\nvar text_range_TextRange = /*#__PURE__*/function () {\n /**\n * Construct an immutable `TextRange` from a `start` and `end` point.\n *\n * @param {TextPosition} start\n * @param {TextPosition} end\n */\n function TextRange(start, end) {\n _classCallCheck(this, TextRange);\n\n this.start = start;\n this.end = end;\n }\n /**\n * Return a copy of this range with start and end positions relative to a\n * given ancestor. See `TextPosition.relativeTo`.\n *\n * @param {Element} element\n */\n\n\n _createClass(TextRange, [{\n key: "relativeTo",\n value: function relativeTo(element) {\n return new TextRange(this.start.relativeTo(element), this.end.relativeTo(element));\n }\n /**\n * Resolve the `TextRange` to a DOM range.\n *\n * The resulting DOM Range will always start and end in a `Text` node.\n * Hence `TextRange.fromRange(range).toRange()` can be used to "shrink" a\n * range to the text it contains.\n *\n * May throw if the `start` or `end` positions cannot be resolved to a range.\n *\n * @return {Range}\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var start;\n var end;\n\n if (this.start.element === this.end.element && this.start.offset <= this.end.offset) {\n // Fast path for start and end points in same element.\n var _resolveOffsets = resolveOffsets(this.start.element, this.start.offset, this.end.offset);\n\n var _resolveOffsets2 = _slicedToArray(_resolveOffsets, 2);\n\n start = _resolveOffsets2[0];\n end = _resolveOffsets2[1];\n } else {\n start = this.start.resolve({\n direction: RESOLVE_FORWARDS\n });\n end = this.end.resolve({\n direction: RESOLVE_BACKWARDS\n });\n }\n\n var range = new Range();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range;\n }\n /**\n * Convert an existing DOM `Range` to a `TextRange`\n *\n * @param {Range} range\n * @return {TextRange}\n */\n\n }], [{\n key: "fromRange",\n value: function fromRange(range) {\n var start = text_range_TextPosition.fromPoint(range.startContainer, range.startOffset);\n var end = text_range_TextPosition.fromPoint(range.endContainer, range.endOffset);\n return new TextRange(start, end);\n }\n /**\n * Return a `TextRange` from the `start`th to `end`th characters in `root`.\n *\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n\n }, {\n key: "fromOffsets",\n value: function fromOffsets(root, start, end) {\n return new TextRange(new text_range_TextPosition(root, start), new text_range_TextPosition(root, end));\n }\n }]);\n\n return TextRange;\n}();\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/types.js\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction types_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction types_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction types_createClass(Constructor, protoProps, staticProps) { if (protoProps) types_defineProperties(Constructor.prototype, protoProps); if (staticProps) types_defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This module exports a set of classes for converting between DOM `Range`\n * objects and different types of selectors. It is mostly a thin wrapper around a\n * set of anchoring libraries. It serves two main purposes:\n *\n * 1. Providing a consistent interface across different types of anchors.\n * 2. Insulating the rest of the code from API changes in the underlying anchoring\n * libraries.\n */\n\n\n\n/**\n * @typedef {import(\'../../types/api\').RangeSelector} RangeSelector\n * @typedef {import(\'../../types/api\').TextPositionSelector} TextPositionSelector\n * @typedef {import(\'../../types/api\').TextQuoteSelector} TextQuoteSelector\n */\n\n/**\n * Converts between `RangeSelector` selectors and `Range` objects.\n */\n\nvar RangeAnchor = /*#__PURE__*/(/* unused pure expression or super */ null && (function () {\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n function RangeAnchor(root, range) {\n types_classCallCheck(this, RangeAnchor);\n\n this.root = root;\n this.range = range;\n }\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n\n\n types_createClass(RangeAnchor, [{\n key: "toRange",\n value: function toRange() {\n return this.range;\n }\n /**\n * @return {RangeSelector}\n */\n\n }, {\n key: "toSelector",\n value: function toSelector() {\n // "Shrink" the range so that it tightly wraps its text. This ensures more\n // predictable output for a given text selection.\n var normalizedRange = TextRange.fromRange(this.range).toRange();\n var textRange = TextRange.fromRange(normalizedRange);\n var startContainer = xpathFromNode(textRange.start.element, this.root);\n var endContainer = xpathFromNode(textRange.end.element, this.root);\n return {\n type: \'RangeSelector\',\n startContainer: startContainer,\n startOffset: textRange.start.offset,\n endContainer: endContainer,\n endOffset: textRange.end.offset\n };\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n return new RangeAnchor(root, range);\n }\n /**\n * Create an anchor from a serialized `RangeSelector` selector.\n *\n * @param {Element} root - A root element from which to anchor.\n * @param {RangeSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var startContainer = nodeFromXPath(selector.startContainer, root);\n\n if (!startContainer) {\n throw new Error(\'Failed to resolve startContainer XPath\');\n }\n\n var endContainer = nodeFromXPath(selector.endContainer, root);\n\n if (!endContainer) {\n throw new Error(\'Failed to resolve endContainer XPath\');\n }\n\n var startPos = TextPosition.fromCharOffset(startContainer, selector.startOffset);\n var endPos = TextPosition.fromCharOffset(endContainer, selector.endOffset);\n var range = new TextRange(startPos, endPos).toRange();\n return new RangeAnchor(root, range);\n }\n }]);\n\n return RangeAnchor;\n}()));\n/**\n * Converts between `TextPositionSelector` selectors and `Range` objects.\n */\n\nvar TextPositionAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n function TextPositionAnchor(root, start, end) {\n types_classCallCheck(this, TextPositionAnchor);\n\n this.root = root;\n this.start = start;\n this.end = end;\n }\n /**\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextPositionAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextPositionSelector}\n */\n function toSelector() {\n return {\n type: \'TextPositionSelector\',\n start: this.start,\n end: this.end\n };\n }\n }, {\n key: "toRange",\n value: function toRange() {\n return text_range_TextRange.fromOffsets(this.root, this.start, this.end).toRange();\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n return new TextPositionAnchor(root, textRange.start.offset, textRange.end.offset);\n }\n /**\n * @param {Element} root\n * @param {TextPositionSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n return new TextPositionAnchor(root, selector.start, selector.end);\n }\n }]);\n\n return TextPositionAnchor;\n}();\n/**\n * @typedef QuoteMatchOptions\n * @prop {number} [hint] - Expected position of match in text. See `matchQuote`.\n */\n\n/**\n * Converts between `TextQuoteSelector` selectors and `Range` objects.\n */\n\nvar TextQuoteAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root - A root element from which to anchor.\n * @param {string} exact\n * @param {Object} context\n * @param {string} [context.prefix]\n * @param {string} [context.suffix]\n */\n function TextQuoteAnchor(root, exact) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n types_classCallCheck(this, TextQuoteAnchor);\n\n this.root = root;\n this.exact = exact;\n this.context = context;\n }\n /**\n * Create a `TextQuoteAnchor` from a range.\n *\n * Will throw if `range` does not contain any text nodes.\n *\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextQuoteAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextQuoteSelector}\n */\n function toSelector() {\n return {\n type: \'TextQuoteSelector\',\n exact: this.exact,\n prefix: this.context.prefix,\n suffix: this.context.suffix\n };\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return this.toPositionAnchor(options).toRange();\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toPositionAnchor",\n value: function toPositionAnchor() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var text =\n /** @type {string} */\n this.root.textContent;\n var match = matchQuote(text, this.exact, _objectSpread(_objectSpread({}, this.context), {}, {\n hint: options.hint\n }));\n\n if (!match) {\n throw new Error(\'Quote not found\');\n }\n\n return new TextPositionAnchor(this.root, match.start, match.end);\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var text =\n /** @type {string} */\n root.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n var start = textRange.start.offset;\n var end = textRange.end.offset; // Number of characters around the quote to capture as context. We currently\n // always use a fixed amount, but it would be better if this code was aware\n // of logical boundaries in the document (paragraph, article etc.) to avoid\n // capturing text unrelated to the quote.\n //\n // In regular prose the ideal content would often be the surrounding sentence.\n // This is a natural unit of meaning which enables displaying quotes in\n // context even when the document is not available. We could use `Intl.Segmenter`\n // for this when available.\n\n var contextLen = 32;\n return new TextQuoteAnchor(root, text.slice(start, end), {\n prefix: text.slice(Math.max(0, start - contextLen), start),\n suffix: text.slice(end, Math.min(text.length, end + contextLen))\n });\n }\n /**\n * @param {Element} root\n * @param {TextQuoteSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var prefix = selector.prefix,\n suffix = selector.suffix;\n return new TextQuoteAnchor(root, selector.exact, {\n prefix: prefix,\n suffix: suffix\n });\n }\n }]);\n\n return TextQuoteAnchor;\n}();\n;// CONCATENATED MODULE: ./src/utils.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = utils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction utils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return utils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return utils_arrayLikeToArray(o, minLen); }\n\nfunction utils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n // Catch JS errors to log them in the app.\n\nwindow.addEventListener("error", function (event) {\n Android.logError(event.message, event.filename, event.lineno);\n}, false);\nwindow.addEventListener("load", function () {\n var observer = new ResizeObserver(function () {\n onViewportWidthChanged();\n snapCurrentOffset();\n });\n observer.observe(document.body);\n}, false);\n/**\n * Having an odd number of columns when displaying two columns per screen causes snapping and page\n * turning issues. To fix this, we insert a blank virtual column at the end of the resource.\n */\n\nfunction appendVirtualColumnIfNeeded() {\n var id = "readium-virtual-page";\n var virtualCol = document.getElementById(id);\n\n if (isScrollModeEnabled() || getColumnCountPerScreen() != 2) {\n if (virtualCol) {\n virtualCol.remove();\n }\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var colCount = documentWidth / pageWidth;\n var hasOddColCount = Math.round(colCount * 2) / 2 % 1 > 0.1;\n\n if (hasOddColCount) {\n if (virtualCol) {\n virtualCol.remove();\n } else {\n virtualCol = document.createElement("div");\n virtualCol.setAttribute("id", id);\n virtualCol.style.breakBefore = "column";\n virtualCol.innerHTML = "​"; // zero-width space\n\n document.body.appendChild(virtualCol);\n }\n }\n }\n}\n\nvar pageWidth = 1;\n\nfunction onViewportWidthChanged() {\n // We can\'t rely on window.innerWidth for the pageWidth on Android, because if the\n // device pixel ratio is not an integer, we get rounding issues offsetting the pages.\n //\n // See https://github.com/readium/readium-css/issues/97\n // and https://github.com/readium/r2-navigator-kotlin/issues/146\n var width = Android.getViewportWidth();\n pageWidth = width / window.devicePixelRatio;\n setProperty("--RS__viewportWidth", "calc(" + width + "px / " + window.devicePixelRatio + ")");\n appendVirtualColumnIfNeeded();\n}\n\nfunction getColumnCountPerScreen() {\n return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n}\nfunction isScrollModeEnabled() {\n var style = document.documentElement.style;\n return style.getPropertyValue("--USER__view").trim() == "readium-scroll-on" || // FIXME: Will need to be removed in Readium 3.0, --USER__scroll was incorrect.\n style.getPropertyValue("--USER__scroll").trim() == "readium-scroll-on";\n}\nfunction isRTL() {\n return document.body.dir.toLowerCase() == "rtl";\n} // Scroll to the given TagId in document and snap.\n\nfunction scrollToId(id) {\n var element = document.getElementById(id);\n\n if (!element) {\n return false;\n }\n\n return scrollToRect(element.getBoundingClientRect());\n} // Position must be in the range [0 - 1], 0-100%.\n\nfunction scrollToPosition(position) {\n // Android.log("scrollToPosition " + position);\n if (position < 0 || position > 1) {\n throw "scrollToPosition() must be given a position from 0.0 to 1.0";\n }\n\n var offset;\n\n if (isScrollModeEnabled()) {\n offset = document.scrollingElement.scrollHeight * position;\n document.scrollingElement.scrollTop = offset; // window.scrollTo(0, offset);\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var factor = isRTL() ? -1 : 1;\n offset = documentWidth * position * factor;\n document.scrollingElement.scrollLeft = snapOffset(offset);\n }\n} // Scrolls to the first occurrence of the given text snippet.\n//\n// The expected text argument is a Locator Text object, as defined here:\n// https://readium.org/architecture/models/locators/\n\nfunction scrollToText(text) {\n var range = rangeFromLocator({\n text: text\n });\n\n if (!range) {\n return false;\n }\n\n scrollToRange(range);\n return true;\n}\n\nfunction scrollToRange(range) {\n return scrollToRect(range.getBoundingClientRect());\n}\n\nfunction scrollToRect(rect) {\n if (isScrollModeEnabled()) {\n document.scrollingElement.scrollTop = rect.top + window.scrollY - window.innerHeight / 2;\n } else {\n document.scrollingElement.scrollLeft = snapOffset(rect.left + window.scrollX);\n }\n\n return true;\n}\n\nfunction scrollToStart() {\n // Android.log("scrollToStart");\n if (!isScrollModeEnabled()) {\n document.scrollingElement.scrollLeft = 0;\n } else {\n document.scrollingElement.scrollTop = 0;\n window.scrollTo(0, 0);\n }\n}\nfunction scrollToEnd() {\n // Android.log("scrollToEnd");\n if (!isScrollModeEnabled()) {\n var factor = isRTL() ? -1 : 1;\n document.scrollingElement.scrollLeft = snapOffset(document.scrollingElement.scrollWidth * factor);\n } else {\n document.scrollingElement.scrollTop = document.body.scrollHeight;\n window.scrollTo(0, document.body.scrollHeight);\n }\n} // Returns false if the page is already at the left-most scroll offset.\n\nfunction scrollLeft() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX - pageWidth;\n var minOffset = isRTL() ? -(documentWidth - pageWidth) : 0;\n return scrollToOffset(Math.max(offset, minOffset));\n} // Returns false if the page is already at the right-most scroll offset.\n\nfunction scrollRight() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX + pageWidth;\n var maxOffset = isRTL() ? 0 : documentWidth - pageWidth;\n return scrollToOffset(Math.min(offset, maxOffset));\n} // Scrolls to the given left offset.\n// Returns false if the page scroll position is already close enough to the given offset.\n\nfunction scrollToOffset(offset) {\n // Android.log("scrollToOffset " + offset);\n if (isScrollModeEnabled()) {\n throw "Called scrollToOffset() with scroll mode enabled. This can only be used in paginated mode.";\n }\n\n var currentOffset = window.scrollX;\n document.scrollingElement.scrollLeft = snapOffset(offset); // In some case the scrollX cannot reach the position respecting to innerWidth\n\n var diff = Math.abs(currentOffset - offset) / pageWidth;\n return diff > 0.01;\n} // Snap the offset to the screen width (page width).\n\n\nfunction snapOffset(offset) {\n var value = offset + (isRTL() ? -1 : 1);\n return value - value % pageWidth;\n} // Snaps the current offset to the page width.\n\n\nfunction snapCurrentOffset() {\n // Android.log("snapCurrentOffset");\n if (isScrollModeEnabled()) {\n return;\n }\n\n var currentOffset = window.scrollX; // Adds half a page to make sure we don\'t snap to the previous page.\n\n var factor = isRTL() ? -1 : 1;\n var delta = factor * (pageWidth / 2);\n document.scrollingElement.scrollLeft = snapOffset(currentOffset + delta);\n}\nfunction rangeFromLocator(locator) {\n try {\n var locations = locator.locations;\n var text = locator.text;\n\n if (text && text.highlight) {\n var root;\n\n if (locations && locations.cssSelector) {\n root = document.querySelector(locations.cssSelector);\n }\n\n if (!root) {\n root = document.body;\n }\n\n var anchor = new TextQuoteAnchor(root, text.highlight, {\n prefix: text.before,\n suffix: text.after\n });\n return anchor.toRange();\n }\n\n if (locations) {\n var element = null;\n\n if (!element && locations.cssSelector) {\n element = document.querySelector(locations.cssSelector);\n }\n\n if (!element && locations.fragments) {\n var _iterator = _createForOfIteratorHelper(locations.fragments),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var htmlId = _step.value;\n element = document.getElementById(htmlId);\n\n if (element) {\n break;\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n if (element) {\n var range = document.createRange();\n range.setStartBefore(element);\n range.setEndAfter(element);\n return range;\n }\n }\n } catch (e) {\n logError(e);\n }\n\n return null;\n} /// User Settings.\n\nfunction setCSSProperties(properties) {\n for (var name in properties) {\n setProperty(name, properties[name]);\n }\n} // For setting user setting.\n\nfunction setProperty(key, value) {\n if (value === null || value === "") {\n removeProperty(key);\n } else {\n var root = document.documentElement; // The `!important` annotation is added with `setProperty()` because if it\'s part of the\n // `value`, it will be ignored by the Web View.\n\n root.style.setProperty(key, value, "important");\n }\n} // For removing user setting.\n\nfunction removeProperty(key) {\n var root = document.documentElement;\n root.style.removeProperty(key);\n} /// Toolkit\n\nfunction log() {\n var message = Array.prototype.slice.call(arguments).join(" ");\n Android.log(message);\n}\nfunction logError(message) {\n Android.logError(message, "", 0);\n}\n;// CONCATENATED MODULE: ./src/rect.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction rect_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = rect_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction rect_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return rect_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return rect_arrayLikeToArray(o, minLen); }\n\nfunction rect_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nvar debug = false;\n/**\n * Converts a DOMRect into a JSON object understandable by the native side.\n */\n\nfunction toNativeRect(rect) {\n var pixelRatio = window.devicePixelRatio;\n var width = rect.width * pixelRatio;\n var height = rect.height * pixelRatio;\n var left = rect.left * pixelRatio;\n var top = rect.top * pixelRatio;\n var right = left + width;\n var bottom = top + height;\n return {\n width: width,\n height: height,\n left: left,\n top: top,\n right: right,\n bottom: bottom\n };\n}\nfunction getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var clientRects = range.getClientRects();\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator = rect_createForOfIteratorHelper(clientRects),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var rangeClientRect = _step.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n var mergedRects = mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = removeContainedRects(mergedRects, tolerance);\n var newRects = replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n rect_log("CLIENT RECT: remove small");\n newRects.splice(j, 1);\n } else {\n rect_log("CLIENT RECT: remove small, but keep otherwise empty!");\n break;\n }\n }\n }\n\n rect_log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n return newRects;\n}\n\nfunction mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("mergeTouchingRects rect1 === rect2 ??!");\n return "continue";\n }\n\n var rectsLineUpVertically = almostEqual(rect1.top, rect2.top, tolerance) && almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = almostEqual(rect1.left, rect2.left, tolerance) && almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n rect_log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret = _loop(j);\n\n if (_ret === "continue") continue;\n if (_typeof(_ret) === "object") return _ret.v;\n }\n }\n\n return rects;\n}\n\nfunction getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator2 = rect_createForOfIteratorHelper(rects),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var rect = _step2.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n rect_log("CLIENT RECT: remove tiny");\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator3 = rect_createForOfIteratorHelper(rects),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var possiblyContainingRect = _step3.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (rectContains(possiblyContainingRect, rect, tolerance)) {\n rect_log("CLIENT RECT: remove contained");\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction rectContains(rect1, rect2, tolerance) {\n return rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || almostEqual(rect.left, x, tolerance)) && (rect.right > x || almostEqual(rect.right, x, tolerance)) && (rect.top < y || almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("replaceOverlapingRects rect1 === rect2 ??!");\n continue;\n }\n\n if (rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret2 = function () {\n var toAdd = [];\n var toRemove = void 0;\n var subtractRects1 = rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n var subtractRects2 = rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n }\n }\n\n rect_log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: replaceOverlapingRects(newRects)\n };\n }();\n\n if (_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction rectSubtract(rect1, rect2) {\n var rectIntersected = rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n return {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n}\n\nfunction rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction rect_log() {\n if (debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/decorator.js\nfunction decorator_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = decorator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction decorator_slicedToArray(arr, i) { return decorator_arrayWithHoles(arr) || decorator_iterableToArrayLimit(arr, i) || decorator_unsupportedIterableToArray(arr, i) || decorator_nonIterableRest(); }\n\nfunction decorator_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction decorator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return decorator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return decorator_arrayLikeToArray(o, minLen); }\n\nfunction decorator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction decorator_iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction decorator_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nvar styles = new Map();\nvar groups = new Map();\nvar lastGroupId = 0;\n/**\n * Registers a list of additional supported Decoration Templates.\n *\n * Each template object is indexed by the style ID.\n */\n\nfunction registerTemplates(newStyles) {\n var stylesheet = "";\n\n for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = decorator_slicedToArray(_Object$entries[_i], 2),\n id = _Object$entries$_i[0],\n style = _Object$entries$_i[1];\n\n styles.set(id, style);\n\n if (style.stylesheet) {\n stylesheet += style.stylesheet + "\\n";\n }\n }\n\n if (stylesheet) {\n var styleElement = document.createElement("style");\n styleElement.innerHTML = stylesheet;\n document.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n}\n/**\n * Returns an instance of DecorationGroup for the given group name.\n */\n\nfunction getDecorations(groupName) {\n var group = groups.get(groupName);\n\n if (!group) {\n var id = "r2-decoration-" + lastGroupId++;\n group = DecorationGroup(id, groupName);\n groups.set(groupName, group);\n }\n\n return group;\n}\n/**\n * Handles click events on a Decoration.\n * Returns whether a decoration matched this event.\n */\n\nfunction handleDecorationClickEvent(event, clickEvent) {\n if (groups.size === 0) {\n return false;\n }\n\n function findTarget() {\n var _iterator = decorator_createForOfIteratorHelper(groups),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = decorator_slicedToArray(_step.value, 2),\n group = _step$value[0],\n groupContent = _step$value[1];\n\n var _iterator2 = decorator_createForOfIteratorHelper(groupContent.items.reverse()),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var item = _step2.value;\n\n if (!item.clickableElements) {\n continue;\n }\n\n var _iterator3 = decorator_createForOfIteratorHelper(item.clickableElements),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var element = _step3.value;\n var rect = element.getBoundingClientRect().toJSON();\n\n if (rectContainsPoint(rect, event.clientX, event.clientY, 1)) {\n return {\n group: group,\n item: item,\n element: element,\n rect: rect\n };\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var target = findTarget();\n\n if (!target) {\n return false;\n }\n\n return Android.onDecorationActivated(JSON.stringify({\n id: target.item.decoration.id,\n group: target.group,\n rect: toNativeRect(target.item.range.getBoundingClientRect()),\n click: clickEvent\n }));\n}\n/**\n * Creates a DecorationGroup object from a unique HTML ID and its name.\n */\n\nfunction DecorationGroup(groupId, groupName) {\n var items = [];\n var lastItemId = 0;\n var container = null;\n /**\n * Adds a new decoration to the group.\n */\n\n function add(decoration) {\n var id = groupId + "-" + lastItemId++;\n var range = rangeFromLocator(decoration.locator);\n\n if (!range) {\n log("Can\'t locate DOM range for decoration", decoration);\n return;\n }\n\n var item = {\n id: id,\n decoration: decoration,\n range: range\n };\n items.push(item);\n layout(item);\n }\n /**\n * Removes the decoration with given ID from the group.\n */\n\n\n function remove(decorationId) {\n var index = items.findIndex(function (i) {\n return i.decoration.id === decorationId;\n });\n\n if (index === -1) {\n return;\n }\n\n var item = items[index];\n items.splice(index, 1);\n item.clickableElements = null;\n\n if (item.container) {\n item.container.remove();\n item.container = null;\n }\n }\n /**\n * Notifies that the given decoration was modified and needs to be updated.\n */\n\n\n function update(decoration) {\n remove(decoration.id);\n add(decoration);\n }\n /**\n * Removes all decorations from this group.\n */\n\n\n function clear() {\n clearContainer();\n items.length = 0;\n }\n /**\n * Recreates the decoration elements.\n *\n * To be called after reflowing the resource, for example.\n */\n\n\n function requestLayout() {\n clearContainer();\n items.forEach(function (item) {\n return layout(item);\n });\n }\n /**\n * Layouts a single Decoration item.\n */\n\n\n function layout(item) {\n var groupContainer = requireContainer();\n var style = styles.get(item.decoration.style);\n\n if (!style) {\n logError("Unknown decoration style: ".concat(item.decoration.style));\n return;\n }\n\n var itemContainer = document.createElement("div");\n itemContainer.setAttribute("id", item.id);\n itemContainer.setAttribute("data-style", item.decoration.style);\n itemContainer.style.setProperty("pointer-events", "none");\n var viewportWidth = window.innerWidth;\n var columnCount = parseInt(getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n var pageWidth = viewportWidth / (columnCount || 1);\n var scrollingElement = document.scrollingElement;\n var xOffset = scrollingElement.scrollLeft;\n var yOffset = scrollingElement.scrollTop;\n\n function positionElement(element, rect, boundingRect) {\n element.style.position = "absolute";\n\n if (style.width === "wrap") {\n element.style.width = "".concat(rect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(rect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "viewport") {\n element.style.width = "".concat(viewportWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n var left = Math.floor(rect.left / viewportWidth) * viewportWidth;\n element.style.left = "".concat(left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "bounds") {\n element.style.width = "".concat(boundingRect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(boundingRect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "page") {\n element.style.width = "".concat(pageWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n\n var _left = Math.floor(rect.left / pageWidth) * pageWidth;\n\n element.style.left = "".concat(_left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n }\n }\n\n var boundingRect = item.range.getBoundingClientRect();\n var elementTemplate;\n\n try {\n var template = document.createElement("template");\n template.innerHTML = item.decoration.element.trim();\n elementTemplate = template.content.firstElementChild;\n } catch (error) {\n logError("Invalid decoration element \\"".concat(item.decoration.element, "\\": ").concat(error.message));\n return;\n }\n\n if (style.layout === "boxes") {\n var doNotMergeHorizontallyAlignedRects = true;\n var clientRects = getClientRectsNoOverlap(item.range, doNotMergeHorizontallyAlignedRects);\n clientRects = clientRects.sort(function (r1, r2) {\n if (r1.top < r2.top) {\n return -1;\n } else if (r1.top > r2.top) {\n return 1;\n } else {\n return 0;\n }\n });\n\n var _iterator4 = decorator_createForOfIteratorHelper(clientRects),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var clientRect = _step4.value;\n var line = elementTemplate.cloneNode(true);\n line.style.setProperty("pointer-events", "none");\n positionElement(line, clientRect, boundingRect);\n itemContainer.append(line);\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n } else if (style.layout === "bounds") {\n var bounds = elementTemplate.cloneNode(true);\n bounds.style.setProperty("pointer-events", "none");\n positionElement(bounds, boundingRect, boundingRect);\n itemContainer.append(bounds);\n }\n\n groupContainer.append(itemContainer);\n item.container = itemContainer;\n item.clickableElements = Array.from(itemContainer.querySelectorAll("[data-activable=\'1\']"));\n\n if (item.clickableElements.length === 0) {\n item.clickableElements = Array.from(itemContainer.children);\n }\n }\n /**\n * Returns the group container element, after making sure it exists.\n */\n\n\n function requireContainer() {\n if (!container) {\n container = document.createElement("div");\n container.setAttribute("id", groupId);\n container.setAttribute("data-group", groupName);\n container.style.setProperty("pointer-events", "none");\n document.body.append(container);\n }\n\n return container;\n }\n /**\n * Removes the group container.\n */\n\n\n function clearContainer() {\n if (container) {\n container.remove();\n container = null;\n }\n }\n\n return {\n add: add,\n remove: remove,\n update: update,\n clear: clear,\n items: items,\n requestLayout: requestLayout\n };\n}\nwindow.addEventListener("load", function () {\n // Will relayout all the decorations when the document body is resized.\n var body = document.body;\n var lastSize = {\n width: 0,\n height: 0\n };\n var observer = new ResizeObserver(function () {\n if (lastSize.width === body.clientWidth && lastSize.height === body.clientHeight) {\n return;\n }\n\n lastSize = {\n width: body.clientWidth,\n height: body.clientHeight\n };\n groups.forEach(function (group) {\n group.requestLayout();\n });\n });\n observer.observe(body);\n}, false);\n// EXTERNAL MODULE: ./node_modules/css-selector-generator/build/index.js\nvar build = __webpack_require__(4766);\n;// CONCATENATED MODULE: ./src/dom.js\n//\n// Copyright 2022 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n // See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling\n\nfunction nearestInteractiveElement(element) {\n if (element == null) {\n return null;\n }\n\n var interactiveTags = ["a", "audio", "button", "canvas", "details", "input", "label", "option", "select", "submit", "textarea", "video"];\n\n if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) {\n return element.outerHTML;\n } // Checks whether the element is editable by the user.\n\n\n if (element.hasAttribute("contenteditable") && element.getAttribute("contenteditable").toLowerCase() != "false") {\n return element.outerHTML;\n } // Checks parents recursively because the touch might be for example on an inside a .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n}\n;// CONCATENATED MODULE: ./src/keyboard.js\n//\n// Copyright 2023 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nwindow.addEventListener("keydown", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "down");\n});\nwindow.addEventListener("keyup", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "up");\n});\n\nfunction shouldIgnoreEvent(event) {\n return event.defaultPrevented || nearestInteractiveElement(document.activeElement) != null;\n} // We prevent the default behavior for keyboard events, otherwise the web view\n// might scroll.\n\n\nfunction preventDefault(event) {\n event.stopPropagation();\n event.preventDefault();\n}\n\nfunction sendPressKeyMessage(event, type) {\n if (event.repeat) return;\n var keyEvent = {\n type: type,\n code: event.code,\n characters: String.fromCharCode(event.keyCode),\n alt: event.altKey,\n control: event.ctrlKey,\n shift: event.shiftKey,\n meta: event.metaKey\n };\n Android.onKey(JSON.stringify(keyEvent));\n}\n;// CONCATENATED MODULE: ./src/highlight.js\nfunction highlight_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { highlight_typeof = function _typeof(obj) { return typeof obj; }; } else { highlight_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return highlight_typeof(obj); }\n\nfunction highlight_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = highlight_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction highlight_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return highlight_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return highlight_arrayLikeToArray(o, minLen); }\n\nfunction highlight_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/* eslint-disable */\n//\n// highlight.js\n// r2-navigator-kotlin\n//\n// Organized by Taehyun Kim on 6/27/19 from r2-navigator-js.\n//\n// Copyright 2019 Readium Foundation. All rights reserved.\n// Use of this source code is governed by a BSD-style license which is detailed\n// in the LICENSE file present in the project repository where this source code is maintained.\n//\nvar ROOT_CLASS_REDUCE_MOTION = "r2-reduce-motion";\nvar ROOT_CLASS_NO_FOOTNOTES = "r2-no-popup-foonotes";\nvar POPUP_DIALOG_CLASS = "r2-popup-dialog";\nvar FOOTNOTES_CONTAINER_CLASS = "r2-footnote-container";\nvar FOOTNOTES_CLOSE_BUTTON_CLASS = "r2-footnote-close";\nvar FOOTNOTE_FORCE_SHOW = "r2-footnote-force-show";\nvar TTS_ID_PREVIOUS = "r2-tts-previous";\nvar TTS_ID_NEXT = "r2-tts-next";\nvar TTS_ID_SLIDER = "r2-tts-slider";\nvar TTS_ID_ACTIVE_WORD = "r2-tts-active-word";\nvar TTS_ID_CONTAINER = "r2-tts-txt";\nvar TTS_ID_INFO = "r2-tts-info";\nvar TTS_NAV_BUTTON_CLASS = "r2-tts-button";\nvar TTS_ID_SPEAKING_DOC_ELEMENT = "r2-tts-speaking-el";\nvar TTS_CLASS_INJECTED_SPAN = "r2-tts-speaking-txt";\nvar TTS_CLASS_INJECTED_SUBSPAN = "r2-tts-speaking-word";\nvar TTS_ID_INJECTED_PARENT = "r2-tts-speaking-txt-parent";\nvar ID_HIGHLIGHTS_CONTAINER = "R2_ID_HIGHLIGHTS_CONTAINER";\nvar ID_ANNOTATION_CONTAINER = "R2_ID_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_CONTAINER = "R2_CLASS_HIGHLIGHT_CONTAINER";\nvar CLASS_ANNOTATION_CONTAINER = "R2_CLASS_ANNOTATION_CONTAINER";\nvar CLASS_HIGHLIGHT_AREA = "R2_CLASS_HIGHLIGHT_AREA";\nvar CLASS_ANNOTATION_AREA = "R2_CLASS_ANNOTATION_AREA";\nvar CLASS_HIGHLIGHT_BOUNDING_AREA = "R2_CLASS_HIGHLIGHT_BOUNDING_AREA";\nvar CLASS_ANNOTATION_BOUNDING_AREA = "R2_CLASS_ANNOTATION_BOUNDING_AREA"; // tslint:disable-next-line:max-line-length\n\nvar _blacklistIdClassForCFI = [POPUP_DIALOG_CLASS, TTS_CLASS_INJECTED_SPAN, TTS_CLASS_INJECTED_SUBSPAN, ID_HIGHLIGHTS_CONTAINER, CLASS_HIGHLIGHT_CONTAINER, CLASS_HIGHLIGHT_AREA, CLASS_HIGHLIGHT_BOUNDING_AREA, "resize-sensor"];\nvar CLASS_PAGINATED = "r2-css-paginated"; //const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");\n\nvar IS_DEV = false;\nvar _highlights = [];\n\nvar _highlightsContainer;\n\nvar _annotationContainer;\n\nvar lastMouseDownX = -1;\nvar lastMouseDownY = -1;\nvar bodyEventListenersSet = false;\nvar USE_SVG = false;\nvar DEFAULT_BACKGROUND_COLOR_OPACITY = 0.3;\nvar ALT_BACKGROUND_COLOR_OPACITY = 0.45; //const DEBUG_VISUALS = false;\n\nvar DEBUG_VISUALS = false;\nvar DEFAULT_BACKGROUND_COLOR = {\n blue: 100,\n green: 50,\n red: 230\n};\nvar ANNOTATION_WIDTH = 15;\n\nfunction resetHighlightBoundingStyle(_win, highlightBounding) {\n if (highlightBounding.getAttribute("class") == CLASS_ANNOTATION_BOUNDING_AREA) {\n return;\n }\n\n highlightBounding.style.outline = "none";\n highlightBounding.style.setProperty("background-color", "transparent", "important");\n}\n\nfunction setHighlightAreaStyle(win, highlightAreas, highlight) {\n var useSVG = !DEBUG_VISUALS && USE_SVG;\n\n var _iterator = highlight_createForOfIteratorHelper(highlightAreas),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var highlightArea = _step.value;\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var opacity = ALT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n}\n\nfunction resetHighlightAreaStyle(win, highlightArea) {\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var isSVG = useSVG && highlightArea.namespaceURI === SVG_XML_NAMESPACE;\n var id = isSVG ? highlightArea.parentNode && highlightArea.parentNode.parentNode && highlightArea.parentNode.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.parentNode.getAttribute ? highlightArea.parentNode.parentNode.getAttribute("id") : undefined : highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && highlightArea.parentNode.getAttribute ? highlightArea.parentNode.getAttribute("id") : undefined;\n\n if (id) {\n var highlight = _highlights.find(function (h) {\n return h.id === id;\n });\n\n if (highlight) {\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n\n if (isSVG) {\n highlightArea.style.setProperty("fill", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("fill-opacity", "".concat(opacity), "important");\n highlightArea.style.setProperty("stroke", "rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ")"), "important");\n highlightArea.style.setProperty("stroke-opacity", "".concat(opacity), "important");\n } else {\n highlightArea.style.setProperty("background-color", "rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ")"), "important");\n }\n }\n }\n}\n\nfunction processTouchEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.changedTouches[0].clientX;\n var y = ev.changedTouches[0].clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect; // _highlights.sort(function(a, b) {\n // console.log(JSON.stringify(a.selectionInfo))\n // return a.selectionInfo.cleanText.length < b.selectionInfo.cleanText.length\n // })\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator2 = highlight_createForOfIteratorHelper(highlightFragments),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var highlightFragment = _step2.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator3 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var highlightBounding = _step3.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i = 0, _allHighlightAreas = allHighlightAreas; _i < _allHighlightAreas.length; _i++) {\n var highlightArea = _allHighlightAreas[_i];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas2 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator4 = highlight_createForOfIteratorHelper(_allHighlightAreas2),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var _highlightArea = _step4.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea) < 0) {\n resetHighlightAreaStyle(win, _highlightArea);\n }\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator5 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step5;\n\n try {\n for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {\n var _highlightBounding = _step5.value;\n\n if (!foundElementHighlightBounding || _highlightBounding !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding);\n }\n }\n } catch (err) {\n _iterator5.e(err);\n } finally {\n _iterator5.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "touchstart" || ev.type === "touchend") {\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight.id,\n size: size\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n console.log(foundHighlight.id.includes("R2_ANNOTATION_"));\n\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n}\n\nfunction processMouseEvent(win, ev) {\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var x = ev.clientX;\n var y = ev.clientY;\n\n if (!_highlightsContainer) {\n return;\n }\n\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var xOffset;\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var foundHighlight;\n var foundElement;\n var foundRect;\n\n for (var i = _highlights.length - 1; i >= 0; i--) {\n var highlight = _highlights[i];\n var highlightParent = document.getElementById("".concat(highlight.id));\n\n if (!highlightParent) {\n highlightParent = _highlightsContainer.querySelector("#".concat(highlight.id));\n }\n\n if (!highlightParent) {\n continue;\n }\n\n var hit = false;\n var highlightFragments = highlightParent.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator6 = highlight_createForOfIteratorHelper(highlightFragments),\n _step6;\n\n try {\n for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {\n var highlightFragment = _step6.value;\n var withRect = highlightFragment;\n var left = withRect.rect.left + xOffset;\n var top = withRect.rect.top + yOffset;\n foundRect = withRect.rect;\n\n if (x >= left && x < left + withRect.rect.width && y >= top && y < top + withRect.rect.height) {\n hit = true;\n break;\n }\n }\n } catch (err) {\n _iterator6.e(err);\n } finally {\n _iterator6.f();\n }\n\n if (hit) {\n foundHighlight = highlight;\n foundElement = highlightParent;\n break;\n }\n }\n\n if (!foundHighlight || !foundElement) {\n var highlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator7 = highlight_createForOfIteratorHelper(highlightBoundings),\n _step7;\n\n try {\n for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {\n var highlightBounding = _step7.value;\n resetHighlightBoundingStyle(win, highlightBounding);\n }\n } catch (err) {\n _iterator7.e(err);\n } finally {\n _iterator7.f();\n }\n\n var allHighlightAreas = Array.from(_highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n for (var _i2 = 0, _allHighlightAreas3 = allHighlightAreas; _i2 < _allHighlightAreas3.length; _i2++) {\n var highlightArea = _allHighlightAreas3[_i2];\n resetHighlightAreaStyle(win, highlightArea);\n }\n\n return;\n }\n\n if (foundElement.getAttribute("data-click")) {\n if (ev.type === "mousemove") {\n var foundElementHighlightAreas = Array.from(foundElement.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA)));\n\n var _allHighlightAreas4 = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_AREA));\n\n var _iterator8 = highlight_createForOfIteratorHelper(_allHighlightAreas4),\n _step8;\n\n try {\n for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {\n var _highlightArea2 = _step8.value;\n\n if (foundElementHighlightAreas.indexOf(_highlightArea2) < 0) {\n resetHighlightAreaStyle(win, _highlightArea2);\n }\n }\n } catch (err) {\n _iterator8.e(err);\n } finally {\n _iterator8.f();\n }\n\n setHighlightAreaStyle(win, foundElementHighlightAreas, foundHighlight);\n var foundElementHighlightBounding = foundElement.querySelector(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var allHighlightBoundings = _highlightsContainer.querySelectorAll(".".concat(CLASS_HIGHLIGHT_BOUNDING_AREA));\n\n var _iterator9 = highlight_createForOfIteratorHelper(allHighlightBoundings),\n _step9;\n\n try {\n for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {\n var _highlightBounding2 = _step9.value;\n\n if (!foundElementHighlightBounding || _highlightBounding2 !== foundElementHighlightBounding) {\n resetHighlightBoundingStyle(win, _highlightBounding2);\n }\n }\n } catch (err) {\n _iterator9.e(err);\n } finally {\n _iterator9.f();\n }\n\n if (foundElementHighlightBounding) {\n if (DEBUG_VISUALS) {\n setHighlightBoundingStyle(win, foundElementHighlightBounding, foundHighlight);\n }\n }\n } else if (ev.type === "mouseup" || ev.type === "touchend") {\n var touchedPosition = {\n screenWidth: window.outerWidth,\n screenHeight: window.innerHeight,\n left: foundRect.left,\n width: foundRect.width,\n top: foundRect.top,\n height: foundRect.height\n };\n var payload = {\n highlight: foundHighlight,\n position: touchedPosition\n };\n\n if (typeof window !== "undefined" && highlight_typeof(window.process) === "object" && window.process.type === "renderer") {\n electron_1.ipcRenderer.sendToHost(R2_EVENT_HIGHLIGHT_CLICK, payload);\n } else if (window.webkitURL) {\n if (foundHighlight.id.search("R2_ANNOTATION_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightAnnotationMarkActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightAnnotationMarkActivated.postMessage(foundHighlight.id);\n }\n } else if (foundHighlight.id.search("R2_HIGHLIGHT_") >= 0) {\n if (navigator.userAgent.match(/Android/i)) {\n Android.highlightActivated(foundHighlight.id);\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n webkit.messageHandlers.highlightActivated.postMessage(foundHighlight.id);\n }\n }\n }\n\n ev.stopPropagation();\n }\n }\n}\n\nfunction highlight_rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && highlight_almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && highlight_almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && highlight_almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && highlight_almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction highlight_replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("replaceOverlapingRects rect1 === rect2 ??!");\n }\n\n continue;\n }\n\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret = function () {\n var toAdd = [];\n var toRemove = void 0;\n var toPreserve = void 0;\n var subtractRects1 = highlight_rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n var subtractRects2 = highlight_rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n toPreserve = rect2;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n toPreserve = rect1;\n }\n }\n\n if (IS_DEV) {\n var toCheck = [];\n toCheck.push(toPreserve);\n Array.prototype.push.apply(toCheck, toAdd);\n checkOverlaps(toCheck);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: highlight_replaceOverlapingRects(newRects)\n };\n }();\n\n if (highlight_typeof(_ret) === "object") return _ret.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction checkOverlaps(rects) {\n var stillOverlapingRects = [];\n\n var _iterator10 = highlight_createForOfIteratorHelper(rects),\n _step10;\n\n try {\n for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {\n var rect1 = _step10.value;\n\n var _iterator11 = highlight_createForOfIteratorHelper(rects),\n _step11;\n\n try {\n for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {\n var rect2 = _step11.value;\n\n if (rect1 === rect2) {\n continue;\n }\n\n var has1 = stillOverlapingRects.indexOf(rect1) >= 0;\n var has2 = stillOverlapingRects.indexOf(rect2) >= 0;\n\n if (!has1 || !has2) {\n if (highlight_rectsTouchOrOverlap(rect1, rect2, -1)) {\n if (!has1) {\n stillOverlapingRects.push(rect1);\n }\n\n if (!has2) {\n stillOverlapingRects.push(rect2);\n }\n\n console.log("CLIENT RECT: overlap ---");\n console.log("#1 TOP:".concat(rect1.top, " BOTTOM:").concat(rect1.bottom, " LEFT:").concat(rect1.left, " RIGHT:").concat(rect1.right, " WIDTH:").concat(rect1.width, " HEIGHT:").concat(rect1.height));\n console.log("#2 TOP:".concat(rect2.top, " BOTTOM:").concat(rect2.bottom, " LEFT:").concat(rect2.left, " RIGHT:").concat(rect2.right, " WIDTH:").concat(rect2.width, " HEIGHT:").concat(rect2.height));\n var xOverlap = getRectOverlapX(rect1, rect2);\n console.log("xOverlap: ".concat(xOverlap));\n var yOverlap = getRectOverlapY(rect1, rect2);\n console.log("yOverlap: ".concat(yOverlap));\n }\n }\n }\n } catch (err) {\n _iterator11.e(err);\n } finally {\n _iterator11.f();\n }\n }\n } catch (err) {\n _iterator10.e(err);\n } finally {\n _iterator10.f();\n }\n\n if (stillOverlapingRects.length) {\n console.log("CLIENT RECT: overlaps ".concat(stillOverlapingRects.length));\n }\n}\n\nfunction highlight_removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator12 = highlight_createForOfIteratorHelper(rects),\n _step12;\n\n try {\n for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {\n var rect = _step12.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove tiny");\n }\n\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator13 = highlight_createForOfIteratorHelper(rects),\n _step13;\n\n try {\n for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {\n var possiblyContainingRect = _step13.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (highlight_rectContains(possiblyContainingRect, rect, tolerance)) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove contained");\n }\n\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator13.e(err);\n } finally {\n _iterator13.f();\n }\n }\n } catch (err) {\n _iterator12.e(err);\n } finally {\n _iterator12.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction highlight_almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction highlight_rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n var rect = {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n return rect;\n}\n\nfunction highlight_rectSubtract(rect1, rect2) {\n var rectIntersected = highlight_rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction highlight_rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || highlight_almostEqual(rect.left, x, tolerance)) && (rect.right > x || highlight_almostEqual(rect.right, x, tolerance)) && (rect.top < y || highlight_almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || highlight_almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction highlight_rectContains(rect1, rect2, tolerance) {\n return highlight_rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && highlight_rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && highlight_rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction highlight_getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction highlight_mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n if (IS_DEV) {\n console.log("mergeTouchingRects rect1 === rect2 ??!");\n }\n\n return "continue";\n }\n\n var rectsLineUpVertically = highlight_almostEqual(rect1.top, rect2.top, tolerance) && highlight_almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = highlight_almostEqual(rect1.left, rect2.left, tolerance) && highlight_almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && highlight_rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n if (IS_DEV) {\n console.log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n }\n\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = highlight_getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: highlight_mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret2 = _loop(j);\n\n if (_ret2 === "continue") continue;\n if (highlight_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n\n return rects;\n}\n\nfunction highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var rangeClientRects = range.getClientRects();\n return getClientRectsNoOverlap_(rangeClientRects, doNotMergeHorizontallyAlignedRects);\n}\n\nfunction getClientRectsNoOverlap_(clientRects, doNotMergeHorizontallyAlignedRects) {\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator14 = highlight_createForOfIteratorHelper(clientRects),\n _step14;\n\n try {\n for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {\n var rangeClientRect = _step14.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator14.e(err);\n } finally {\n _iterator14.f();\n }\n\n var mergedRects = highlight_mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = highlight_removeContainedRects(mergedRects, tolerance);\n var newRects = highlight_replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small");\n }\n\n newRects.splice(j, 1);\n } else {\n if (IS_DEV) {\n console.log("CLIENT RECT: remove small, but keep otherwise empty!");\n }\n\n break;\n }\n }\n }\n\n if (IS_DEV) {\n checkOverlaps(newRects);\n }\n\n if (IS_DEV) {\n console.log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n }\n\n return newRects;\n}\n\nfunction isPaginated(document) {\n return document && document.documentElement && document.documentElement.classList.contains(CLASS_PAGINATED);\n}\n\nfunction getScrollingElement(document) {\n if (document.scrollingElement) {\n return document.scrollingElement;\n }\n\n return document.body;\n}\n\nfunction ensureContainer(win, annotationFlag) {\n var document = win.document;\n\n if (!_highlightsContainer) {\n if (!bodyEventListenersSet) {\n bodyEventListenersSet = true;\n document.body.addEventListener("mousedown", function (ev) {\n lastMouseDownX = ev.clientX;\n lastMouseDownY = ev.clientY;\n }, false);\n document.body.addEventListener("mouseup", function (ev) {\n if (Math.abs(lastMouseDownX - ev.clientX) < 3 && Math.abs(lastMouseDownY - ev.clientY) < 3) {\n processMouseEvent(win, ev);\n }\n }, false);\n document.body.addEventListener("mousemove", function (ev) {\n processMouseEvent(win, ev);\n }, false);\n document.body.addEventListener("touchend", function touchEnd(e) {\n processTouchEvent(win, e);\n }, false);\n }\n\n _highlightsContainer = document.createElement("div");\n\n _highlightsContainer.setAttribute("id", ID_HIGHLIGHTS_CONTAINER);\n\n _highlightsContainer.style.setProperty("pointer-events", "none");\n\n document.body.append(_highlightsContainer);\n }\n\n return _highlightsContainer;\n}\n\nfunction hideAllhighlights() {\n if (_highlightsContainer) {\n _highlightsContainer.remove();\n\n _highlightsContainer = null;\n }\n}\n\nfunction destroyAllhighlights() {\n hideAllhighlights();\n\n _highlights.splice(0, _highlights.length);\n}\n\nfunction destroyHighlight(id) {\n var i = -1;\n var _document = window.document;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (highlight && i >= 0 && i < _highlights.length) {\n _highlights.splice(i, 1);\n }\n\n var highlightContainer = _document.getElementById(id);\n\n if (highlightContainer) {\n highlightContainer.remove();\n }\n}\n\nfunction isCfiTextNode(node) {\n return node.nodeType !== Node.ELEMENT_NODE;\n}\n\nfunction getChildTextNodeCfiIndex(element, child) {\n var found = -1;\n var textNodeIndex = -1;\n var previousWasElement = false;\n\n for (var i = 0; i < element.childNodes.length; i++) {\n var childNode = element.childNodes[i];\n var isText = isCfiTextNode(childNode);\n\n if (isText || previousWasElement) {\n textNodeIndex += 2;\n }\n\n if (isText) {\n if (childNode === child) {\n found = textNodeIndex;\n break;\n }\n }\n\n previousWasElement = childNode.nodeType === Node.ELEMENT_NODE;\n }\n\n return found;\n}\n\nfunction getCommonAncestorElement(node1, node2) {\n if (node1.nodeType === Node.ELEMENT_NODE && node1 === node2) {\n return node1;\n }\n\n if (node1.nodeType === Node.ELEMENT_NODE && node1.contains(node2)) {\n return node1;\n }\n\n if (node2.nodeType === Node.ELEMENT_NODE && node2.contains(node1)) {\n return node2;\n }\n\n var node1ElementAncestorChain = [];\n var parent = node1.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node1ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var node2ElementAncestorChain = [];\n parent = node2.parentNode;\n\n while (parent && parent.nodeType === Node.ELEMENT_NODE) {\n node2ElementAncestorChain.push(parent);\n parent = parent.parentNode;\n }\n\n var commonAncestor = node1ElementAncestorChain.find(function (node1ElementAncestor) {\n return node2ElementAncestorChain.indexOf(node1ElementAncestor) >= 0;\n });\n\n if (!commonAncestor) {\n commonAncestor = node2ElementAncestorChain.find(function (node2ElementAncestor) {\n return node1ElementAncestorChain.indexOf(node2ElementAncestor) >= 0;\n });\n }\n\n return commonAncestor;\n}\n\nfunction fullQualifiedSelector(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n return lowerCaseName;\n } //return cssPath(node, justSelector);\n\n\n return cssPath(node, true);\n}\n\nfunction getCurrentSelectionInfo() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n console.log("^^^ SELECTION COLLAPSED.");\n return undefined;\n }\n\n var rawText = selection.toString();\n var cleanText = rawText.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanText.length === 0) {\n console.log("^^^ SELECTION TEXT EMPTY.");\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n console.log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var rangeInfo = convertRange(range, fullQualifiedSelector, computeCFI);\n\n if (!rangeInfo) {\n console.log("^^^ SELECTION RANGE INFO FAIL?!");\n return undefined;\n }\n\n if (IS_DEV && DEBUG_VISUALS) {\n var restoredRange = convertRangeInfo(win.document, rangeInfo);\n\n if (restoredRange) {\n if (restoredRange.startOffset === range.startOffset && restoredRange.endOffset === range.endOffset && restoredRange.startContainer === range.startContainer && restoredRange.endContainer === range.endContainer) {\n console.log("SELECTION RANGE RESTORED OKAY (dev check).");\n } else {\n console.log("SELECTION RANGE RESTORE FAIL (dev check).");\n dumpDebug("SELECTION", selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset, getCssSelector);\n dumpDebug("ORDERED RANGE FROM SELECTION", range.startContainer, range.startOffset, range.endContainer, range.endOffset, getCssSelector);\n dumpDebug("RESTORED RANGE", restoredRange.startContainer, restoredRange.startOffset, restoredRange.endContainer, restoredRange.endOffset, getCssSelector);\n }\n } else {\n console.log("CANNOT RESTORE SELECTION RANGE ??!");\n }\n } else {}\n\n return {\n locations: rangeInfo2Location(rangeInfo),\n text: {\n highlight: rawText\n }\n };\n}\n\nfunction checkBlacklisted(el) {\n var blacklistedId;\n var id = el.getAttribute("id");\n\n if (id && _blacklistIdClassForCFI.indexOf(id) >= 0) {\n console.log("checkBlacklisted ID: " + id);\n blacklistedId = id;\n }\n\n var blacklistedClass;\n\n var _iterator15 = highlight_createForOfIteratorHelper(_blacklistIdClassForCFI),\n _step15;\n\n try {\n for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {\n var item = _step15.value;\n\n if (el.classList.contains(item)) {\n console.log("checkBlacklisted CLASS: " + item);\n blacklistedClass = item;\n break;\n }\n }\n } catch (err) {\n _iterator15.e(err);\n } finally {\n _iterator15.f();\n }\n\n if (blacklistedId || blacklistedClass) {\n return true;\n }\n\n return false;\n}\n\nfunction cssPath(node, optimized) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return "";\n }\n\n var steps = [];\n var contextNode = node;\n\n while (contextNode) {\n var step = _cssPathStep(contextNode, !!optimized, contextNode === node);\n\n if (!step) {\n break; // Error - bail out early.\n }\n\n steps.push(step.value);\n\n if (step.optimized) {\n break;\n }\n\n contextNode = contextNode.parentNode;\n }\n\n steps.reverse();\n return steps.join(" > ");\n} // tslint:disable-next-line:max-line-length\n// https://chromium.googlesource.com/chromium/blink/+/master/Source/devtools/front_end/components/DOMPresentationUtils.js#316\n\n\nfunction _cssPathStep(node, optimized, isTargetNode) {\n function prefixedElementClassNames(nd) {\n var classAttribute = nd.getAttribute("class");\n\n if (!classAttribute) {\n return [];\n }\n\n return classAttribute.split(/\\s+/g).filter(Boolean).map(function (nm) {\n // The prefix is required to store "__proto__" in a object-based map.\n return "$" + nm;\n });\n }\n\n function idSelector(idd) {\n return "#" + escapeIdentifierIfNeeded(idd);\n }\n\n function escapeIdentifierIfNeeded(ident) {\n if (isCSSIdentifier(ident)) {\n return ident;\n }\n\n var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);\n var lastIndex = ident.length - 1;\n return ident.replace(/./g, function (c, ii) {\n return shouldEscapeFirst && ii === 0 || !isCSSIdentChar(c) ? escapeAsciiChar(c, ii === lastIndex) : c;\n });\n }\n\n function escapeAsciiChar(c, isLast) {\n return "\\\\" + toHexByte(c) + (isLast ? "" : " ");\n }\n\n function toHexByte(c) {\n var hexByte = c.charCodeAt(0).toString(16);\n\n if (hexByte.length === 1) {\n hexByte = "0" + hexByte;\n }\n\n return hexByte;\n }\n\n function isCSSIdentChar(c) {\n if (/[a-zA-Z0-9_-]/.test(c)) {\n return true;\n }\n\n return c.charCodeAt(0) >= 0xa0;\n }\n\n function isCSSIdentifier(value) {\n return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var lowerCaseName = node.localName && node.localName.toLowerCase() || node.nodeName.toLowerCase();\n var element = node;\n var id = element.getAttribute("id");\n\n if (optimized) {\n if (id) {\n return {\n optimized: true,\n value: idSelector(id)\n };\n }\n\n if (lowerCaseName === "body" || lowerCaseName === "head" || lowerCaseName === "html") {\n return {\n optimized: true,\n value: lowerCaseName // node.nodeNameInCorrectCase(),\n\n };\n }\n }\n\n var nodeName = lowerCaseName; // node.nodeNameInCorrectCase();\n\n if (id) {\n return {\n optimized: true,\n value: nodeName + idSelector(id)\n };\n }\n\n var parent = node.parentNode;\n\n if (!parent || parent.nodeType === Node.DOCUMENT_NODE) {\n return {\n optimized: true,\n value: nodeName\n };\n }\n\n var prefixedOwnClassNamesArray_ = prefixedElementClassNames(element);\n var prefixedOwnClassNamesArray = []; // .keySet()\n\n prefixedOwnClassNamesArray_.forEach(function (arrItem) {\n if (prefixedOwnClassNamesArray.indexOf(arrItem) < 0) {\n prefixedOwnClassNamesArray.push(arrItem);\n }\n });\n var needsClassNames = false;\n var needsNthChild = false;\n var ownIndex = -1;\n var elementIndex = -1;\n var siblings = parent.children;\n\n var _loop2 = function _loop2(i) {\n var sibling = siblings[i];\n\n if (sibling.nodeType !== Node.ELEMENT_NODE) {\n return "continue";\n }\n\n elementIndex += 1;\n\n if (sibling === node) {\n ownIndex = elementIndex;\n return "continue";\n }\n\n if (needsNthChild) {\n return "continue";\n } // sibling.nodeNameInCorrectCase()\n\n\n var siblingName = sibling.localName && sibling.localName.toLowerCase() || sibling.nodeName.toLowerCase();\n\n if (siblingName !== nodeName) {\n return "continue";\n }\n\n needsClassNames = true;\n var ownClassNames = [];\n prefixedOwnClassNamesArray.forEach(function (arrItem) {\n ownClassNames.push(arrItem);\n });\n var ownClassNameCount = ownClassNames.length;\n\n if (ownClassNameCount === 0) {\n needsNthChild = true;\n return "continue";\n }\n\n var siblingClassNamesArray_ = prefixedElementClassNames(sibling);\n var siblingClassNamesArray = []; // .keySet()\n\n siblingClassNamesArray_.forEach(function (arrItem) {\n if (siblingClassNamesArray.indexOf(arrItem) < 0) {\n siblingClassNamesArray.push(arrItem);\n }\n });\n\n for (var _i3 = 0, _siblingClassNamesArr = siblingClassNamesArray; _i3 < _siblingClassNamesArr.length; _i3++) {\n var siblingClass = _siblingClassNamesArr[_i3];\n var ind = ownClassNames.indexOf(siblingClass);\n\n if (ind < 0) {\n continue;\n }\n\n ownClassNames.splice(ind, 1); // delete ownClassNames[siblingClass];\n\n if (! --ownClassNameCount) {\n needsNthChild = true;\n break;\n }\n }\n };\n\n for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {\n var _ret3 = _loop2(i);\n\n if (_ret3 === "continue") continue;\n }\n\n var result = nodeName;\n\n if (isTargetNode && nodeName === "input" && element.getAttribute("type") && !element.getAttribute("id") && !element.getAttribute("class")) {\n result += \'[type="\' + element.getAttribute("type") + \'"]\';\n }\n\n if (needsNthChild) {\n result += ":nth-child(" + (ownIndex + 1) + ")";\n } else if (needsClassNames) {\n var _iterator16 = highlight_createForOfIteratorHelper(prefixedOwnClassNamesArray),\n _step16;\n\n try {\n for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {\n var prefixedName = _step16.value;\n result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));\n }\n } catch (err) {\n _iterator16.e(err);\n } finally {\n _iterator16.f();\n }\n }\n\n return {\n optimized: false,\n value: result\n };\n}\n\nfunction computeCFI(node) {\n // TODO: handle character position inside text node\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return undefined;\n }\n\n var cfi = "";\n var currentElement = node;\n\n while (currentElement.parentNode && currentElement.parentNode.nodeType === Node.ELEMENT_NODE) {\n var blacklisted = checkBlacklisted(currentElement);\n\n if (!blacklisted) {\n var currentElementParentChildren = currentElement.parentNode.children;\n var currentElementIndex = -1;\n\n for (var i = 0; i < currentElementParentChildren.length; i++) {\n if (currentElement === currentElementParentChildren[i]) {\n currentElementIndex = i;\n break;\n }\n }\n\n if (currentElementIndex >= 0) {\n var cfiIndex = (currentElementIndex + 1) * 2;\n cfi = cfiIndex + (currentElement.id ? "[" + currentElement.id + "]" : "") + (cfi.length ? "/" + cfi : "");\n }\n }\n\n currentElement = currentElement.parentNode;\n }\n\n return "/" + cfi;\n}\n\nfunction _createHighlight(locations, color, pointerInteraction, type) {\n var rangeInfo = location2RangeInfo(locations);\n var uniqueStr = "".concat(rangeInfo.cfi).concat(rangeInfo.startContainerElementCssSelector).concat(rangeInfo.startContainerChildTextNodeIndex).concat(rangeInfo.startOffset).concat(rangeInfo.endContainerElementCssSelector).concat(rangeInfo.endContainerChildTextNodeIndex).concat(rangeInfo.endOffset);\n\n var hash = __webpack_require__(3715);\n\n var sha256Hex = hash.sha256().update(uniqueStr).digest("hex");\n var id;\n\n if (type == ID_HIGHLIGHTS_CONTAINER) {\n id = "R2_HIGHLIGHT_" + sha256Hex;\n } else {\n id = "R2_ANNOTATION_" + sha256Hex;\n }\n\n destroyHighlight(id);\n var highlight = {\n color: color ? color : DEFAULT_BACKGROUND_COLOR,\n id: id,\n pointerInteraction: pointerInteraction,\n rangeInfo: rangeInfo\n };\n\n _highlights.push(highlight);\n\n createHighlightDom(window, highlight, type == ID_ANNOTATION_CONTAINER ? true : false);\n return highlight;\n}\n\nfunction createHighlight(selectionInfo, color, pointerInteraction) {\n return _createHighlight(selectionInfo, color, pointerInteraction, ID_HIGHLIGHTS_CONTAINER);\n}\nfunction createAnnotation(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n if (i == _highlights.length) return;\n var locations = {\n locations: rangeInfo2Location(highlight.rangeInfo)\n };\n return _createHighlight(locations, highlight.color, true, ID_ANNOTATION_CONTAINER);\n}\n\nfunction createHighlightDom(win, highlight, annotationFlag) {\n var document = win.document;\n var scale = 1 / (win.READIUM2 && win.READIUM2.isFixedLayout ? win.READIUM2.fxlViewportScale : 1);\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var paginated = isPaginated(document);\n var highlightsContainer = ensureContainer(win, annotationFlag);\n var highlightParent = document.createElement("div");\n highlightParent.setAttribute("id", highlight.id);\n highlightParent.setAttribute("class", CLASS_HIGHLIGHT_CONTAINER);\n document.body.style.position = "relative";\n highlightParent.style.setProperty("pointer-events", "none");\n\n if (highlight.pointerInteraction) {\n highlightParent.setAttribute("data-click", "1");\n }\n\n var bodyRect = document.body.getBoundingClientRect();\n var useSVG = !DEBUG_VISUALS && USE_SVG; //const useSVG = USE_SVG;\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var highlightAreaSVGDocFrag;\n var roundedCorner = 3;\n var underlineThickness = 2;\n var strikeThroughLineThickness = 3;\n var opacity = DEFAULT_BACKGROUND_COLOR_OPACITY;\n var extra = "";\n var rangeAnnotationBoundingClientRect = frameForHighlightAnnotationMarkWithID(win, highlight.id);\n var xOffset;\n var yOffset;\n var annotationOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n xOffset = paginated ? -scrollElement.scrollLeft : bodyRect.left;\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n annotationOffset = parseInt((rangeAnnotationBoundingClientRect.right - xOffset) / window.innerWidth) + 1;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n xOffset = paginated ? 0 : -scrollElement.scrollLeft;\n yOffset = paginated ? 0 : bodyRect.top;\n annotationOffset = parseInt(rangeAnnotationBoundingClientRect.right / window.innerWidth + 1);\n }\n\n var _iterator17 = highlight_createForOfIteratorHelper(clientRects),\n _step17;\n\n try {\n for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {\n var clientRect = _step17.value;\n\n if (useSVG) {\n var borderThickness = 0;\n\n if (!highlightAreaSVGDocFrag) {\n highlightAreaSVGDocFrag = document.createDocumentFragment();\n }\n\n var highlightAreaSVGRect = document.createElementNS(SVG_XML_NAMESPACE, "rect");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGRect.setAttribute("style", "fill: rgb(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; fill-opacity: ").concat(opacity, " !important; stroke-width: 0;"));\n highlightAreaSVGRect.scale = scale;\n /*\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGRect.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGRect.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaSVGRect.setAttribute("rx", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("ry", "".concat(roundedCorner * scale));\n highlightAreaSVGRect.setAttribute("x", "".concat((highlightAreaSVGRect.rect.left - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("y", "".concat((highlightAreaSVGRect.rect.top - borderThickness) * scale));\n highlightAreaSVGRect.setAttribute("height", "".concat((highlightAreaSVGRect.rect.height + borderThickness * 2) * scale));\n highlightAreaSVGRect.setAttribute("width", "".concat((highlightAreaSVGRect.rect.width + borderThickness * 2) * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGRect);\n\n if (drawUnderline) {\n var highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaSVGLine.setAttribute("style", "stroke-linecap: round; stroke-width: ".concat(underlineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n var lineOffset = highlightAreaSVGLine.rect.width > roundedCorner ? roundedCorner : 0;\n highlightAreaSVGLine.setAttribute("x1", "".concat((highlightAreaSVGLine.rect.left + lineOffset) * scale));\n highlightAreaSVGLine.setAttribute("x2", "".concat((highlightAreaSVGLine.rect.left + highlightAreaSVGLine.rect.width - lineOffset) * scale));\n var y = (highlightAreaSVGLine.rect.top + highlightAreaSVGLine.rect.height - underlineThickness / 2) * scale;\n highlightAreaSVGLine.setAttribute("y1", "".concat(y));\n highlightAreaSVGLine.setAttribute("y2", "".concat(y));\n highlightAreaSVGLine.setAttribute("height", "".concat(highlightAreaSVGLine.rect.height * scale));\n highlightAreaSVGLine.setAttribute("width", "".concat(highlightAreaSVGLine.rect.width * scale));\n highlightAreaSVGDocFrag.appendChild(highlightAreaSVGLine);\n }\n\n if (drawStrikeThrough) {\n var _highlightAreaSVGLine = document.createElementNS(SVG_XML_NAMESPACE, "line");\n\n highlightAreaSVGRect.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n _highlightAreaSVGLine.setAttribute("style", "stroke-linecap: butt; stroke-width: ".concat(strikeThroughLineThickness * scale, "; stroke: rgb(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ") !important; stroke-opacity: ").concat(opacity, " !important"));\n\n _highlightAreaSVGLine.scale = scale;\n /*\n highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n _highlightAreaSVGLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n _highlightAreaSVGLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n _highlightAreaSVGLine.setAttribute("x1", "".concat(_highlightAreaSVGLine.rect.left * scale));\n\n _highlightAreaSVGLine.setAttribute("x2", "".concat((_highlightAreaSVGLine.rect.left + _highlightAreaSVGLine.rect.width) * scale));\n\n var _lineOffset = _highlightAreaSVGLine.rect.height / 2;\n\n var _y = (_highlightAreaSVGLine.rect.top + _lineOffset) * scale;\n\n _highlightAreaSVGLine.setAttribute("y1", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("y2", "".concat(_y));\n\n _highlightAreaSVGLine.setAttribute("height", "".concat(_highlightAreaSVGLine.rect.height * scale));\n\n _highlightAreaSVGLine.setAttribute("width", "".concat(_highlightAreaSVGLine.rect.width * scale));\n\n highlightAreaSVGDocFrag.appendChild(_highlightAreaSVGLine);\n }\n } else {\n var highlightArea = document.createElement("div");\n highlightArea.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n\n if (DEBUG_VISUALS) {\n var rgb = Math.round(0xffffff * Math.random());\n var r = rgb >> 16;\n var g = rgb >> 8 & 255;\n var b = rgb & 255;\n extra = "outline-color: rgb(".concat(r, ", ").concat(g, ", ").concat(b, "); outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n } else {\n if (drawUnderline) {\n extra += "border-bottom: ".concat(underlineThickness * scale, "px solid rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important");\n }\n }\n\n highlightArea.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n highlightArea.style.setProperty("pointer-events", "none");\n highlightArea.style.position = paginated ? "fixed" : "absolute";\n highlightArea.scale = scale;\n /*\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightArea.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightArea.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightArea.style.width = "".concat(highlightArea.rect.width * scale, "px");\n highlightArea.style.height = "".concat(highlightArea.rect.height * scale, "px");\n highlightArea.style.left = "".concat(highlightArea.rect.left * scale, "px");\n highlightArea.style.top = "".concat(highlightArea.rect.top * scale, "px");\n highlightParent.append(highlightArea);\n\n if (!DEBUG_VISUALS && drawStrikeThrough) {\n //if (drawStrikeThrough) {\n var highlightAreaLine = document.createElement("div");\n highlightAreaLine.setAttribute("class", CLASS_HIGHLIGHT_AREA);\n highlightAreaLine.setAttribute("style", "background-color: rgba(".concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important;"));\n highlightAreaLine.style.setProperty("pointer-events", "none");\n highlightAreaLine.style.position = paginated ? "fixed" : "absolute";\n highlightAreaLine.scale = scale;\n /*\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width,\n };\n */\n\n if (annotationFlag) {\n highlightAreaLine.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n highlightAreaLine.rect = {\n height: clientRect.height,\n left: clientRect.left - xOffset,\n top: clientRect.top - yOffset,\n width: clientRect.width\n };\n }\n\n highlightAreaLine.style.width = "".concat(highlightAreaLine.rect.width * scale, "px");\n highlightAreaLine.style.height = "".concat(strikeThroughLineThickness * scale, "px");\n highlightAreaLine.style.left = "".concat(highlightAreaLine.rect.left * scale, "px");\n highlightAreaLine.style.top = "".concat((highlightAreaLine.rect.top + highlightAreaLine.rect.height / 2 - strikeThroughLineThickness / 2) * scale, "px");\n highlightParent.append(highlightAreaLine);\n }\n }\n\n if (annotationFlag) {\n break;\n }\n }\n } catch (err) {\n _iterator17.e(err);\n } finally {\n _iterator17.f();\n }\n\n if (useSVG && highlightAreaSVGDocFrag) {\n var highlightAreaSVG = document.createElementNS(SVG_XML_NAMESPACE, "svg");\n highlightAreaSVG.setAttribute("pointer-events", "none");\n highlightAreaSVG.style.position = paginated ? "fixed" : "absolute";\n highlightAreaSVG.style.overflow = "visible";\n highlightAreaSVG.style.left = "0";\n highlightAreaSVG.style.top = "0";\n highlightAreaSVG.append(highlightAreaSVGDocFrag);\n highlightParent.append(highlightAreaSVG);\n }\n\n var highlightBounding = document.createElement("div");\n\n if (annotationFlag) {\n highlightBounding.setAttribute("class", CLASS_ANNOTATION_BOUNDING_AREA);\n highlightBounding.setAttribute("style", "border-radius: ".concat(roundedCorner, "px !important; background-color: rgba(").concat(highlight.color.red, ", ").concat(highlight.color.green, ", ").concat(highlight.color.blue, ", ").concat(opacity, ") !important; ").concat(extra));\n } else {\n highlightBounding.setAttribute("class", CLASS_HIGHLIGHT_BOUNDING_AREA);\n }\n\n highlightBounding.style.setProperty("pointer-events", "none");\n highlightBounding.style.position = paginated ? "fixed" : "absolute";\n highlightBounding.scale = scale;\n\n if (DEBUG_VISUALS) {\n highlightBounding.setAttribute("style", "outline-color: magenta; outline-style: solid; outline-width: 1px; outline-offset: -1px;");\n }\n\n if (annotationFlag) {\n highlightBounding.rect = {\n height: ANNOTATION_WIDTH,\n //rangeAnnotationBoundingClientRect.height - rangeAnnotationBoundingClientRect.height/4,\n left: window.innerWidth * annotationOffset - ANNOTATION_WIDTH,\n top: rangeAnnotationBoundingClientRect.top - yOffset,\n width: ANNOTATION_WIDTH\n };\n } else {\n var rangeBoundingClientRect = range.getBoundingClientRect();\n highlightBounding.rect = {\n height: rangeBoundingClientRect.height,\n left: rangeBoundingClientRect.left - xOffset,\n top: rangeBoundingClientRect.top - yOffset,\n width: rangeBoundingClientRect.width\n };\n }\n\n highlightBounding.style.width = "".concat(highlightBounding.rect.width * scale, "px");\n highlightBounding.style.height = "".concat(highlightBounding.rect.height * scale, "px");\n highlightBounding.style.left = "".concat(highlightBounding.rect.left * scale, "px");\n highlightBounding.style.top = "".concat(highlightBounding.rect.top * scale, "px");\n highlightParent.append(highlightBounding);\n highlightsContainer.append(highlightParent);\n return highlightParent;\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n console.log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n console.log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n console.log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRange(range, getCssSelector, computeElementCFI) {\n var startIsElement = range.startContainer.nodeType === Node.ELEMENT_NODE;\n var startContainerElement = startIsElement ? range.startContainer : range.startContainer.parentNode && range.startContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.startContainer.parentNode : undefined;\n\n if (!startContainerElement) {\n return undefined;\n }\n\n var startContainerChildTextNodeIndex = startIsElement ? -1 : Array.from(startContainerElement.childNodes).indexOf(range.startContainer);\n\n if (startContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var startContainerElementCssSelector = getCssSelector(startContainerElement);\n var endIsElement = range.endContainer.nodeType === Node.ELEMENT_NODE;\n var endContainerElement = endIsElement ? range.endContainer : range.endContainer.parentNode && range.endContainer.parentNode.nodeType === Node.ELEMENT_NODE ? range.endContainer.parentNode : undefined;\n\n if (!endContainerElement) {\n return undefined;\n }\n\n var endContainerChildTextNodeIndex = endIsElement ? -1 : Array.from(endContainerElement.childNodes).indexOf(range.endContainer);\n\n if (endContainerChildTextNodeIndex < -1) {\n return undefined;\n }\n\n var endContainerElementCssSelector = getCssSelector(endContainerElement);\n var commonElementAncestor = getCommonAncestorElement(range.startContainer, range.endContainer);\n\n if (!commonElementAncestor) {\n console.log("^^^ NO RANGE COMMON ANCESTOR?!");\n return undefined;\n }\n\n if (range.commonAncestorContainer) {\n var rangeCommonAncestorElement = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? range.commonAncestorContainer : range.commonAncestorContainer.parentNode;\n\n if (rangeCommonAncestorElement && rangeCommonAncestorElement.nodeType === Node.ELEMENT_NODE) {\n if (commonElementAncestor !== rangeCommonAncestorElement) {\n console.log(">>>>>> COMMON ANCESTOR CONTAINER DIFF??!");\n console.log(getCssSelector(commonElementAncestor));\n console.log(getCssSelector(rangeCommonAncestorElement));\n }\n }\n }\n\n var rootElementCfi = computeElementCFI(commonElementAncestor);\n var startElementCfi = computeElementCFI(startContainerElement);\n var endElementCfi = computeElementCFI(endContainerElement);\n var cfi;\n\n if (rootElementCfi && startElementCfi && endElementCfi) {\n var startElementOrTextCfi = startElementCfi;\n\n if (!startIsElement) {\n var startContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(startContainerElement, range.startContainer);\n startElementOrTextCfi = startElementCfi + "/" + startContainerChildTextNodeIndexForCfi + ":" + range.startOffset;\n } else {\n if (range.startOffset >= 0 && range.startOffset < startContainerElement.childNodes.length) {\n var childNode = startContainerElement.childNodes[range.startOffset];\n\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (range.startOffset + 1) * 2;\n } else {\n var cfiTextNodeIndex = getChildTextNodeCfiIndex(startContainerElement, childNode);\n startElementOrTextCfi = startElementCfi + "/" + cfiTextNodeIndex;\n }\n } else {\n var cfiIndexOfLastElement = startContainerElement.childElementCount * 2;\n var lastChildNode = startContainerElement.childNodes[startContainerElement.childNodes.length - 1];\n\n if (lastChildNode.nodeType === Node.ELEMENT_NODE) {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 1);\n } else {\n startElementOrTextCfi = startElementCfi + "/" + (cfiIndexOfLastElement + 2);\n }\n }\n }\n\n var endElementOrTextCfi = endElementCfi;\n\n if (!endIsElement) {\n var endContainerChildTextNodeIndexForCfi = getChildTextNodeCfiIndex(endContainerElement, range.endContainer);\n endElementOrTextCfi = endElementCfi + "/" + endContainerChildTextNodeIndexForCfi + ":" + range.endOffset;\n } else {\n if (range.endOffset >= 0 && range.endOffset < endContainerElement.childNodes.length) {\n var _childNode = endContainerElement.childNodes[range.endOffset];\n\n if (_childNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (range.endOffset + 1) * 2;\n } else {\n var _cfiTextNodeIndex = getChildTextNodeCfiIndex(endContainerElement, _childNode);\n\n endElementOrTextCfi = endElementCfi + "/" + _cfiTextNodeIndex;\n }\n } else {\n var _cfiIndexOfLastElement = endContainerElement.childElementCount * 2;\n\n var _lastChildNode = endContainerElement.childNodes[endContainerElement.childNodes.length - 1];\n\n if (_lastChildNode.nodeType === Node.ELEMENT_NODE) {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 1);\n } else {\n endElementOrTextCfi = endElementCfi + "/" + (_cfiIndexOfLastElement + 2);\n }\n }\n }\n\n cfi = rootElementCfi + "," + startElementOrTextCfi.replace(rootElementCfi, "") + "," + endElementOrTextCfi.replace(rootElementCfi, "");\n }\n\n return {\n cfi: cfi,\n endContainerChildTextNodeIndex: endContainerChildTextNodeIndex,\n endContainerElementCssSelector: endContainerElementCssSelector,\n endOffset: range.endOffset,\n startContainerChildTextNodeIndex: startContainerChildTextNodeIndex,\n startContainerElementCssSelector: startContainerElementCssSelector,\n startOffset: range.startOffset\n };\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n console.log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n console.log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n console.log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n console.log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\n\nfunction frameForHighlightAnnotationMarkWithID(win, id) {\n var clientRects = frameForHighlightWithID(id);\n if (!clientRects) return;\n var topClientRect = clientRects[0];\n var maxHeight = topClientRect.height;\n\n var _iterator18 = highlight_createForOfIteratorHelper(clientRects),\n _step18;\n\n try {\n for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {\n var clientRect = _step18.value;\n if (clientRect.top < topClientRect.top) topClientRect = clientRect;\n if (clientRect.height > maxHeight) maxHeight = clientRect.height;\n }\n } catch (err) {\n _iterator18.e(err);\n } finally {\n _iterator18.f();\n }\n\n var document = win.document;\n var scrollElement = getScrollingElement(document);\n var paginated = isPaginated(document);\n var bodyRect = document.body.getBoundingClientRect();\n var yOffset;\n\n if (navigator.userAgent.match(/Android/i)) {\n yOffset = paginated ? -scrollElement.scrollTop : bodyRect.top;\n } else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n yOffset = paginated ? 0 : bodyRect.top;\n }\n\n var newTop = topClientRect.top;\n\n if (_highlightsContainer) {\n do {\n var boundingAreas = document.getElementsByClassName(CLASS_ANNOTATION_BOUNDING_AREA);\n var found = false; //for (let i = 0, length = boundingAreas.snapshotLength; i < length; ++i) {\n\n for (var i = 0, len = boundingAreas.length | 0; i < len; i = i + 1 | 0) {\n var boundingArea = boundingAreas[i];\n\n if (Math.abs(boundingArea.rect.top - (newTop - yOffset)) < 3) {\n newTop += boundingArea.rect.height;\n found = true;\n break;\n }\n }\n } while (found);\n }\n\n topClientRect.top = newTop;\n topClientRect.height = maxHeight;\n return topClientRect;\n}\n\nfunction highlightWithID(id) {\n var i = -1;\n\n var highlight = _highlights.find(function (h, j) {\n i = j;\n return h.id === id;\n });\n\n return highlight;\n}\n\nfunction frameForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n return clientRects;\n}\n\nfunction rangeInfo2Location(rangeInfo) {\n return {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n partialCfi: rangeInfo.cfi,\n domRange: {\n start: {\n cssSelector: rangeInfo.startContainerElementCssSelector,\n textNodeIndex: rangeInfo.startContainerChildTextNodeIndex,\n offset: rangeInfo.startOffset\n },\n end: {\n cssSelector: rangeInfo.endContainerElementCssSelector,\n textNodeIndex: rangeInfo.endContainerChildTextNodeIndex,\n offset: rangeInfo.endOffset\n }\n }\n };\n}\n\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n cfi: location.partialCfi,\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction rectangleForHighlightWithID(id) {\n var highlight = highlightWithID(id);\n if (!highlight) return;\n var document = window.document;\n var scrollElement = getScrollingElement(document);\n var range = convertRangeInfo(document, highlight.rangeInfo);\n\n if (!range) {\n return undefined;\n }\n\n var drawUnderline = false;\n var drawStrikeThrough = false;\n var doNotMergeHorizontallyAlignedRects = drawUnderline || drawStrikeThrough; //const clientRects = DEBUG_VISUALS ? range.getClientRects() :\n\n var clientRects = highlight_getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects);\n var size = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRects[0].left,\n width: clientRects[0].width,\n top: clientRects[0].top,\n height: clientRects[0].height\n };\n return size;\n}\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n var clientRect = range.getBoundingClientRect();\n var handleBounds = {\n screenWidth: window.outerWidth,\n screenHeight: window.outerHeight,\n left: clientRect.left,\n width: clientRect.width,\n top: clientRect.top,\n height: clientRect.height\n };\n return handleBounds;\n } catch (e) {\n return null;\n }\n}\nfunction setScrollMode(flag) {\n if (!flag) {\n document.documentElement.classList.add(CLASS_PAGINATED);\n } else {\n document.documentElement.classList.remove(CLASS_PAGINATED);\n }\n}\n/*\n if (document.addEventListener) { // IE >= 9; other browsers\n document.addEventListener(\'contextmenu\', function(e) {\n //alert("You\'ve tried to open context menu"); //here you draw your own menu\n //e.preventDefault();\n //let getCssSelector = fullQualifiedSelector;\n \n\t\t\tlet str = window.getSelection();\n\t\t\tlet selectionInfo = getCurrentSelectionInfo();\n\t\t\tlet pos = createHighlight(selectionInfo,{red:10,green:50,blue:230},true);\n\t\t\tlet ret2 = createAnnotation(pos.id);\n\t\t\t\n }, false);\n } else { // IE < 9\n document.attachEvent(\'oncontextmenu\', function() {\n alert("You\'ve tried to open context menu");\n window.event.returnValue = false;\n });\n }\n*/\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = selection_getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction selection_getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : selection_createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction selection_createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction selection_convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return selection_createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction selection_location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n}; // Legacy highlights API.\n\nwindow.createAnnotation = createAnnotation;\nwindow.createHighlight = createHighlight;\nwindow.destroyHighlight = destroyHighlight;\nwindow.getCurrentSelectionInfo = getCurrentSelectionInfo;\nwindow.getSelectionRect = getSelectionRect;\nwindow.rectangleForHighlightWithID = rectangleForHighlightWithID;\nwindow.setScrollMode = setScrollMode;\n;// CONCATENATED MODULE: ./src/index-reflowable.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for reflowable resources.\n\nwindow.readium.isReflowable = true;\ndocument.addEventListener("DOMContentLoaded", function () {\n // Setups the `viewport` meta tag to disable zooming.\n var meta = document.createElement("meta");\n meta.setAttribute("name", "viewport");\n meta.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no");\n document.head.appendChild(meta);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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a0IsTUFBbEIsRUFBMEIsVUFBMUI7QUFDQWdSLEVBQUFBLElBQUksQ0FBQ2hSLFlBQUwsQ0FDRSxTQURGLEVBRUUsOEZBRkY7QUFJQXBFLEVBQUFBLFFBQVEsQ0FBQ3lwQixJQUFULENBQWNqbEIsV0FBZCxDQUEwQjRRLElBQTFCO0FBQ0QsQ0FURCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL21hdGNoLXF1b3RlLmpzP2RkNmEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdGV4dC1yYW5nZS5qcz9mZGVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzLmpzPzQwMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy91dGlscy5qcz8wMjVlIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvcmVjdC5qcz80ZDVhIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZGVjb3JhdG9yLmpzPzFiMDQiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kb20uanM/Y2JmMCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2dlc3R1cmVzLmpzPzE0YzIiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9rZXlib2FyZC5qcz8xOGUzIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvaGlnaGxpZ2h0LmpzPzhkYTgiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9zZWxlY3Rpb24uanM/NTlhYyIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LmpzP2I2MzUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9pbmRleC1yZWZsb3dhYmxlLmpzPzM5MjUiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFwcHJveFNlYXJjaCBmcm9tICdhcHByb3gtc3RyaW5nLW1hdGNoJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHByb3gtc3RyaW5nLW1hdGNoJykuTWF0Y2h9IFN0cmluZ01hdGNoXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBNYXRjaFxuICogQHByb3Age251bWJlcn0gc3RhcnQgLSBTdGFydCBvZmZzZXQgb2YgbWF0Y2ggaW4gdGV4dFxuICogQHByb3Age251bWJlcn0gZW5kIC0gRW5kIG9mZnNldCBvZiBtYXRjaCBpbiB0ZXh0XG4gKiBAcHJvcCB7bnVtYmVyfSBzY29yZSAtXG4gKiAgIFNjb3JlIGZvciB0aGUgbWF0Y2ggYmV0d2VlbiAwIGFuZCAxLjAsIHdoZXJlIDEuMCBpbmRpY2F0ZXMgYSBwZXJmZWN0IG1hdGNoXG4gKiAgIGZvciB0aGUgcXVvdGUgYW5kIGNvbnRleHQuXG4gKi9cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoZXMgZm9yIGBzdHJgIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhFcnJvcnNcbiAqIEByZXR1cm4ge1N0cmluZ01hdGNoW119XG4gKi9cbmZ1bmN0aW9uIHNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycykge1xuICAvLyBEbyBhIGZhc3Qgc2VhcmNoIGZvciBleGFjdCBtYXRjaGVzLiBUaGUgYGFwcHJveC1zdHJpbmctbWF0Y2hgIGxpYnJhcnlcbiAgLy8gZG9lc24ndCBjdXJyZW50bHkgaW5jb3Jwb3JhdGUgdGhpcyBvcHRpbWl6YXRpb24gaXRzZWxmLlxuICBsZXQgbWF0Y2hQb3MgPSAwO1xuICBsZXQgZXhhY3RNYXRjaGVzID0gW107XG4gIHdoaWxlIChtYXRjaFBvcyAhPT0gLTEpIHtcbiAgICBtYXRjaFBvcyA9IHRleHQuaW5kZXhPZihzdHIsIG1hdGNoUG9zKTtcbiAgICBpZiAobWF0Y2hQb3MgIT09IC0xKSB7XG4gICAgICBleGFjdE1hdGNoZXMucHVzaCh7XG4gICAgICAgIHN0YXJ0OiBtYXRjaFBvcyxcbiAgICAgICAgZW5kOiBtYXRjaFBvcyArIHN0ci5sZW5ndGgsXG4gICAgICAgIGVycm9yczogMCxcbiAgICAgIH0pO1xuICAgICAgbWF0Y2hQb3MgKz0gMTtcbiAgICB9XG4gIH1cbiAgaWYgKGV4YWN0TWF0Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGV4YWN0TWF0Y2hlcztcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBubyBleGFjdCBtYXRjaGVzLCBkbyBhIG1vcmUgZXhwZW5zaXZlIHNlYXJjaCBmb3IgbWF0Y2hlc1xuICAvLyB3aXRoIGVycm9ycy5cbiAgcmV0dXJuIGFwcHJveFNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycyk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSBhIHNjb3JlIGJldHdlZW4gMCBhbmQgMS4wIGZvciB0aGUgc2ltaWxhcml0eSBiZXR3ZWVuIGB0ZXh0YCBhbmQgYHN0cmAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqL1xuZnVuY3Rpb24gdGV4dE1hdGNoU2NvcmUodGV4dCwgc3RyKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0IC0gYHNjb3JlTWF0Y2hgIHdpbGwgbmV2ZXIgcGFzcyBhbiBlbXB0eSBzdHJpbmcgKi9cbiAgaWYgKHN0ci5sZW5ndGggPT09IDAgfHwgdGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gMC4wO1xuICB9XG4gIGNvbnN0IG1hdGNoZXMgPSBzZWFyY2godGV4dCwgc3RyLCBzdHIubGVuZ3RoKTtcblxuICAvLyBwcmV0dGllci1pZ25vcmVcbiAgcmV0dXJuIDEgLSAobWF0Y2hlc1swXS5lcnJvcnMgLyBzdHIubGVuZ3RoKTtcbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoIGZvciBgcXVvdGVgIGluIGB0ZXh0YC5cbiAqXG4gKiBSZXR1cm5zIGBudWxsYCBpZiBubyBtYXRjaCBleGNlZWRpbmcgdGhlIG1pbmltdW0gcXVhbGl0eSB0aHJlc2hvbGQgd2FzIGZvdW5kLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gRG9jdW1lbnQgdGV4dCB0byBzZWFyY2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBxdW90ZSAtIFN0cmluZyB0byBmaW5kIHdpdGhpbiBgdGV4dGBcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC1cbiAqICAgQ29udGV4dCBpbiB3aGljaCB0aGUgcXVvdGUgb3JpZ2luYWxseSBhcHBlYXJlZC4gVGhpcyBpcyB1c2VkIHRvIGNob29zZSB0aGVcbiAqICAgYmVzdCBtYXRjaC5cbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnByZWZpeF0gLSBFeHBlY3RlZCB0ZXh0IGJlZm9yZSB0aGUgcXVvdGVcbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnN1ZmZpeF0gLSBFeHBlY3RlZCB0ZXh0IGFmdGVyIHRoZSBxdW90ZVxuICogICBAcGFyYW0ge251bWJlcn0gW2NvbnRleHQuaGludF0gLSBFeHBlY3RlZCBvZmZzZXQgb2YgbWF0Y2ggd2l0aGluIHRleHRcbiAqIEByZXR1cm4ge01hdGNofG51bGx9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaFF1b3RlKHRleHQsIHF1b3RlLCBjb250ZXh0ID0ge30pIHtcbiAgaWYgKHF1b3RlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQ2hvb3NlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBlcnJvcnMgdG8gYWxsb3cgZm9yIHRoZSBpbml0aWFsIHNlYXJjaC5cbiAgLy8gVGhpcyBjaG9pY2UgaW52b2x2ZXMgYSB0cmFkZW9mZiBiZXR3ZWVuOlxuICAvL1xuICAvLyAgLSBSZWNhbGwgKHByb3BvcnRpb24gb2YgXCJnb29kXCIgbWF0Y2hlcyBmb3VuZClcbiAgLy8gIC0gUHJlY2lzaW9uIChwcm9wb3J0aW9uIG9mIG1hdGNoZXMgZm91bmQgd2hpY2ggYXJlIFwiZ29vZFwiKVxuICAvLyAgLSBDb3N0IG9mIHRoZSBpbml0aWFsIHNlYXJjaCBhbmQgb2YgcHJvY2Vzc2luZyB0aGUgY2FuZGlkYXRlIG1hdGNoZXMgWzFdXG4gIC8vXG4gIC8vIFsxXSBTcGVjaWZpY2FsbHksIHRoZSBleHBlY3RlZC10aW1lIGNvbXBsZXhpdHkgb2YgdGhlIGluaXRpYWwgc2VhcmNoIGlzXG4gIC8vICAgICBgTygobWF4RXJyb3JzIC8gMzIpICogdGV4dC5sZW5ndGgpYC4gU2VlIGBhcHByb3gtc3RyaW5nLW1hdGNoYCBkb2NzLlxuICBjb25zdCBtYXhFcnJvcnMgPSBNYXRoLm1pbigyNTYsIHF1b3RlLmxlbmd0aCAvIDIpO1xuXG4gIC8vIEZpbmQgY2xvc2VzdCBtYXRjaGVzIGZvciBgcXVvdGVgIGluIGB0ZXh0YCBiYXNlZCBvbiBlZGl0IGRpc3RhbmNlLlxuICBjb25zdCBtYXRjaGVzID0gc2VhcmNoKHRleHQsIHF1b3RlLCBtYXhFcnJvcnMpO1xuXG4gIGlmIChtYXRjaGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEuMCBmb3IgYSBtYXRjaCBjYW5kaWRhdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nTWF0Y2h9IG1hdGNoXG4gICAqL1xuICBjb25zdCBzY29yZU1hdGNoID0gbWF0Y2ggPT4ge1xuICAgIGNvbnN0IHF1b3RlV2VpZ2h0ID0gNTA7IC8vIFNpbWlsYXJpdHkgb2YgbWF0Y2hlZCB0ZXh0IHRvIHF1b3RlLlxuICAgIGNvbnN0IHByZWZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYmVmb3JlIG1hdGNoZWQgdGV4dCB0byBgY29udGV4dC5wcmVmaXhgLlxuICAgIGNvbnN0IHN1ZmZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYWZ0ZXIgbWF0Y2hlZCB0ZXh0IHRvIGBjb250ZXh0LnN1ZmZpeGAuXG4gICAgY29uc3QgcG9zV2VpZ2h0ID0gMjsgLy8gUHJveGltaXR5IHRvIGV4cGVjdGVkIGxvY2F0aW9uLiBVc2VkIGFzIGEgdGllLWJyZWFrZXIuXG5cbiAgICBjb25zdCBxdW90ZVNjb3JlID0gMSAtIG1hdGNoLmVycm9ycyAvIHF1b3RlLmxlbmd0aDtcblxuICAgIGNvbnN0IHByZWZpeFNjb3JlID0gY29udGV4dC5wcmVmaXhcbiAgICAgID8gdGV4dE1hdGNoU2NvcmUoXG4gICAgICAgICAgdGV4dC5zbGljZShNYXRoLm1heCgwLCBtYXRjaC5zdGFydCAtIGNvbnRleHQucHJlZml4Lmxlbmd0aCksIG1hdGNoLnN0YXJ0KSxcbiAgICAgICAgICBjb250ZXh0LnByZWZpeFxuICAgICAgICApXG4gICAgICA6IDEuMDtcbiAgICBjb25zdCBzdWZmaXhTY29yZSA9IGNvbnRleHQuc3VmZml4XG4gICAgICA/IHRleHRNYXRjaFNjb3JlKFxuICAgICAgICAgIHRleHQuc2xpY2UobWF0Y2guZW5kLCBtYXRjaC5lbmQgKyBjb250ZXh0LnN1ZmZpeC5sZW5ndGgpLFxuICAgICAgICAgIGNvbnRleHQuc3VmZml4XG4gICAgICAgIClcbiAgICAgIDogMS4wO1xuXG4gICAgbGV0IHBvc1Njb3JlID0gMS4wO1xuICAgIGlmICh0eXBlb2YgY29udGV4dC5oaW50ID09PSAnbnVtYmVyJykge1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5hYnMobWF0Y2guc3RhcnQgLSBjb250ZXh0LmhpbnQpO1xuICAgICAgcG9zU2NvcmUgPSAxLjAgLSBvZmZzZXQgLyB0ZXh0Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBjb25zdCByYXdTY29yZSA9XG4gICAgICBxdW90ZVdlaWdodCAqIHF1b3RlU2NvcmUgK1xuICAgICAgcHJlZml4V2VpZ2h0ICogcHJlZml4U2NvcmUgK1xuICAgICAgc3VmZml4V2VpZ2h0ICogc3VmZml4U2NvcmUgK1xuICAgICAgcG9zV2VpZ2h0ICogcG9zU2NvcmU7XG4gICAgY29uc3QgbWF4U2NvcmUgPSBxdW90ZVdlaWdodCArIHByZWZpeFdlaWdodCArIHN1ZmZpeFdlaWdodCArIHBvc1dlaWdodDtcbiAgICBjb25zdCBub3JtYWxpemVkU2NvcmUgPSByYXdTY29yZSAvIG1heFNjb3JlO1xuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRTY29yZTtcbiAgfTtcblxuICAvLyBSYW5rIG1hdGNoZXMgYmFzZWQgb24gc2ltaWxhcml0eSBvZiBhY3R1YWwgYW5kIGV4cGVjdGVkIHN1cnJvdW5kaW5nIHRleHRcbiAgLy8gYW5kIGFjdHVhbC9leHBlY3RlZCBvZmZzZXQgaW4gdGhlIGRvY3VtZW50IHRleHQuXG4gIGNvbnN0IHNjb3JlZE1hdGNoZXMgPSBtYXRjaGVzLm1hcChtID0+ICh7XG4gICAgc3RhcnQ6IG0uc3RhcnQsXG4gICAgZW5kOiBtLmVuZCxcbiAgICBzY29yZTogc2NvcmVNYXRjaChtKSxcbiAgfSkpO1xuXG4gIC8vIENob29zZSBtYXRjaCB3aXRoIGhpZ2hlc3Qgc2NvcmUuXG4gIHNjb3JlZE1hdGNoZXMuc29ydCgoYSwgYikgPT4gYi5zY29yZSAtIGEuc2NvcmUpO1xuICByZXR1cm4gc2NvcmVkTWF0Y2hlc1swXTtcbn1cbiIsIi8qKlxuICogUmV0dXJuIHRoZSBjb21iaW5lZCBsZW5ndGggb2YgdGV4dCBub2RlcyBjb250YWluZWQgaW4gYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICovXG5mdW5jdGlvbiBub2RlVGV4dExlbmd0aChub2RlKSB7XG4gIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgIC8vIG5iLiBgdGV4dENvbnRlbnRgIGV4Y2x1ZGVzIHRleHQgaW4gY29tbWVudHMgYW5kIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zXG4gICAgICAvLyB3aGVuIGNhbGxlZCBvbiBhIHBhcmVudCBlbGVtZW50LCBzbyB3ZSBkb24ndCBuZWVkIHRvIHN1YnRyYWN0IHRoYXQgaGVyZS5cblxuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobm9kZS50ZXh0Q29udGVudCkubGVuZ3RoO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gMDtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgdG90YWwgbGVuZ3RoIG9mIHRoZSB0ZXh0IG9mIGFsbCBwcmV2aW91cyBzaWJsaW5ncyBvZiBgbm9kZWAuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKi9cbmZ1bmN0aW9uIHByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoKG5vZGUpIHtcbiAgbGV0IHNpYmxpbmcgPSBub2RlLnByZXZpb3VzU2libGluZztcbiAgbGV0IGxlbmd0aCA9IDA7XG4gIHdoaWxlIChzaWJsaW5nKSB7XG4gICAgbGVuZ3RoICs9IG5vZGVUZXh0TGVuZ3RoKHNpYmxpbmcpO1xuICAgIHNpYmxpbmcgPSBzaWJsaW5nLnByZXZpb3VzU2libGluZztcbiAgfVxuICByZXR1cm4gbGVuZ3RoO1xufVxuXG4vKipcbiAqIFJlc29sdmUgb25lIG9yIG1vcmUgY2hhcmFjdGVyIG9mZnNldHMgd2l0aGluIGFuIGVsZW1lbnQgdG8gKHRleHQgbm9kZSwgcG9zaXRpb24pXG4gKiBwYWlycy5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyW119IG9mZnNldHMgLSBPZmZzZXRzLCB3aGljaCBtdXN0IGJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXJcbiAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfVtdfVxuICovXG5mdW5jdGlvbiByZXNvbHZlT2Zmc2V0cyhlbGVtZW50LCAuLi5vZmZzZXRzKSB7XG4gIGxldCBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICBjb25zdCBub2RlSXRlciA9IC8qKiBAdHlwZSB7RG9jdW1lbnR9ICovIChcbiAgICBlbGVtZW50Lm93bmVyRG9jdW1lbnRcbiAgKS5jcmVhdGVOb2RlSXRlcmF0b3IoZWxlbWVudCwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuICBjb25zdCByZXN1bHRzID0gW107XG5cbiAgbGV0IGN1cnJlbnROb2RlID0gbm9kZUl0ZXIubmV4dE5vZGUoKTtcbiAgbGV0IHRleHROb2RlO1xuICBsZXQgbGVuZ3RoID0gMDtcblxuICAvLyBGaW5kIHRoZSB0ZXh0IG5vZGUgY29udGFpbmluZyB0aGUgYG5leHRPZmZzZXRgdGggY2hhcmFjdGVyIGZyb20gdGhlIHN0YXJ0XG4gIC8vIG9mIGBlbGVtZW50YC5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50Tm9kZSkge1xuICAgIHRleHROb2RlID0gLyoqIEB0eXBlIHtUZXh0fSAqLyAoY3VycmVudE5vZGUpO1xuICAgIGlmIChsZW5ndGggKyB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCA+IG5leHRPZmZzZXQpIHtcbiAgICAgIHJlc3VsdHMucHVzaCh7IG5vZGU6IHRleHROb2RlLCBvZmZzZXQ6IG5leHRPZmZzZXQgLSBsZW5ndGggfSk7XG4gICAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IG5vZGVJdGVyLm5leHROb2RlKCk7XG4gICAgICBsZW5ndGggKz0gdGV4dE5vZGUuZGF0YS5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgLy8gQm91bmRhcnkgY2FzZS5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiB0ZXh0Tm9kZSAmJiBsZW5ndGggPT09IG5leHRPZmZzZXQpIHtcbiAgICByZXN1bHRzLnB1c2goeyBub2RlOiB0ZXh0Tm9kZSwgb2Zmc2V0OiB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCB9KTtcbiAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICB9XG5cbiAgaWYgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPZmZzZXQgZXhjZWVkcyB0ZXh0IGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmV4cG9ydCBsZXQgUkVTT0xWRV9GT1JXQVJEUyA9IDE7XG5leHBvcnQgbGV0IFJFU09MVkVfQkFDS1dBUkRTID0gMjtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIG9mZnNldCB3aXRoaW4gdGhlIHRleHQgY29udGVudCBvZiBhbiBlbGVtZW50LlxuICpcbiAqIFRoaXMgcG9zaXRpb24gY2FuIGJlIHJlc29sdmVkIHRvIGEgc3BlY2lmaWMgZGVzY2VuZGFudCBub2RlIGluIHRoZSBjdXJyZW50XG4gKiBET00gc3VidHJlZSBvZiB0aGUgZWxlbWVudCB1c2luZyB0aGUgYHJlc29sdmVgIG1ldGhvZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbiB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgdGV4dCBwb3NpdGlvbiBgb2Zmc2V0YCB3aXRoaW5cbiAgICogdGhlIHRleHQgY29udGVudCBvZiBgZWxlbWVudGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvZmZzZXQpIHtcbiAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPZmZzZXQgaXMgaW52YWxpZCcpO1xuICAgIH1cblxuICAgIC8qKiBFbGVtZW50IHRoYXQgYG9mZnNldGAgaXMgcmVsYXRpdmUgdG8uICovXG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIC8qKiBDaGFyYWN0ZXIgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBlbGVtZW50J3MgYHRleHRDb250ZW50YC4gKi9cbiAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgcG9zaXRpb24gd2l0aCBvZmZzZXQgcmVsYXRpdmUgdG8gYSBnaXZlbiBhbmNlc3RvclxuICAgKiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHBhcmVudCAtIEFuY2VzdG9yIG9mIGB0aGlzLmVsZW1lbnRgXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHJlbGF0aXZlVG8ocGFyZW50KSB7XG4gICAgaWYgKCFwYXJlbnQuY29udGFpbnModGhpcy5lbGVtZW50KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJlbnQgaXMgbm90IGFuIGFuY2VzdG9yIG9mIGN1cnJlbnQgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIGxldCBlbCA9IHRoaXMuZWxlbWVudDtcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgd2hpbGUgKGVsICE9PSBwYXJlbnQpIHtcbiAgICAgIG9mZnNldCArPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChlbCk7XG4gICAgICBlbCA9IC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKGVsLnBhcmVudEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKGVsLCBvZmZzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIHBvc2l0aW9uIHRvIGEgc3BlY2lmaWMgdGV4dCBub2RlIGFuZCBvZmZzZXQgd2l0aGluIHRoYXQgbm9kZS5cbiAgICpcbiAgICogVGhyb3dzIGlmIGB0aGlzLm9mZnNldGAgZXhjZWVkcyB0aGUgbGVuZ3RoIG9mIHRoZSBlbGVtZW50J3MgdGV4dC4gSW4gdGhlXG4gICAqIGNhc2Ugd2hlcmUgdGhlIGVsZW1lbnQgaGFzIG5vIHRleHQgYW5kIGB0aGlzLm9mZnNldGAgaXMgMCwgdGhlIGBkaXJlY3Rpb25gXG4gICAqIG9wdGlvbiBkZXRlcm1pbmVzIHdoYXQgaGFwcGVucy5cbiAgICpcbiAgICogT2Zmc2V0cyBhdCB0aGUgYm91bmRhcnkgYmV0d2VlbiB0d28gbm9kZXMgYXJlIHJlc29sdmVkIHRvIHRoZSBzdGFydCBvZiB0aGVcbiAgICogbm9kZSB0aGF0IGJlZ2lucyBhdCB0aGUgYm91bmRhcnkuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBAcGFyYW0ge1JFU09MVkVfRk9SV0FSRFN8UkVTT0xWRV9CQUNLV0FSRFN9IFtvcHRpb25zLmRpcmVjdGlvbl0gLVxuICAgKiAgICAgU3BlY2lmaWVzIGluIHdoaWNoIGRpcmVjdGlvbiB0byBzZWFyY2ggZm9yIHRoZSBuZWFyZXN0IHRleHQgbm9kZSBpZlxuICAgKiAgICAgYHRoaXMub2Zmc2V0YCBpcyBgMGAgYW5kIGB0aGlzLmVsZW1lbnRgIGhhcyBubyB0ZXh0LiBJZiBub3Qgc3BlY2lmaWVkXG4gICAqICAgICBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfX1cbiAgICogQHRocm93cyB7UmFuZ2VFcnJvcn1cbiAgICovXG4gIHJlc29sdmUob3B0aW9ucyA9IHt9KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiByZXNvbHZlT2Zmc2V0cyh0aGlzLmVsZW1lbnQsIHRoaXMub2Zmc2V0KVswXTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmICh0aGlzLm9mZnNldCA9PT0gMCAmJiBvcHRpb25zLmRpcmVjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHR3ID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVFxuICAgICAgICApO1xuICAgICAgICB0dy5jdXJyZW50Tm9kZSA9IHRoaXMuZWxlbWVudDtcbiAgICAgICAgY29uc3QgZm9yd2FyZHMgPSBvcHRpb25zLmRpcmVjdGlvbiA9PT0gUkVTT0xWRV9GT1JXQVJEUztcbiAgICAgICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7VGV4dHxudWxsfSAqLyAoXG4gICAgICAgICAgZm9yd2FyZHMgPyB0dy5uZXh0Tm9kZSgpIDogdHcucHJldmlvdXNOb2RlKClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHRleHQsIG9mZnNldDogZm9yd2FyZHMgPyAwIDogdGV4dC5kYXRhLmxlbmd0aCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgYG9mZnNldGB0aCBjaGFyYWN0ZXIgd2l0aGluXG4gICAqIGBub2RlYC5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7VGV4dFBvc2l0aW9ufVxuICAgKi9cbiAgc3RhdGljIGZyb21DaGFyT2Zmc2V0KG5vZGUsIG9mZnNldCkge1xuICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgICAgcmV0dXJuIFRleHRQb3NpdGlvbi5mcm9tUG9pbnQobm9kZSwgb2Zmc2V0KTtcbiAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCBvZmZzZXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb2RlIGlzIG5vdCBhbiBlbGVtZW50IG9yIHRleHQgbm9kZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCByZXByZXNlbnRpbmcgdGhlIHJhbmdlIHN0YXJ0IG9yIGVuZCBwb2ludCAobm9kZSwgb2Zmc2V0KS5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlIC0gVGV4dCBvciBFbGVtZW50IG5vZGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCAtIE9mZnNldCB3aXRoaW4gdGhlIG5vZGUuXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tUG9pbnQobm9kZSwgb2Zmc2V0KSB7XG4gICAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7XG4gICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOiB7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IC8qKiBAdHlwZSB7VGV4dH0gKi8gKG5vZGUpLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IG5vZGUgb2Zmc2V0IGlzIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFub2RlLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RleHQgbm9kZSBoYXMgbm8gcGFyZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcGFyZW50IGVsZW1lbnQuXG4gICAgICAgIGNvbnN0IHRleHRPZmZzZXQgPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChub2RlKSArIG9mZnNldDtcblxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbihub2RlLnBhcmVudEVsZW1lbnQsIHRleHRPZmZzZXQpO1xuICAgICAgfVxuICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERToge1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBub2RlIG9mZnNldCBpcyBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgdGV4dCBsZW5ndGggYmVmb3JlIHRoZSBgb2Zmc2V0YHRoIGNoaWxkIG9mIGVsZW1lbnQuXG4gICAgICAgIGxldCB0ZXh0T2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvZmZzZXQ7IGkrKykge1xuICAgICAgICAgIHRleHRPZmZzZXQgKz0gbm9kZVRleHRMZW5ndGgobm9kZS5jaGlsZE5vZGVzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCB0ZXh0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUG9pbnQgaXMgbm90IGluIGFuIGVsZW1lbnQgb3IgdGV4dCBub2RlJyk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHJlZ2lvbiBvZiBhIGRvY3VtZW50IGFzIGEgKHN0YXJ0LCBlbmQpIHBhaXIgb2YgYFRleHRQb3NpdGlvbmAgcG9pbnRzLlxuICpcbiAqIFJlcHJlc2VudGluZyBhIHJhbmdlIGluIHRoaXMgd2F5IGFsbG93cyBmb3IgY2hhbmdlcyBpbiB0aGUgRE9NIGNvbnRlbnQgb2YgdGhlXG4gKiByYW5nZSB3aGljaCBkb24ndCBhZmZlY3QgaXRzIHRleHQgY29udGVudCwgd2l0aG91dCBhZmZlY3RpbmcgdGhlIHRleHQgY29udGVudFxuICogb2YgdGhlIHJhbmdlIGl0c2VsZi5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRSYW5nZSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYW4gaW1tdXRhYmxlIGBUZXh0UmFuZ2VgIGZyb20gYSBgc3RhcnRgIGFuZCBgZW5kYCBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb259IHN0YXJ0XG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9ufSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5lbmQgPSBlbmQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGlzIHJhbmdlIHdpdGggc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgcmVsYXRpdmUgdG8gYVxuICAgKiBnaXZlbiBhbmNlc3Rvci4gU2VlIGBUZXh0UG9zaXRpb24ucmVsYXRpdmVUb2AuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKi9cbiAgcmVsYXRpdmVUbyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2UoXG4gICAgICB0aGlzLnN0YXJ0LnJlbGF0aXZlVG8oZWxlbWVudCksXG4gICAgICB0aGlzLmVuZC5yZWxhdGl2ZVRvKGVsZW1lbnQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBgVGV4dFJhbmdlYCB0byBhIERPTSByYW5nZS5cbiAgICpcbiAgICogVGhlIHJlc3VsdGluZyBET00gUmFuZ2Ugd2lsbCBhbHdheXMgc3RhcnQgYW5kIGVuZCBpbiBhIGBUZXh0YCBub2RlLlxuICAgKiBIZW5jZSBgVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkudG9SYW5nZSgpYCBjYW4gYmUgdXNlZCB0byBcInNocmlua1wiIGFcbiAgICogcmFuZ2UgdG8gdGhlIHRleHQgaXQgY29udGFpbnMuXG4gICAqXG4gICAqIE1heSB0aHJvdyBpZiB0aGUgYHN0YXJ0YCBvciBgZW5kYCBwb3NpdGlvbnMgY2Fubm90IGJlIHJlc29sdmVkIHRvIGEgcmFuZ2UuXG4gICAqXG4gICAqIEByZXR1cm4ge1JhbmdlfVxuICAgKi9cbiAgdG9SYW5nZSgpIHtcbiAgICBsZXQgc3RhcnQ7XG4gICAgbGV0IGVuZDtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhcnQuZWxlbWVudCA9PT0gdGhpcy5lbmQuZWxlbWVudCAmJlxuICAgICAgdGhpcy5zdGFydC5vZmZzZXQgPD0gdGhpcy5lbmQub2Zmc2V0XG4gICAgKSB7XG4gICAgICAvLyBGYXN0IHBhdGggZm9yIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGluIHNhbWUgZWxlbWVudC5cbiAgICAgIFtzdGFydCwgZW5kXSA9IHJlc29sdmVPZmZzZXRzKFxuICAgICAgICB0aGlzLnN0YXJ0LmVsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhcnQub2Zmc2V0LFxuICAgICAgICB0aGlzLmVuZC5vZmZzZXRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0ID0gdGhpcy5zdGFydC5yZXNvbHZlKHsgZGlyZWN0aW9uOiBSRVNPTFZFX0ZPUldBUkRTIH0pO1xuICAgICAgZW5kID0gdGhpcy5lbmQucmVzb2x2ZSh7IGRpcmVjdGlvbjogUkVTT0xWRV9CQUNLV0FSRFMgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgUmFuZ2UoKTtcbiAgICByYW5nZS5zZXRTdGFydChzdGFydC5ub2RlLCBzdGFydC5vZmZzZXQpO1xuICAgIHJhbmdlLnNldEVuZChlbmQubm9kZSwgZW5kLm9mZnNldCk7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYW4gZXhpc3RpbmcgRE9NIGBSYW5nZWAgdG8gYSBgVGV4dFJhbmdlYFxuICAgKlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZVxuICAgKiBAcmV0dXJuIHtUZXh0UmFuZ2V9XG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJhbmdlKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBUZXh0UG9zaXRpb24uZnJvbVBvaW50KFxuICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgICByYW5nZS5zdGFydE9mZnNldFxuICAgICk7XG4gICAgY29uc3QgZW5kID0gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2Uoc3RhcnQsIGVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgYFRleHRSYW5nZWAgZnJvbSB0aGUgYHN0YXJ0YHRoIHRvIGBlbmRgdGggY2hhcmFjdGVycyBpbiBgcm9vdGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZFxuICAgKi9cbiAgc3RhdGljIGZyb21PZmZzZXRzKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gbmV3IFRleHRSYW5nZShcbiAgICAgIG5ldyBUZXh0UG9zaXRpb24ocm9vdCwgc3RhcnQpLFxuICAgICAgbmV3IFRleHRQb3NpdGlvbihyb290LCBlbmQpXG4gICAgKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBUaGlzIG1vZHVsZSBleHBvcnRzIGEgc2V0IG9mIGNsYXNzZXMgZm9yIGNvbnZlcnRpbmcgYmV0d2VlbiBET00gYFJhbmdlYFxuICogb2JqZWN0cyBhbmQgZGlmZmVyZW50IHR5cGVzIG9mIHNlbGVjdG9ycy4gSXQgaXMgbW9zdGx5IGEgdGhpbiB3cmFwcGVyIGFyb3VuZCBhXG4gKiBzZXQgb2YgYW5jaG9yaW5nIGxpYnJhcmllcy4gSXQgc2VydmVzIHR3byBtYWluIHB1cnBvc2VzOlxuICpcbiAqICAxLiBQcm92aWRpbmcgYSBjb25zaXN0ZW50IGludGVyZmFjZSBhY3Jvc3MgZGlmZmVyZW50IHR5cGVzIG9mIGFuY2hvcnMuXG4gKiAgMi4gSW5zdWxhdGluZyB0aGUgcmVzdCBvZiB0aGUgY29kZSBmcm9tIEFQSSBjaGFuZ2VzIGluIHRoZSB1bmRlcmx5aW5nIGFuY2hvcmluZ1xuICogICAgIGxpYnJhcmllcy5cbiAqL1xuXG5pbXBvcnQgeyBtYXRjaFF1b3RlIH0gZnJvbSAnLi9tYXRjaC1xdW90ZSc7XG5pbXBvcnQgeyBUZXh0UmFuZ2UsIFRleHRQb3NpdGlvbiB9IGZyb20gJy4vdGV4dC1yYW5nZSc7XG5pbXBvcnQgeyBub2RlRnJvbVhQYXRoLCB4cGF0aEZyb21Ob2RlIH0gZnJvbSAnLi94cGF0aCc7XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuUmFuZ2VTZWxlY3Rvcn0gUmFuZ2VTZWxlY3RvclxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuVGV4dFBvc2l0aW9uU2VsZWN0b3J9IFRleHRQb3NpdGlvblNlbGVjdG9yXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi8uLi90eXBlcy9hcGknKS5UZXh0UXVvdGVTZWxlY3Rvcn0gVGV4dFF1b3RlU2VsZWN0b3JcbiAqL1xuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgUmFuZ2VBbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtOb2RlfSByb290IC0gQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgcmFuZ2UpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMucmFuZ2UgPSByYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge05vZGV9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyb290LCByYW5nZSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2VBbmNob3Iocm9vdCwgcmFuZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBhbmNob3IgZnJvbSBhIHNlcmlhbGl6ZWQgYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9yLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2VTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IG5vZGVGcm9tWFBhdGgoc2VsZWN0b3Iuc3RhcnRDb250YWluZXIsIHJvb3QpO1xuICAgIGlmICghc3RhcnRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgc3RhcnRDb250YWluZXIgWFBhdGgnKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmRDb250YWluZXIgPSBub2RlRnJvbVhQYXRoKHNlbGVjdG9yLmVuZENvbnRhaW5lciwgcm9vdCk7XG4gICAgaWYgKCFlbmRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgZW5kQ29udGFpbmVyIFhQYXRoJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBzdGFydENvbnRhaW5lcixcbiAgICAgIHNlbGVjdG9yLnN0YXJ0T2Zmc2V0XG4gICAgKTtcbiAgICBjb25zdCBlbmRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBlbmRDb250YWluZXIsXG4gICAgICBzZWxlY3Rvci5lbmRPZmZzZXRcbiAgICApO1xuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgVGV4dFJhbmdlKHN0YXJ0UG9zLCBlbmRQb3MpLnRvUmFuZ2UoKTtcbiAgICByZXR1cm4gbmV3IFJhbmdlQW5jaG9yKHJvb3QsIHJhbmdlKTtcbiAgfVxuXG4gIHRvUmFuZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMucmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7UmFuZ2VTZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgLy8gXCJTaHJpbmtcIiB0aGUgcmFuZ2Ugc28gdGhhdCBpdCB0aWdodGx5IHdyYXBzIGl0cyB0ZXh0LiBUaGlzIGVuc3VyZXMgbW9yZVxuICAgIC8vIHByZWRpY3RhYmxlIG91dHB1dCBmb3IgYSBnaXZlbiB0ZXh0IHNlbGVjdGlvbi5cbiAgICBjb25zdCBub3JtYWxpemVkUmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHRoaXMucmFuZ2UpLnRvUmFuZ2UoKTtcblxuICAgIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2Uobm9ybWFsaXplZFJhbmdlKTtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IHhwYXRoRnJvbU5vZGUodGV4dFJhbmdlLnN0YXJ0LmVsZW1lbnQsIHRoaXMucm9vdCk7XG4gICAgY29uc3QgZW5kQ29udGFpbmVyID0geHBhdGhGcm9tTm9kZSh0ZXh0UmFuZ2UuZW5kLmVsZW1lbnQsIHRoaXMucm9vdCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1JhbmdlU2VsZWN0b3InLFxuICAgICAgc3RhcnRDb250YWluZXIsXG4gICAgICBzdGFydE9mZnNldDogdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldCxcbiAgICAgIGVuZENvbnRhaW5lcixcbiAgICAgIGVuZE9mZnNldDogdGV4dFJhbmdlLmVuZC5vZmZzZXQsXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFRleHRQb3NpdGlvblNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbkFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICB0aGlzLmVuZCA9IGVuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKFxuICAgICAgcm9vdCxcbiAgICAgIHRleHRSYW5nZS5zdGFydC5vZmZzZXQsXG4gICAgICB0ZXh0UmFuZ2UuZW5kLm9mZnNldFxuICAgICk7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvblNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKHJvb3QsIHNlbGVjdG9yLnN0YXJ0LCBzZWxlY3Rvci5lbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvblNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRQb3NpdGlvblNlbGVjdG9yJyxcbiAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0LFxuICAgICAgZW5kOiB0aGlzLmVuZCxcbiAgICB9O1xuICB9XG5cbiAgdG9SYW5nZSgpIHtcbiAgICByZXR1cm4gVGV4dFJhbmdlLmZyb21PZmZzZXRzKHRoaXMucm9vdCwgdGhpcy5zdGFydCwgdGhpcy5lbmQpLnRvUmFuZ2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIFF1b3RlTWF0Y2hPcHRpb25zXG4gKiBAcHJvcCB7bnVtYmVyfSBbaGludF0gLSBFeHBlY3RlZCBwb3NpdGlvbiBvZiBtYXRjaCBpbiB0ZXh0LiBTZWUgYG1hdGNoUXVvdGVgLlxuICovXG5cbi8qKlxuICogQ29udmVydHMgYmV0d2VlbiBgVGV4dFF1b3RlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgVGV4dFF1b3RlQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdCAtIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXhhY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQucHJlZml4XVxuICAgKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5zdWZmaXhdXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCBleGFjdCwgY29udGV4dCA9IHt9KSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLmV4YWN0ID0gZXhhY3Q7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBgVGV4dFF1b3RlQW5jaG9yYCBmcm9tIGEgcmFuZ2UuXG4gICAqXG4gICAqIFdpbGwgdGhyb3cgaWYgYHJhbmdlYCBkb2VzIG5vdCBjb250YWluIGFueSB0ZXh0IG5vZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyb290LnRleHRDb250ZW50KTtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuXG4gICAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICAgIGNvbnN0IGVuZCA9IHRleHRSYW5nZS5lbmQub2Zmc2V0O1xuXG4gICAgLy8gTnVtYmVyIG9mIGNoYXJhY3RlcnMgYXJvdW5kIHRoZSBxdW90ZSB0byBjYXB0dXJlIGFzIGNvbnRleHQuIFdlIGN1cnJlbnRseVxuICAgIC8vIGFsd2F5cyB1c2UgYSBmaXhlZCBhbW91bnQsIGJ1dCBpdCB3b3VsZCBiZSBiZXR0ZXIgaWYgdGhpcyBjb2RlIHdhcyBhd2FyZVxuICAgIC8vIG9mIGxvZ2ljYWwgYm91bmRhcmllcyBpbiB0aGUgZG9jdW1lbnQgKHBhcmFncmFwaCwgYXJ0aWNsZSBldGMuKSB0byBhdm9pZFxuICAgIC8vIGNhcHR1cmluZyB0ZXh0IHVucmVsYXRlZCB0byB0aGUgcXVvdGUuXG4gICAgLy9cbiAgICAvLyBJbiByZWd1bGFyIHByb3NlIHRoZSBpZGVhbCBjb250ZW50IHdvdWxkIG9mdGVuIGJlIHRoZSBzdXJyb3VuZGluZyBzZW50ZW5jZS5cbiAgICAvLyBUaGlzIGlzIGEgbmF0dXJhbCB1bml0IG9mIG1lYW5pbmcgd2hpY2ggZW5hYmxlcyBkaXNwbGF5aW5nIHF1b3RlcyBpblxuICAgIC8vIGNvbnRleHQgZXZlbiB3aGVuIHRoZSBkb2N1bWVudCBpcyBub3QgYXZhaWxhYmxlLiBXZSBjb3VsZCB1c2UgYEludGwuU2VnbWVudGVyYFxuICAgIC8vIGZvciB0aGlzIHdoZW4gYXZhaWxhYmxlLlxuICAgIGNvbnN0IGNvbnRleHRMZW4gPSAzMjtcblxuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHRleHQuc2xpY2Uoc3RhcnQsIGVuZCksIHtcbiAgICAgIHByZWZpeDogdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIGNvbnRleHRMZW4pLCBzdGFydCksXG4gICAgICBzdWZmaXg6IHRleHQuc2xpY2UoZW5kLCBNYXRoLm1pbih0ZXh0Lmxlbmd0aCwgZW5kICsgY29udGV4dExlbikpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRRdW90ZVNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIGNvbnN0IHsgcHJlZml4LCBzdWZmaXggfSA9IHNlbGVjdG9yO1xuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHNlbGVjdG9yLmV4YWN0LCB7IHByZWZpeCwgc3VmZml4IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRRdW90ZVNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRRdW90ZVNlbGVjdG9yJyxcbiAgICAgIGV4YWN0OiB0aGlzLmV4YWN0LFxuICAgICAgcHJlZml4OiB0aGlzLmNvbnRleHQucHJlZml4LFxuICAgICAgc3VmZml4OiB0aGlzLmNvbnRleHQuc3VmZml4LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtRdW90ZU1hdGNoT3B0aW9uc30gW29wdGlvbnNdXG4gICAqL1xuICB0b1JhbmdlKG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnRvUG9zaXRpb25BbmNob3Iob3B0aW9ucykudG9SYW5nZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVvdGVNYXRjaE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKi9cbiAgdG9Qb3NpdGlvbkFuY2hvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovICh0aGlzLnJvb3QudGV4dENvbnRlbnQpO1xuICAgIGNvbnN0IG1hdGNoID0gbWF0Y2hRdW90ZSh0ZXh0LCB0aGlzLmV4YWN0LCB7XG4gICAgICAuLi50aGlzLmNvbnRleHQsXG4gICAgICBoaW50OiBvcHRpb25zLmhpbnQsXG4gICAgfSk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdRdW90ZSBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb25BbmNob3IodGhpcy5yb290LCBtYXRjaC5zdGFydCwgbWF0Y2guZW5kKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgVGV4dFF1b3RlQW5jaG9yIH0gZnJvbSBcIi4vdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzXCI7XG5cbi8vIENhdGNoIEpTIGVycm9ycyB0byBsb2cgdGhlbSBpbiB0aGUgYXBwLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwiZXJyb3JcIixcbiAgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgQW5kcm9pZC5sb2dFcnJvcihldmVudC5tZXNzYWdlLCBldmVudC5maWxlbmFtZSwgZXZlbnQubGluZW5vKTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIG9uVmlld3BvcnRXaWR0aENoYW5nZWQoKTtcbiAgICAgIHNuYXBDdXJyZW50T2Zmc2V0KCk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudC5ib2R5KTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbi8qKlxuICogSGF2aW5nIGFuIG9kZCBudW1iZXIgb2YgY29sdW1ucyB3aGVuIGRpc3BsYXlpbmcgdHdvIGNvbHVtbnMgcGVyIHNjcmVlbiBjYXVzZXMgc25hcHBpbmcgYW5kIHBhZ2VcbiAqIHR1cm5pbmcgaXNzdWVzLiBUbyBmaXggdGhpcywgd2UgaW5zZXJ0IGEgYmxhbmsgdmlydHVhbCBjb2x1bW4gYXQgdGhlIGVuZCBvZiB0aGUgcmVzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGFwcGVuZFZpcnR1YWxDb2x1bW5JZk5lZWRlZCgpIHtcbiAgY29uc3QgaWQgPSBcInJlYWRpdW0tdmlydHVhbC1wYWdlXCI7XG4gIHZhciB2aXJ0dWFsQ29sID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHx8IGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkgIT0gMikge1xuICAgIGlmICh2aXJ0dWFsQ29sKSB7XG4gICAgICB2aXJ0dWFsQ29sLnJlbW92ZSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGNvbENvdW50ID0gZG9jdW1lbnRXaWR0aCAvIHBhZ2VXaWR0aDtcbiAgICB2YXIgaGFzT2RkQ29sQ291bnQgPSAoTWF0aC5yb3VuZChjb2xDb3VudCAqIDIpIC8gMikgJSAxID4gMC4xO1xuICAgIGlmIChoYXNPZGRDb2xDb3VudCkge1xuICAgICAgaWYgKHZpcnR1YWxDb2wpIHtcbiAgICAgICAgdmlydHVhbENvbC5yZW1vdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpcnR1YWxDb2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICB2aXJ0dWFsQ29sLnNldEF0dHJpYnV0ZShcImlkXCIsIGlkKTtcbiAgICAgICAgdmlydHVhbENvbC5zdHlsZS5icmVha0JlZm9yZSA9IFwiY29sdW1uXCI7XG4gICAgICAgIHZpcnR1YWxDb2wuaW5uZXJIVE1MID0gXCImIzgyMDM7XCI7IC8vIHplcm8td2lkdGggc3BhY2VcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh2aXJ0dWFsQ29sKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHZhciBwYWdlV2lkdGggPSAxO1xuXG5mdW5jdGlvbiBvblZpZXdwb3J0V2lkdGhDaGFuZ2VkKCkge1xuICAvLyBXZSBjYW4ndCByZWx5IG9uIHdpbmRvdy5pbm5lcldpZHRoIGZvciB0aGUgcGFnZVdpZHRoIG9uIEFuZHJvaWQsIGJlY2F1c2UgaWYgdGhlXG4gIC8vIGRldmljZSBwaXhlbCByYXRpbyBpcyBub3QgYW4gaW50ZWdlciwgd2UgZ2V0IHJvdW5kaW5nIGlzc3VlcyBvZmZzZXR0aW5nIHRoZSBwYWdlcy5cbiAgLy9cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFkaXVtL3JlYWRpdW0tY3NzL2lzc3Vlcy85N1xuICAvLyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL3JlYWRpdW0vcjItbmF2aWdhdG9yLWtvdGxpbi9pc3N1ZXMvMTQ2XG4gIHZhciB3aWR0aCA9IEFuZHJvaWQuZ2V0Vmlld3BvcnRXaWR0aCgpO1xuICBwYWdlV2lkdGggPSB3aWR0aCAvIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBzZXRQcm9wZXJ0eShcbiAgICBcIi0tUlNfX3ZpZXdwb3J0V2lkdGhcIixcbiAgICBcImNhbGMoXCIgKyB3aWR0aCArIFwicHggLyBcIiArIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICsgXCIpXCJcbiAgKTtcblxuICBhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkge1xuICByZXR1cm4gcGFyc2VJbnQoXG4gICAgd2luZG93XG4gICAgICAuZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpXG4gICAgICAuZ2V0UHJvcGVydHlWYWx1ZShcImNvbHVtbi1jb3VudFwiKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHtcbiAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGU7XG4gIHJldHVybiAoXG4gICAgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tVVNFUl9fdmlld1wiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiIHx8XG4gICAgLy8gRklYTUU6IFdpbGwgbmVlZCB0byBiZSByZW1vdmVkIGluIFJlYWRpdW0gMy4wLCAtLVVTRVJfX3Njcm9sbCB3YXMgaW5jb3JyZWN0LlxuICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLVVTRVJfX3Njcm9sbFwiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JUTCgpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmJvZHkuZGlyLnRvTG93ZXJDYXNlKCkgPT0gXCJydGxcIjtcbn1cblxuLy8gU2Nyb2xsIHRvIHRoZSBnaXZlbiBUYWdJZCBpbiBkb2N1bWVudCBhbmQgc25hcC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb0lkKGlkKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gc2Nyb2xsVG9SZWN0KGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG4vLyBQb3NpdGlvbiBtdXN0IGJlIGluIHRoZSByYW5nZSBbMCAtIDFdLCAwLTEwMCUuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb1Bvc2l0aW9uIFwiICsgcG9zaXRpb24pO1xuICBpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID4gMSkge1xuICAgIHRocm93IFwic2Nyb2xsVG9Qb3NpdGlvbigpIG11c3QgYmUgZ2l2ZW4gYSBwb3NpdGlvbiBmcm9tIDAuMCB0byAgMS4wXCI7XG4gIH1cblxuICBsZXQgb2Zmc2V0O1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxIZWlnaHQgKiBwb3NpdGlvbjtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IG9mZnNldDtcbiAgICAvLyB3aW5kb3cuc2Nyb2xsVG8oMCwgb2Zmc2V0KTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnRXaWR0aCAqIHBvc2l0aW9uICogZmFjdG9yO1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgfVxufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBnaXZlbiB0ZXh0IHNuaXBwZXQuXG4vL1xuLy8gVGhlIGV4cGVjdGVkIHRleHQgYXJndW1lbnQgaXMgYSBMb2NhdG9yIFRleHQgb2JqZWN0LCBhcyBkZWZpbmVkIGhlcmU6XG4vLyBodHRwczovL3JlYWRpdW0ub3JnL2FyY2hpdGVjdHVyZS9tb2RlbHMvbG9jYXRvcnMvXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9UZXh0KHRleHQpIHtcbiAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcih7IHRleHQgfSk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc2Nyb2xsVG9SYW5nZShyYW5nZSk7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JhbmdlKHJhbmdlKSB7XG4gIHJldHVybiBzY3JvbGxUb1JlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JlY3QocmVjdCkge1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPVxuICAgICAgcmVjdC50b3AgKyB3aW5kb3cuc2Nyb2xsWSAtIHdpbmRvdy5pbm5lckhlaWdodCAvIDI7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChcbiAgICAgIHJlY3QubGVmdCArIHdpbmRvdy5zY3JvbGxYXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9TdGFydCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9TdGFydFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gMDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgMCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvRW5kKCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb0VuZFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KFxuICAgICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aCAqIGZhY3RvclxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQpO1xuICB9XG59XG5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2UgaXMgYWxyZWFkeSBhdCB0aGUgbGVmdC1tb3N0IHNjcm9sbCBvZmZzZXQuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsTGVmdCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggLSBwYWdlV2lkdGg7XG4gIHZhciBtaW5PZmZzZXQgPSBpc1JUTCgpID8gLShkb2N1bWVudFdpZHRoIC0gcGFnZVdpZHRoKSA6IDA7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1heChvZmZzZXQsIG1pbk9mZnNldCkpO1xufVxuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIGlzIGFscmVhZHkgYXQgdGhlIHJpZ2h0LW1vc3Qgc2Nyb2xsIG9mZnNldC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxSaWdodCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggKyBwYWdlV2lkdGg7XG4gIHZhciBtYXhPZmZzZXQgPSBpc1JUTCgpID8gMCA6IGRvY3VtZW50V2lkdGggLSBwYWdlV2lkdGg7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1pbihvZmZzZXQsIG1heE9mZnNldCkpO1xufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBnaXZlbiBsZWZ0IG9mZnNldC5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2Ugc2Nyb2xsIHBvc2l0aW9uIGlzIGFscmVhZHkgY2xvc2UgZW5vdWdoIHRvIHRoZSBnaXZlbiBvZmZzZXQuXG5mdW5jdGlvbiBzY3JvbGxUb09mZnNldChvZmZzZXQpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9PZmZzZXQgXCIgKyBvZmZzZXQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgdGhyb3cgXCJDYWxsZWQgc2Nyb2xsVG9PZmZzZXQoKSB3aXRoIHNjcm9sbCBtb2RlIGVuYWJsZWQuIFRoaXMgY2FuIG9ubHkgYmUgdXNlZCBpbiBwYWdpbmF0ZWQgbW9kZS5cIjtcbiAgfVxuXG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgLy8gSW4gc29tZSBjYXNlIHRoZSBzY3JvbGxYIGNhbm5vdCByZWFjaCB0aGUgcG9zaXRpb24gcmVzcGVjdGluZyB0byBpbm5lcldpZHRoXG4gIHZhciBkaWZmID0gTWF0aC5hYnMoY3VycmVudE9mZnNldCAtIG9mZnNldCkgLyBwYWdlV2lkdGg7XG4gIHJldHVybiBkaWZmID4gMC4wMTtcbn1cblxuLy8gU25hcCB0aGUgb2Zmc2V0IHRvIHRoZSBzY3JlZW4gd2lkdGggKHBhZ2Ugd2lkdGgpLlxuZnVuY3Rpb24gc25hcE9mZnNldChvZmZzZXQpIHtcbiAgdmFyIHZhbHVlID0gb2Zmc2V0ICsgKGlzUlRMKCkgPyAtMSA6IDEpO1xuICByZXR1cm4gdmFsdWUgLSAodmFsdWUgJSBwYWdlV2lkdGgpO1xufVxuXG4vLyBTbmFwcyB0aGUgY3VycmVudCBvZmZzZXQgdG8gdGhlIHBhZ2Ugd2lkdGguXG5leHBvcnQgZnVuY3Rpb24gc25hcEN1cnJlbnRPZmZzZXQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNuYXBDdXJyZW50T2Zmc2V0XCIpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIC8vIEFkZHMgaGFsZiBhIHBhZ2UgdG8gbWFrZSBzdXJlIHdlIGRvbid0IHNuYXAgdG8gdGhlIHByZXZpb3VzIHBhZ2UuXG4gIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICB2YXIgZGVsdGEgPSBmYWN0b3IgKiAocGFnZVdpZHRoIC8gMik7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoY3VycmVudE9mZnNldCArIGRlbHRhKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlRnJvbUxvY2F0b3IobG9jYXRvcikge1xuICB0cnkge1xuICAgIGxldCBsb2NhdGlvbnMgPSBsb2NhdG9yLmxvY2F0aW9ucztcbiAgICBsZXQgdGV4dCA9IGxvY2F0b3IudGV4dDtcbiAgICBpZiAodGV4dCAmJiB0ZXh0LmhpZ2hsaWdodCkge1xuICAgICAgdmFyIHJvb3Q7XG4gICAgICBpZiAobG9jYXRpb25zICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICByb290ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuICAgICAgaWYgKCFyb290KSB7XG4gICAgICAgIHJvb3QgPSBkb2N1bWVudC5ib2R5O1xuICAgICAgfVxuXG4gICAgICBsZXQgYW5jaG9yID0gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCB0ZXh0LmhpZ2hsaWdodCwge1xuICAgICAgICBwcmVmaXg6IHRleHQuYmVmb3JlLFxuICAgICAgICBzdWZmaXg6IHRleHQuYWZ0ZXIsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhbmNob3IudG9SYW5nZSgpO1xuICAgIH1cblxuICAgIGlmIChsb2NhdGlvbnMpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gbnVsbDtcblxuICAgICAgaWYgKCFlbGVtZW50ICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnQgJiYgbG9jYXRpb25zLmZyYWdtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IGh0bWxJZCBvZiBsb2NhdGlvbnMuZnJhZ21lbnRzKSB7XG4gICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGh0bWxJZCk7XG4gICAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBsZXQgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEJlZm9yZShlbGVtZW50KTtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kQWZ0ZXIoZWxlbWVudCk7XG4gICAgICAgIHJldHVybiByYW5nZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dFcnJvcihlKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vLy8gVXNlciBTZXR0aW5ncy5cblxuZXhwb3J0IGZ1bmN0aW9uIHNldENTU1Byb3BlcnRpZXMocHJvcGVydGllcykge1xuICBmb3IgKGNvbnN0IG5hbWUgaW4gcHJvcGVydGllcykge1xuICAgIHNldFByb3BlcnR5KG5hbWUsIHByb3BlcnRpZXNbbmFtZV0pO1xuICB9XG59XG5cbi8vIEZvciBzZXR0aW5nIHVzZXIgc2V0dGluZy5cbmV4cG9ydCBmdW5jdGlvbiBzZXRQcm9wZXJ0eShrZXksIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikge1xuICAgIHJlbW92ZVByb3BlcnR5KGtleSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgLy8gVGhlIGAhaW1wb3J0YW50YCBhbm5vdGF0aW9uIGlzIGFkZGVkIHdpdGggYHNldFByb3BlcnR5KClgIGJlY2F1c2UgaWYgaXQncyBwYXJ0IG9mIHRoZVxuICAgIC8vIGB2YWx1ZWAsIGl0IHdpbGwgYmUgaWdub3JlZCBieSB0aGUgV2ViIFZpZXcuXG4gICAgcm9vdC5zdHlsZS5zZXRQcm9wZXJ0eShrZXksIHZhbHVlLCBcImltcG9ydGFudFwiKTtcbiAgfVxufVxuXG4vLyBGb3IgcmVtb3ZpbmcgdXNlciBzZXR0aW5nLlxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5KGtleSkge1xuICB2YXIgcm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuICByb290LnN0eWxlLnJlbW92ZVByb3BlcnR5KGtleSk7XG59XG5cbi8vLyBUb29sa2l0XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2coKSB7XG4gIHZhciBtZXNzYWdlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKFwiIFwiKTtcbiAgQW5kcm9pZC5sb2cobWVzc2FnZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dFcnJvcihtZXNzYWdlKSB7XG4gIEFuZHJvaWQubG9nRXJyb3IobWVzc2FnZSwgXCJcIiwgMCk7XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBsb2cgYXMgbG9nTmF0aXZlIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuY29uc3QgZGVidWcgPSBmYWxzZTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIERPTVJlY3QgaW50byBhIEpTT04gb2JqZWN0IHVuZGVyc3RhbmRhYmxlIGJ5IHRoZSBuYXRpdmUgc2lkZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvTmF0aXZlUmVjdChyZWN0KSB7XG4gIGNvbnN0IHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgY29uc3Qgd2lkdGggPSByZWN0LndpZHRoICogcGl4ZWxSYXRpbztcbiAgY29uc3QgaGVpZ2h0ID0gcmVjdC5oZWlnaHQgKiBwaXhlbFJhdGlvO1xuICBjb25zdCBsZWZ0ID0gcmVjdC5sZWZ0ICogcGl4ZWxSYXRpbztcbiAgY29uc3QgdG9wID0gcmVjdC50b3AgKiBwaXhlbFJhdGlvO1xuICBjb25zdCByaWdodCA9IGxlZnQgKyB3aWR0aDtcbiAgY29uc3QgYm90dG9tID0gdG9wICsgaGVpZ2h0O1xuICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0LCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20gfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICByYW5nZSxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGxldCBjbGllbnRSZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG5cbiAgY29uc3QgdG9sZXJhbmNlID0gMTtcbiAgY29uc3Qgb3JpZ2luYWxSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJhbmdlQ2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIG9yaWdpbmFsUmVjdHMucHVzaCh7XG4gICAgICBib3R0b206IHJhbmdlQ2xpZW50UmVjdC5ib3R0b20sXG4gICAgICBoZWlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUNsaWVudFJlY3QubGVmdCxcbiAgICAgIHJpZ2h0OiByYW5nZUNsaWVudFJlY3QucmlnaHQsXG4gICAgICB0b3A6IHJhbmdlQ2xpZW50UmVjdC50b3AsXG4gICAgICB3aWR0aDogcmFuZ2VDbGllbnRSZWN0LndpZHRoLFxuICAgIH0pO1xuICB9XG4gIGNvbnN0IG1lcmdlZFJlY3RzID0gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgIG9yaWdpbmFsUmVjdHMsXG4gICAgdG9sZXJhbmNlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgY29uc3Qgbm9Db250YWluZWRSZWN0cyA9IHJlbW92ZUNvbnRhaW5lZFJlY3RzKG1lcmdlZFJlY3RzLCB0b2xlcmFuY2UpO1xuICBjb25zdCBuZXdSZWN0cyA9IHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobm9Db250YWluZWRSZWN0cyk7XG4gIGNvbnN0IG1pbkFyZWEgPSAyICogMjtcbiAgZm9yIChsZXQgaiA9IG5ld1JlY3RzLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgY29uc3QgcmVjdCA9IG5ld1JlY3RzW2pdO1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggKiByZWN0LmhlaWdodCA+IG1pbkFyZWE7XG4gICAgaWYgKCFiaWdFbm91Z2gpIHtcbiAgICAgIGlmIChuZXdSZWN0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGxcIik7XG4gICAgICAgIG5ld1JlY3RzLnNwbGljZShqLCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGwsIGJ1dCBrZWVwIG90aGVyd2lzZSBlbXB0eSFcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBsb2coYENMSUVOVCBSRUNUOiByZWR1Y2VkICR7b3JpZ2luYWxSZWN0cy5sZW5ndGh9IC0tPiAke25ld1JlY3RzLmxlbmd0aH1gKTtcbiAgcmV0dXJuIG5ld1JlY3RzO1xufVxuXG5mdW5jdGlvbiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gIHJlY3RzLFxuICB0b2xlcmFuY2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJtZXJnZVRvdWNoaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0c0xpbmVVcFZlcnRpY2FsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIubGVmdCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCBob3Jpem9udGFsQWxsb3dlZCA9ICFkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzO1xuICAgICAgY29uc3QgYWxpZ25lZCA9XG4gICAgICAgIChyZWN0c0xpbmVVcEhvcml6b250YWxseSAmJiBob3Jpem9udGFsQWxsb3dlZCkgfHxcbiAgICAgICAgKHJlY3RzTGluZVVwVmVydGljYWxseSAmJiAhcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkpO1xuICAgICAgY29uc3QgY2FuTWVyZ2UgPSBhbGlnbmVkICYmIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpO1xuICAgICAgaWYgKGNhbk1lcmdlKSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICBgQ0xJRU5UIFJFQ1Q6IG1lcmdpbmcgdHdvIGludG8gb25lLCBWRVJUSUNBTDogJHtyZWN0c0xpbmVVcFZlcnRpY2FsbHl9IEhPUklaT05UQUw6ICR7cmVjdHNMaW5lVXBIb3Jpem9udGFsbHl9ICgke2RvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHN9KWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gcmVjdDEgJiYgcmVjdCAhPT0gcmVjdDI7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXBsYWNlbWVudENsaWVudFJlY3QgPSBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgbmV3UmVjdHMucHVzaChyZXBsYWNlbWVudENsaWVudFJlY3QpO1xuICAgICAgICByZXR1cm4gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgICAgICAgIG5ld1JlY3RzLFxuICAgICAgICAgIHRvbGVyYW5jZSxcbiAgICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCBsZWZ0ID0gTWF0aC5taW4ocmVjdDEubGVmdCwgcmVjdDIubGVmdCk7XG4gIGNvbnN0IHJpZ2h0ID0gTWF0aC5tYXgocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0KTtcbiAgY29uc3QgdG9wID0gTWF0aC5taW4ocmVjdDEudG9wLCByZWN0Mi50b3ApO1xuICBjb25zdCBib3R0b20gPSBNYXRoLm1heChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSk7XG4gIHJldHVybiB7XG4gICAgYm90dG9tLFxuICAgIGhlaWdodDogYm90dG9tIC0gdG9wLFxuICAgIGxlZnQsXG4gICAgcmlnaHQsXG4gICAgdG9wLFxuICAgIHdpZHRoOiByaWdodCAtIGxlZnQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNvbnRhaW5lZFJlY3RzKHJlY3RzLCB0b2xlcmFuY2UpIHtcbiAgY29uc3QgcmVjdHNUb0tlZXAgPSBuZXcgU2V0KHJlY3RzKTtcbiAgZm9yIChjb25zdCByZWN0IG9mIHJlY3RzKSB7XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCA+IDEgJiYgcmVjdC5oZWlnaHQgPiAxO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHRpbnlcIik7XG4gICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwb3NzaWJseUNvbnRhaW5pbmdSZWN0IG9mIHJlY3RzKSB7XG4gICAgICBpZiAocmVjdCA9PT0gcG9zc2libHlDb250YWluaW5nUmVjdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjdHNUb0tlZXAuaGFzKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RDb250YWlucyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0LCByZWN0LCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgY29udGFpbmVkXCIpO1xuICAgICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gQXJyYXkuZnJvbShyZWN0c1RvS2VlcCk7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWlucyhyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjdENvbnRhaW5zUG9pbnQocmVjdCwgeCwgeSwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QubGVmdCA8IHggfHwgYWxtb3N0RXF1YWwocmVjdC5sZWZ0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnJpZ2h0ID4geCB8fCBhbG1vc3RFcXVhbChyZWN0LnJpZ2h0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnRvcCA8IHkgfHwgYWxtb3N0RXF1YWwocmVjdC50b3AsIHksIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QuYm90dG9tID4geSB8fCBhbG1vc3RFcXVhbChyZWN0LmJvdHRvbSwgeSwgdG9sZXJhbmNlKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhyZWN0cykge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgbGV0IHRvQWRkID0gW107XG4gICAgICAgIGxldCB0b1JlbW92ZTtcbiAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czEgPSByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMiA9IHJlY3RTdWJ0cmFjdChyZWN0MiwgcmVjdDEpO1xuICAgICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPCBzdWJ0cmFjdFJlY3RzMi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMyO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbG9nKGBDTElFTlQgUkVDVDogb3ZlcmxhcCwgY3V0IG9uZSByZWN0IGludG8gJHt0b0FkZC5sZW5ndGh9YCk7XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHRvUmVtb3ZlO1xuICAgICAgICB9KTtcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkobmV3UmVjdHMsIHRvQWRkKTtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobmV3UmVjdHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgcmVjdEludGVyc2VjdGVkID0gcmVjdEludGVyc2VjdChyZWN0MiwgcmVjdDEpO1xuICBpZiAocmVjdEludGVyc2VjdGVkLmhlaWdodCA9PT0gMCB8fCByZWN0SW50ZXJzZWN0ZWQud2lkdGggPT09IDApIHtcbiAgICByZXR1cm4gW3JlY3QxXTtcbiAgfVxuICBjb25zdCByZWN0cyA9IFtdO1xuICB7XG4gICAgY29uc3QgcmVjdEEgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3QxLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEEud2lkdGggPSByZWN0QS5yaWdodCAtIHJlY3RBLmxlZnQ7XG4gICAgcmVjdEEuaGVpZ2h0ID0gcmVjdEEuYm90dG9tIC0gcmVjdEEudG9wO1xuICAgIGlmIChyZWN0QS5oZWlnaHQgIT09IDAgJiYgcmVjdEEud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEEpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEIgPSB7XG4gICAgICBib3R0b206IHJlY3RJbnRlcnNlY3RlZC50b3AsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEIud2lkdGggPSByZWN0Qi5yaWdodCAtIHJlY3RCLmxlZnQ7XG4gICAgcmVjdEIuaGVpZ2h0ID0gcmVjdEIuYm90dG9tIC0gcmVjdEIudG9wO1xuICAgIGlmIChyZWN0Qi5oZWlnaHQgIT09IDAgJiYgcmVjdEIud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEIpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEMgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdEludGVyc2VjdGVkLmJvdHRvbSxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEMud2lkdGggPSByZWN0Qy5yaWdodCAtIHJlY3RDLmxlZnQ7XG4gICAgcmVjdEMuaGVpZ2h0ID0gcmVjdEMuYm90dG9tIC0gcmVjdEMudG9wO1xuICAgIGlmIChyZWN0Qy5oZWlnaHQgIT09IDAgJiYgcmVjdEMud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEMpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEQgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHJpZ2h0OiByZWN0MS5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0RC53aWR0aCA9IHJlY3RELnJpZ2h0IC0gcmVjdEQubGVmdDtcbiAgICByZWN0RC5oZWlnaHQgPSByZWN0RC5ib3R0b20gLSByZWN0RC50b3A7XG4gICAgaWYgKHJlY3RELmhlaWdodCAhPT0gMCAmJiByZWN0RC53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0RCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gcmVjdEludGVyc2VjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbWF4TGVmdCA9IE1hdGgubWF4KHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCBtaW5SaWdodCA9IE1hdGgubWluKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IG1heFRvcCA9IE1hdGgubWF4KHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgbWluQm90dG9tID0gTWF0aC5taW4ocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbTogbWluQm90dG9tLFxuICAgIGhlaWdodDogTWF0aC5tYXgoMCwgbWluQm90dG9tIC0gbWF4VG9wKSxcbiAgICBsZWZ0OiBtYXhMZWZ0LFxuICAgIHJpZ2h0OiBtaW5SaWdodCxcbiAgICB0b3A6IG1heFRvcCxcbiAgICB3aWR0aDogTWF0aC5tYXgoMCwgbWluUmlnaHQgLSBtYXhMZWZ0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0MS5sZWZ0IDwgcmVjdDIucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLmxlZnQgPCByZWN0MS5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLmxlZnQsIHJlY3QxLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDEudG9wIDwgcmVjdDIuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi50b3AgPCByZWN0MS5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi50b3AsIHJlY3QxLmJvdHRvbSwgdG9sZXJhbmNlKSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGFsbW9zdEVxdWFsKGEsIGIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gTWF0aC5hYnMoYSAtIGIpIDw9IHRvbGVyYW5jZTtcbn1cblxuZnVuY3Rpb24gbG9nKCkge1xuICBpZiAoZGVidWcpIHtcbiAgICBsb2dOYXRpdmUuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHtcbiAgZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAsXG4gIHJlY3RDb250YWluc1BvaW50LFxuICB0b05hdGl2ZVJlY3QsXG59IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IGxvZywgbG9nRXJyb3IsIHJhbmdlRnJvbUxvY2F0b3IgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5sZXQgc3R5bGVzID0gbmV3IE1hcCgpO1xubGV0IGdyb3VwcyA9IG5ldyBNYXAoKTtcbnZhciBsYXN0R3JvdXBJZCA9IDA7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgbGlzdCBvZiBhZGRpdGlvbmFsIHN1cHBvcnRlZCBEZWNvcmF0aW9uIFRlbXBsYXRlcy5cbiAqXG4gKiBFYWNoIHRlbXBsYXRlIG9iamVjdCBpcyBpbmRleGVkIGJ5IHRoZSBzdHlsZSBJRC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyVGVtcGxhdGVzKG5ld1N0eWxlcykge1xuICB2YXIgc3R5bGVzaGVldCA9IFwiXCI7XG5cbiAgZm9yIChjb25zdCBbaWQsIHN0eWxlXSBvZiBPYmplY3QuZW50cmllcyhuZXdTdHlsZXMpKSB7XG4gICAgc3R5bGVzLnNldChpZCwgc3R5bGUpO1xuICAgIGlmIChzdHlsZS5zdHlsZXNoZWV0KSB7XG4gICAgICBzdHlsZXNoZWV0ICs9IHN0eWxlLnN0eWxlc2hlZXQgKyBcIlxcblwiO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdHlsZXNoZWV0KSB7XG4gICAgbGV0IHN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICBzdHlsZUVsZW1lbnQuaW5uZXJIVE1MID0gc3R5bGVzaGVldDtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRGVjb3JhdGlvbkdyb3VwIGZvciB0aGUgZ2l2ZW4gZ3JvdXAgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlY29yYXRpb25zKGdyb3VwTmFtZSkge1xuICB2YXIgZ3JvdXAgPSBncm91cHMuZ2V0KGdyb3VwTmFtZSk7XG4gIGlmICghZ3JvdXApIHtcbiAgICBsZXQgaWQgPSBcInIyLWRlY29yYXRpb24tXCIgKyBsYXN0R3JvdXBJZCsrO1xuICAgIGdyb3VwID0gRGVjb3JhdGlvbkdyb3VwKGlkLCBncm91cE5hbWUpO1xuICAgIGdyb3Vwcy5zZXQoZ3JvdXBOYW1lLCBncm91cCk7XG4gIH1cbiAgcmV0dXJuIGdyb3VwO1xufVxuXG4vKipcbiAqIEhhbmRsZXMgY2xpY2sgZXZlbnRzIG9uIGEgRGVjb3JhdGlvbi5cbiAqIFJldHVybnMgd2hldGhlciBhIGRlY29yYXRpb24gbWF0Y2hlZCB0aGlzIGV2ZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQoZXZlbnQsIGNsaWNrRXZlbnQpIHtcbiAgaWYgKGdyb3Vwcy5zaXplID09PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZFRhcmdldCgpIHtcbiAgICBmb3IgKGNvbnN0IFtncm91cCwgZ3JvdXBDb250ZW50XSBvZiBncm91cHMpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBncm91cENvbnRlbnQuaXRlbXMucmV2ZXJzZSgpKSB7XG4gICAgICAgIGlmICghaXRlbS5jbGlja2FibGVFbGVtZW50cykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzKSB7XG4gICAgICAgICAgbGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvSlNPTigpO1xuICAgICAgICAgIGlmIChyZWN0Q29udGFpbnNQb2ludChyZWN0LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCAxKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgZ3JvdXAsIGl0ZW0sIGVsZW1lbnQsIHJlY3QgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgdGFyZ2V0ID0gZmluZFRhcmdldCgpO1xuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBBbmRyb2lkLm9uRGVjb3JhdGlvbkFjdGl2YXRlZChcbiAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBpZDogdGFyZ2V0Lml0ZW0uZGVjb3JhdGlvbi5pZCxcbiAgICAgIGdyb3VwOiB0YXJnZXQuZ3JvdXAsXG4gICAgICByZWN0OiB0b05hdGl2ZVJlY3QodGFyZ2V0Lml0ZW0ucmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpLFxuICAgICAgY2xpY2s6IGNsaWNrRXZlbnQsXG4gICAgfSlcbiAgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgRGVjb3JhdGlvbkdyb3VwIG9iamVjdCBmcm9tIGEgdW5pcXVlIEhUTUwgSUQgYW5kIGl0cyBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gRGVjb3JhdGlvbkdyb3VwKGdyb3VwSWQsIGdyb3VwTmFtZSkge1xuICB2YXIgaXRlbXMgPSBbXTtcbiAgdmFyIGxhc3RJdGVtSWQgPSAwO1xuICB2YXIgY29udGFpbmVyID0gbnVsbDtcblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBkZWNvcmF0aW9uIHRvIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIGFkZChkZWNvcmF0aW9uKSB7XG4gICAgbGV0IGlkID0gZ3JvdXBJZCArIFwiLVwiICsgbGFzdEl0ZW1JZCsrO1xuXG4gICAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcihkZWNvcmF0aW9uLmxvY2F0b3IpO1xuICAgIGlmICghcmFuZ2UpIHtcbiAgICAgIGxvZyhcIkNhbid0IGxvY2F0ZSBET00gcmFuZ2UgZm9yIGRlY29yYXRpb25cIiwgZGVjb3JhdGlvbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSB7IGlkLCBkZWNvcmF0aW9uLCByYW5nZSB9O1xuICAgIGl0ZW1zLnB1c2goaXRlbSk7XG4gICAgbGF5b3V0KGl0ZW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGRlY29yYXRpb24gd2l0aCBnaXZlbiBJRCBmcm9tIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZShkZWNvcmF0aW9uSWQpIHtcbiAgICBsZXQgaW5kZXggPSBpdGVtcy5maW5kSW5kZXgoKGkpID0+IGkuZGVjb3JhdGlvbi5pZCA9PT0gZGVjb3JhdGlvbklkKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSBpdGVtc1tpbmRleF07XG4gICAgaXRlbXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gbnVsbDtcbiAgICBpZiAoaXRlbS5jb250YWluZXIpIHtcbiAgICAgIGl0ZW0uY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgaXRlbS5jb250YWluZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZmllcyB0aGF0IHRoZSBnaXZlbiBkZWNvcmF0aW9uIHdhcyBtb2RpZmllZCBhbmQgbmVlZHMgdG8gYmUgdXBkYXRlZC5cbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZShkZWNvcmF0aW9uKSB7XG4gICAgcmVtb3ZlKGRlY29yYXRpb24uaWQpO1xuICAgIGFkZChkZWNvcmF0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFsbCBkZWNvcmF0aW9ucyBmcm9tIHRoaXMgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICBjbGVhckNvbnRhaW5lcigpO1xuICAgIGl0ZW1zLmxlbmd0aCA9IDA7XG4gIH1cblxuICAvKipcbiAgICogUmVjcmVhdGVzIHRoZSBkZWNvcmF0aW9uIGVsZW1lbnRzLlxuICAgKlxuICAgKiBUbyBiZSBjYWxsZWQgYWZ0ZXIgcmVmbG93aW5nIHRoZSByZXNvdXJjZSwgZm9yIGV4YW1wbGUuXG4gICAqL1xuICBmdW5jdGlvbiByZXF1ZXN0TGF5b3V0KCkge1xuICAgIGNsZWFyQ29udGFpbmVyKCk7XG4gICAgaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4gbGF5b3V0KGl0ZW0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXlvdXRzIGEgc2luZ2xlIERlY29yYXRpb24gaXRlbS5cbiAgICovXG4gIGZ1bmN0aW9uIGxheW91dChpdGVtKSB7XG4gICAgbGV0IGdyb3VwQ29udGFpbmVyID0gcmVxdWlyZUNvbnRhaW5lcigpO1xuXG4gICAgbGV0IHN0eWxlID0gc3R5bGVzLmdldChpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGlmICghc3R5bGUpIHtcbiAgICAgIGxvZ0Vycm9yKGBVbmtub3duIGRlY29yYXRpb24gc3R5bGU6ICR7aXRlbS5kZWNvcmF0aW9uLnN0eWxlfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBpdGVtQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIGl0ZW0uaWQpO1xuICAgIGl0ZW1Db250YWluZXIuc2V0QXR0cmlidXRlKFwiZGF0YS1zdHlsZVwiLCBpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGl0ZW1Db250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG5cbiAgICBsZXQgdmlld3BvcnRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgIGxldCBjb2x1bW5Db3VudCA9IHBhcnNlSW50KFxuICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXG4gICAgICAgIFwiY29sdW1uLWNvdW50XCJcbiAgICAgIClcbiAgICApO1xuICAgIGxldCBwYWdlV2lkdGggPSB2aWV3cG9ydFdpZHRoIC8gKGNvbHVtbkNvdW50IHx8IDEpO1xuICAgIGxldCBzY3JvbGxpbmdFbGVtZW50ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudDtcbiAgICBsZXQgeE9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICBsZXQgeU9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgZnVuY3Rpb24gcG9zaXRpb25FbGVtZW50KGVsZW1lbnQsIHJlY3QsIGJvdW5kaW5nUmVjdCkge1xuICAgICAgZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblxuICAgICAgaWYgKHN0eWxlLndpZHRoID09PSBcIndyYXBcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtyZWN0LmxlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJ2aWV3cG9ydFwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHt2aWV3cG9ydFdpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGxldCBsZWZ0ID0gTWF0aC5mbG9vcihyZWN0LmxlZnQgLyB2aWV3cG9ydFdpZHRoKSAqIHZpZXdwb3J0V2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJib3VuZHNcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7Ym91bmRpbmdSZWN0LndpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2JvdW5kaW5nUmVjdC5sZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwicGFnZVwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtwYWdlV2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgbGV0IGxlZnQgPSBNYXRoLmZsb29yKHJlY3QubGVmdCAvIHBhZ2VXaWR0aCkgKiBwYWdlV2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBib3VuZGluZ1JlY3QgPSBpdGVtLnJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgbGV0IGVsZW1lbnRUZW1wbGF0ZTtcbiAgICB0cnkge1xuICAgICAgbGV0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gaXRlbS5kZWNvcmF0aW9uLmVsZW1lbnQudHJpbSgpO1xuICAgICAgZWxlbWVudFRlbXBsYXRlID0gdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGRlY29yYXRpb24gZWxlbWVudCBcIiR7aXRlbS5kZWNvcmF0aW9uLmVsZW1lbnR9XCI6ICR7ZXJyb3IubWVzc2FnZX1gXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm94ZXNcIikge1xuICAgICAgbGV0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSB0cnVlO1xuICAgICAgbGV0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgICAgIGl0ZW0ucmFuZ2UsXG4gICAgICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgICAgICk7XG5cbiAgICAgIGNsaWVudFJlY3RzID0gY2xpZW50UmVjdHMuc29ydCgocjEsIHIyKSA9PiB7XG4gICAgICAgIGlmIChyMS50b3AgPCByMi50b3ApIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH0gZWxzZSBpZiAocjEudG9wID4gcjIudG9wKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBmb3IgKGxldCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBlbGVtZW50VGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBsaW5lLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICBwb3NpdGlvbkVsZW1lbnQobGluZSwgY2xpZW50UmVjdCwgYm91bmRpbmdSZWN0KTtcbiAgICAgICAgaXRlbUNvbnRhaW5lci5hcHBlbmQobGluZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm91bmRzXCIpIHtcbiAgICAgIGNvbnN0IGJvdW5kcyA9IGVsZW1lbnRUZW1wbGF0ZS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICBib3VuZHMuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBwb3NpdGlvbkVsZW1lbnQoYm91bmRzLCBib3VuZGluZ1JlY3QsIGJvdW5kaW5nUmVjdCk7XG5cbiAgICAgIGl0ZW1Db250YWluZXIuYXBwZW5kKGJvdW5kcyk7XG4gICAgfVxuXG4gICAgZ3JvdXBDb250YWluZXIuYXBwZW5kKGl0ZW1Db250YWluZXIpO1xuICAgIGl0ZW0uY29udGFpbmVyID0gaXRlbUNvbnRhaW5lcjtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gQXJyYXkuZnJvbShcbiAgICAgIGl0ZW1Db250YWluZXIucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWFjdGl2YWJsZT0nMSddXCIpXG4gICAgKTtcbiAgICBpZiAoaXRlbS5jbGlja2FibGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGl0ZW0uY2xpY2thYmxlRWxlbWVudHMgPSBBcnJheS5mcm9tKGl0ZW1Db250YWluZXIuY2hpbGRyZW4pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBncm91cCBjb250YWluZXIgZWxlbWVudCwgYWZ0ZXIgbWFraW5nIHN1cmUgaXQgZXhpc3RzLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVxdWlyZUNvbnRhaW5lcigpIHtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBncm91cElkKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJkYXRhLWdyb3VwXCIsIGdyb3VwTmFtZSk7XG4gICAgICBjb250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChjb250YWluZXIpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdyb3VwIGNvbnRhaW5lci5cbiAgICovXG4gIGZ1bmN0aW9uIGNsZWFyQ29udGFpbmVyKCkge1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGNvbnRhaW5lciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgYWRkLCByZW1vdmUsIHVwZGF0ZSwgY2xlYXIsIGl0ZW1zLCByZXF1ZXN0TGF5b3V0IH07XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIC8vIFdpbGwgcmVsYXlvdXQgYWxsIHRoZSBkZWNvcmF0aW9ucyB3aGVuIHRoZSBkb2N1bWVudCBib2R5IGlzIHJlc2l6ZWQuXG4gICAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgdmFyIGxhc3RTaXplID0geyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBsYXN0U2l6ZS53aWR0aCA9PT0gYm9keS5jbGllbnRXaWR0aCAmJlxuICAgICAgICBsYXN0U2l6ZS5oZWlnaHQgPT09IGJvZHkuY2xpZW50SGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbGFzdFNpemUgPSB7XG4gICAgICAgIHdpZHRoOiBib2R5LmNsaWVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGJvZHkuY2xpZW50SGVpZ2h0LFxuICAgICAgfTtcblxuICAgICAgZ3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIGdyb3VwLnJlcXVlc3RMYXlvdXQoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoYm9keSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMiBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgaXNTY3JvbGxNb2RlRW5hYmxlZCB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBnZXRDc3NTZWxlY3RvciB9IGZyb20gXCJjc3Mtc2VsZWN0b3ItZ2VuZXJhdG9yXCI7XG5cbi8vIFNlZS4gaHR0cHM6Ly9naXRodWIuY29tL0pheVBhbm96L2FyY2hpdGVjdHVyZS90cmVlL3RvdWNoLWhhbmRsaW5nL21pc2MvdG91Y2gtaGFuZGxpbmdcbmV4cG9ydCBmdW5jdGlvbiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciBpbnRlcmFjdGl2ZVRhZ3MgPSBbXG4gICAgXCJhXCIsXG4gICAgXCJhdWRpb1wiLFxuICAgIFwiYnV0dG9uXCIsXG4gICAgXCJjYW52YXNcIixcbiAgICBcImRldGFpbHNcIixcbiAgICBcImlucHV0XCIsXG4gICAgXCJsYWJlbFwiLFxuICAgIFwib3B0aW9uXCIsXG4gICAgXCJzZWxlY3RcIixcbiAgICBcInN1Ym1pdFwiLFxuICAgIFwidGV4dGFyZWFcIixcbiAgICBcInZpZGVvXCIsXG4gIF07XG4gIGlmIChpbnRlcmFjdGl2ZVRhZ3MuaW5kZXhPZihlbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpICE9IC0xKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQub3V0ZXJIVE1MO1xuICB9XG5cbiAgLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgZWRpdGFibGUgYnkgdGhlIHVzZXIuXG4gIGlmIChcbiAgICBlbGVtZW50Lmhhc0F0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKSAmJlxuICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiY29udGVudGVkaXRhYmxlXCIpLnRvTG93ZXJDYXNlKCkgIT0gXCJmYWxzZVwiXG4gICkge1xuICAgIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgfVxuXG4gIC8vIENoZWNrcyBwYXJlbnRzIHJlY3Vyc2l2ZWx5IGJlY2F1c2UgdGhlIHRvdWNoIG1pZ2h0IGJlIGZvciBleGFtcGxlIG9uIGFuIDxlbT4gaW5zaWRlIGEgPGE+LlxuICBpZiAoZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XG4gICAgcmV0dXJuIG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZWxlbWVudC5wYXJlbnRFbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IoKSB7XG4gIGNvbnN0IGVsZW1lbnQgPSBmaW5kRWxlbWVudChkb2N1bWVudC5ib2R5KTtcbiAgcmV0dXJuIHtcbiAgICBocmVmOiBcIiNcIixcbiAgICB0eXBlOiBcImFwcGxpY2F0aW9uL3hodG1sK3htbFwiLFxuICAgIGxvY2F0aW9uczoge1xuICAgICAgY3NzU2VsZWN0b3I6IGdldENzc1NlbGVjdG9yKGVsZW1lbnQpLFxuICAgIH0sXG4gICAgdGV4dDoge1xuICAgICAgaGlnaGxpZ2h0OiBlbGVtZW50LnRleHRDb250ZW50LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZpbmRFbGVtZW50KHJvb3RFbGVtZW50KSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcm9vdEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGlsZCA9IHJvb3RFbGVtZW50LmNoaWxkcmVuW2ldO1xuICAgIGlmICghc2hvdWxkSWdub3JlRWxlbWVudChjaGlsZCkgJiYgaXNFbGVtZW50VmlzaWJsZShjaGlsZCkpIHtcbiAgICAgIHJldHVybiBmaW5kRWxlbWVudChjaGlsZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByb290RWxlbWVudDtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50VmlzaWJsZShlbGVtZW50KSB7XG4gIGlmIChyZWFkaXVtLmlzRml4ZWRMYXlvdXQpIHJldHVybiB0cnVlO1xuXG4gIGlmIChlbGVtZW50ID09PSBkb2N1bWVudC5ib2R5IHx8IGVsZW1lbnQgPT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmICghZG9jdW1lbnQgfHwgIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCAhZG9jdW1lbnQuYm9keSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuIHJlY3QuYm90dG9tID4gMCAmJiByZWN0LnRvcCA8IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5sZWZ0IDwgd2luZG93LmlubmVyV2lkdGg7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlRWxlbWVudChlbGVtZW50KSB7XG4gIGNvbnN0IGVsU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICBpZiAoZWxTdHlsZSkge1xuICAgIGNvbnN0IGRpc3BsYXkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJkaXNwbGF5XCIpO1xuICAgIGlmIChkaXNwbGF5ICE9IFwiYmxvY2tcIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENhbm5vdCBiZSByZWxpZWQgdXBvbiwgYmVjYXVzZSB3ZWIgYnJvd3NlciBlbmdpbmUgcmVwb3J0cyBpbnZpc2libGUgd2hlbiBvdXQgb2YgdmlldyBpblxuICAgIC8vIHNjcm9sbGVkIGNvbHVtbnMhXG4gICAgLy8gY29uc3QgdmlzaWJpbGl0eSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcInZpc2liaWxpdHlcIik7XG4gICAgLy8gaWYgKHZpc2liaWxpdHkgPT09IFwiaGlkZGVuXCIpIHtcbiAgICAvLyAgICAgcmV0dXJuIGZhbHNlO1xuICAgIC8vIH1cbiAgICBjb25zdCBvcGFjaXR5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwib3BhY2l0eVwiKTtcbiAgICBpZiAob3BhY2l0eSA9PT0gXCIwXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2VcbiAqIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbiAqL1xuXG5pbXBvcnQgeyBoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudCB9IGZyb20gXCIuL2RlY29yYXRvclwiO1xuaW1wb3J0IHsgbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudCB9IGZyb20gXCIuL2RvbVwiO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgZnVuY3Rpb24gKCkge1xuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgb25DbGljaywgZmFsc2UpO1xuICBiaW5kRHJhZ0dlc3R1cmUoZG9jdW1lbnQpO1xufSk7XG5cbmZ1bmN0aW9uIG9uQ2xpY2soZXZlbnQpIHtcbiAgaWYgKCF3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuaXNDb2xsYXBzZWQpIHtcbiAgICAvLyBUaGVyZSdzIGFuIG9uLWdvaW5nIHNlbGVjdGlvbiwgdGhlIHRhcCB3aWxsIGRpc21pc3MgaXQgc28gd2UgZG9uJ3QgZm9yd2FyZCBpdC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBsZXQgY2xpY2tFdmVudCA9IHtcbiAgICBkZWZhdWx0UHJldmVudGVkOiBldmVudC5kZWZhdWx0UHJldmVudGVkLFxuICAgIHg6IGV2ZW50LmNsaWVudFggKiBwaXhlbFJhdGlvLFxuICAgIHk6IGV2ZW50LmNsaWVudFkgKiBwaXhlbFJhdGlvLFxuICAgIHRhcmdldEVsZW1lbnQ6IGV2ZW50LnRhcmdldC5vdXRlckhUTUwsXG4gICAgaW50ZXJhY3RpdmVFbGVtZW50OiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGV2ZW50LnRhcmdldCksXG4gIH07XG5cbiAgaWYgKGhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50KGV2ZW50LCBjbGlja0V2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFNlbmQgdGhlIHRhcCBkYXRhIG92ZXIgdGhlIEpTIGJyaWRnZSBldmVuIGlmIGl0J3MgYmVlbiBoYW5kbGVkIHdpdGhpbiB0aGUgd2ViIHZpZXcsIHNvIHRoYXRcbiAgLy8gaXQgY2FuIGJlIHByZXNlcnZlZCBhbmQgdXNlZCBieSB0aGUgdG9vbGtpdCBpZiBuZWVkZWQuXG4gIHZhciBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25UYXAoSlNPTi5zdHJpbmdpZnkoY2xpY2tFdmVudCkpO1xuXG4gIGlmIChzaG91bGRQcmV2ZW50RGVmYXVsdCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYmluZERyYWdHZXN0dXJlKGVsZW1lbnQpIHtcbiAgLy8gcGFzc2l2ZTogZmFsc2UgaXMgbmVjZXNzYXJ5IHRvIGJlIGFibGUgdG8gcHJldmVudCB0aGUgZGVmYXVsdCBiZWhhdmlvci5cbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCBvblN0YXJ0LCB7IHBhc3NpdmU6IGZhbHNlIH0pO1xuICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBvbkVuZCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIG9uTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcblxuICB2YXIgc3RhdGUgPSB1bmRlZmluZWQ7XG4gIHZhciBpc1N0YXJ0aW5nRHJhZyA9IGZhbHNlO1xuICBjb25zdCBwaXhlbFJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG5cbiAgZnVuY3Rpb24gb25TdGFydChldmVudCkge1xuICAgIGlzU3RhcnRpbmdEcmFnID0gdHJ1ZTtcblxuICAgIGNvbnN0IHN0YXJ0WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAqIHBpeGVsUmF0aW87XG4gICAgY29uc3Qgc3RhcnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZSA9IHtcbiAgICAgIGRlZmF1bHRQcmV2ZW50ZWQ6IGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQsXG4gICAgICBzdGFydFg6IHN0YXJ0WCxcbiAgICAgIHN0YXJ0WTogc3RhcnRZLFxuICAgICAgY3VycmVudFg6IHN0YXJ0WCxcbiAgICAgIGN1cnJlbnRZOiBzdGFydFksXG4gICAgICBvZmZzZXRYOiAwLFxuICAgICAgb2Zmc2V0WTogMCxcbiAgICAgIGludGVyYWN0aXZlRWxlbWVudDogbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChldmVudC50YXJnZXQpLFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBvbk1vdmUoZXZlbnQpIHtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG5cbiAgICBzdGF0ZS5jdXJyZW50WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUuY3VycmVudFkgPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlLm9mZnNldFggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLnN0YXJ0WDtcbiAgICBzdGF0ZS5vZmZzZXRZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5zdGFydFk7XG5cbiAgICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBmYWxzZTtcbiAgICAvLyBXYWl0IGZvciBhIG1vdmVtZW50IG9mIGF0IGxlYXN0IDYgcGl4ZWxzIGJlZm9yZSByZXBvcnRpbmcgYSBkcmFnLlxuICAgIGlmIChpc1N0YXJ0aW5nRHJhZykge1xuICAgICAgaWYgKE1hdGguYWJzKHN0YXRlLm9mZnNldFgpID49IDYgfHwgTWF0aC5hYnMoc3RhdGUub2Zmc2V0WSkgPj0gNikge1xuICAgICAgICBpc1N0YXJ0aW5nRHJhZyA9IGZhbHNlO1xuICAgICAgICBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnU3RhcnQoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ01vdmUoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbkVuZChldmVudCkge1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcblxuICAgIGNvbnN0IHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdFbmQoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgc3RhdGUgPSB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjMgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQgfSBmcm9tIFwiLi9kb21cIjtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChldmVudCkgPT4ge1xuICBpZiAoc2hvdWxkSWdub3JlRXZlbnQoZXZlbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJldmVudERlZmF1bHQoZXZlbnQpO1xuICBzZW5kUHJlc3NLZXlNZXNzYWdlKGV2ZW50LCBcImRvd25cIik7XG59KTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXl1cFwiLCAoZXZlbnQpID0+IHtcbiAgaWYgKHNob3VsZElnbm9yZUV2ZW50KGV2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcbiAgc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgXCJ1cFwiKTtcbn0pO1xuXG5mdW5jdGlvbiBzaG91bGRJZ25vcmVFdmVudChldmVudCkge1xuICByZXR1cm4gKFxuICAgIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHxcbiAgICBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpICE9IG51bGxcbiAgKTtcbn1cblxuLy8gV2UgcHJldmVudCB0aGUgZGVmYXVsdCBiZWhhdmlvciBmb3Iga2V5Ym9hcmQgZXZlbnRzLCBvdGhlcndpc2UgdGhlIHdlYiB2aWV3XG4vLyBtaWdodCBzY3JvbGwuXG5mdW5jdGlvbiBwcmV2ZW50RGVmYXVsdChldmVudCkge1xuICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbn1cblxuZnVuY3Rpb24gc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgdHlwZSkge1xuICBpZiAoZXZlbnQucmVwZWF0KSByZXR1cm47XG5cbiAgbGV0IGtleUV2ZW50ID0ge1xuICAgIHR5cGU6IHR5cGUsXG4gICAgY29kZTogZXZlbnQuY29kZSxcbiAgICBjaGFyYWN0ZXJzOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LmtleUNvZGUpLFxuICAgIGFsdDogZXZlbnQuYWx0S2V5LFxuICAgIGNvbnRyb2w6IGV2ZW50LmN0cmxLZXksXG4gICAgc2hpZnQ6IGV2ZW50LnNoaWZ0S2V5LFxuICAgIG1ldGE6IGV2ZW50Lm1ldGFLZXksXG4gIH07XG5cbiAgQW5kcm9pZC5vbktleShKU09OLnN0cmluZ2lmeShrZXlFdmVudCkpO1xufVxuIiwiLyogZXNsaW50LWRpc2FibGUgKi9cbi8vXG4vLyAgaGlnaGxpZ2h0LmpzXG4vLyAgcjItbmF2aWdhdG9yLWtvdGxpblxuLy9cbi8vICBPcmdhbml6ZWQgYnkgVGFlaHl1biBLaW0gb24gNi8yNy8xOSBmcm9tIHIyLW5hdmlnYXRvci1qcy5cbi8vXG4vLyAgQ29weXJpZ2h0IDIwMTkgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2Ugd2hpY2ggaXMgZGV0YWlsZWRcbi8vICBpbiB0aGUgTElDRU5TRSBmaWxlIHByZXNlbnQgaW4gdGhlIHByb2plY3QgcmVwb3NpdG9yeSB3aGVyZSB0aGlzIHNvdXJjZSBjb2RlIGlzIG1haW50YWluZWQuXG4vL1xuXG5jb25zdCBST09UX0NMQVNTX1JFRFVDRV9NT1RJT04gPSBcInIyLXJlZHVjZS1tb3Rpb25cIjtcbmNvbnN0IFJPT1RfQ0xBU1NfTk9fRk9PVE5PVEVTID0gXCJyMi1uby1wb3B1cC1mb29ub3Rlc1wiO1xuY29uc3QgUE9QVVBfRElBTE9HX0NMQVNTID0gXCJyMi1wb3B1cC1kaWFsb2dcIjtcbmNvbnN0IEZPT1ROT1RFU19DT05UQUlORVJfQ0xBU1MgPSBcInIyLWZvb3Rub3RlLWNvbnRhaW5lclwiO1xuY29uc3QgRk9PVE5PVEVTX0NMT1NFX0JVVFRPTl9DTEFTUyA9IFwicjItZm9vdG5vdGUtY2xvc2VcIjtcbmNvbnN0IEZPT1ROT1RFX0ZPUkNFX1NIT1cgPSBcInIyLWZvb3Rub3RlLWZvcmNlLXNob3dcIjtcbmNvbnN0IFRUU19JRF9QUkVWSU9VUyA9IFwicjItdHRzLXByZXZpb3VzXCI7XG5jb25zdCBUVFNfSURfTkVYVCA9IFwicjItdHRzLW5leHRcIjtcbmNvbnN0IFRUU19JRF9TTElERVIgPSBcInIyLXR0cy1zbGlkZXJcIjtcbmNvbnN0IFRUU19JRF9BQ1RJVkVfV09SRCA9IFwicjItdHRzLWFjdGl2ZS13b3JkXCI7XG5jb25zdCBUVFNfSURfQ09OVEFJTkVSID0gXCJyMi10dHMtdHh0XCI7XG5jb25zdCBUVFNfSURfSU5GTyA9IFwicjItdHRzLWluZm9cIjtcbmNvbnN0IFRUU19OQVZfQlVUVE9OX0NMQVNTID0gXCJyMi10dHMtYnV0dG9uXCI7XG5jb25zdCBUVFNfSURfU1BFQUtJTkdfRE9DX0VMRU1FTlQgPSBcInIyLXR0cy1zcGVha2luZy1lbFwiO1xuY29uc3QgVFRTX0NMQVNTX0lOSkVDVEVEX1NQQU4gPSBcInIyLXR0cy1zcGVha2luZy10eHRcIjtcbmNvbnN0IFRUU19DTEFTU19JTkpFQ1RFRF9TVUJTUEFOID0gXCJyMi10dHMtc3BlYWtpbmctd29yZFwiO1xuY29uc3QgVFRTX0lEX0lOSkVDVEVEX1BBUkVOVCA9IFwicjItdHRzLXNwZWFraW5nLXR4dC1wYXJlbnRcIjtcbmNvbnN0IElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSID0gXCJSMl9JRF9ISUdITElHSFRTX0NPTlRBSU5FUlwiO1xuY29uc3QgSURfQU5OT1RBVElPTl9DT05UQUlORVIgPSBcIlIyX0lEX0FOTk9UQVRJT05fQ09OVEFJTkVSXCI7XG5jb25zdCBDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSID0gXCJSMl9DTEFTU19ISUdITElHSFRfQ09OVEFJTkVSXCI7XG5jb25zdCBDTEFTU19BTk5PVEFUSU9OX0NPTlRBSU5FUiA9IFwiUjJfQ0xBU1NfQU5OT1RBVElPTl9DT05UQUlORVJcIjtcbmNvbnN0IENMQVNTX0hJR0hMSUdIVF9BUkVBID0gXCJSMl9DTEFTU19ISUdITElHSFRfQVJFQVwiO1xuY29uc3QgQ0xBU1NfQU5OT1RBVElPTl9BUkVBID0gXCJSMl9DTEFTU19BTk5PVEFUSU9OX0FSRUFcIjtcbmNvbnN0IENMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBID0gXCJSMl9DTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQVwiO1xuY29uc3QgQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBID0gXCJSMl9DTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUFcIjtcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbmNvbnN0IF9ibGFja2xpc3RJZENsYXNzRm9yQ0ZJID0gW1xuICBQT1BVUF9ESUFMT0dfQ0xBU1MsXG4gIFRUU19DTEFTU19JTkpFQ1RFRF9TUEFOLFxuICBUVFNfQ0xBU1NfSU5KRUNURURfU1VCU1BBTixcbiAgSURfSElHSExJR0hUU19DT05UQUlORVIsXG4gIENMQVNTX0hJR0hMSUdIVF9DT05UQUlORVIsXG4gIENMQVNTX0hJR0hMSUdIVF9BUkVBLFxuICBDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQSxcbiAgXCJyZXNpemUtc2Vuc29yXCIsXG5dO1xuY29uc3QgQ0xBU1NfUEFHSU5BVEVEID0gXCJyMi1jc3MtcGFnaW5hdGVkXCI7XG5cbi8vY29uc3QgSVNfREVWID0gKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcImRldmVsb3BtZW50XCIgfHwgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwiZGV2XCIpO1xuY29uc3QgSVNfREVWID0gZmFsc2U7XG5jb25zdCBfaGlnaGxpZ2h0cyA9IFtdO1xuXG5sZXQgX2hpZ2hsaWdodHNDb250YWluZXI7XG5sZXQgX2Fubm90YXRpb25Db250YWluZXI7XG5sZXQgbGFzdE1vdXNlRG93blggPSAtMTtcbmxldCBsYXN0TW91c2VEb3duWSA9IC0xO1xubGV0IGJvZHlFdmVudExpc3RlbmVyc1NldCA9IGZhbHNlO1xuXG5jb25zdCBVU0VfU1ZHID0gZmFsc2U7XG5jb25zdCBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWSA9IDAuMztcbmNvbnN0IEFMVF9CQUNLR1JPVU5EX0NPTE9SX09QQUNJVFkgPSAwLjQ1O1xuXG4vL2NvbnN0IERFQlVHX1ZJU1VBTFMgPSBmYWxzZTtcbmNvbnN0IERFQlVHX1ZJU1VBTFMgPSBmYWxzZTtcbmNvbnN0IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUiA9IHtcbiAgYmx1ZTogMTAwLFxuICBncmVlbjogNTAsXG4gIHJlZDogMjMwLFxufTtcblxuY29uc3QgQU5OT1RBVElPTl9XSURUSCA9IDE1O1xuXG5mdW5jdGlvbiByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUoX3dpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpIHtcbiAgaWYgKFxuICAgIGhpZ2hsaWdodEJvdW5kaW5nLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpID09IENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQVxuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc3R5bGUub3V0bGluZSA9IFwibm9uZVwiO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICBcImJhY2tncm91bmQtY29sb3JcIixcbiAgICBcInRyYW5zcGFyZW50XCIsXG4gICAgXCJpbXBvcnRhbnRcIlxuICApO1xufVxuXG5mdW5jdGlvbiBzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhcywgaGlnaGxpZ2h0KSB7XG4gIGNvbnN0IHVzZVNWRyA9ICFERUJVR19WSVNVQUxTICYmIFVTRV9TVkc7XG4gIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBoaWdobGlnaHRBcmVhcykge1xuICAgIGNvbnN0IGlzU1ZHID0gdXNlU1ZHICYmIGhpZ2hsaWdodEFyZWEubmFtZXNwYWNlVVJJID09PSBTVkdfWE1MX05BTUVTUEFDRTtcbiAgICBjb25zdCBvcGFjaXR5ID0gQUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWTtcbiAgICBpZiAoaXNTVkcpIHtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwiZmlsbFwiLFxuICAgICAgICBgcmdiKCR7aGlnaGxpZ2h0LmNvbG9yLnJlZH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtoaWdobGlnaHQuY29sb3IuYmx1ZX0pYCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwiZmlsbC1vcGFjaXR5XCIsXG4gICAgICAgIGAke29wYWNpdHl9YCxcbiAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwic3Ryb2tlXCIsXG4gICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICBcImltcG9ydGFudFwiXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiLFxuICAgICAgICBgJHtvcGFjaXR5fWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiLFxuICAgICAgICBgcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KWAsXG4gICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSkge1xuICBjb25zdCB1c2VTVkcgPSAhREVCVUdfVklTVUFMUyAmJiBVU0VfU1ZHO1xuICAvL2NvbnN0IHVzZVNWRyA9IFVTRV9TVkc7XG4gIGNvbnN0IGlzU1ZHID0gdXNlU1ZHICYmIGhpZ2hsaWdodEFyZWEubmFtZXNwYWNlVVJJID09PSBTVkdfWE1MX05BTUVTUEFDRTtcbiAgY29uc3QgaWQgPSBpc1NWR1xuICAgID8gaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUucGFyZW50Tm9kZSAmJlxuICAgICAgaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGVcbiAgICAgID8gaGlnaGxpZ2h0QXJlYS5wYXJlbnROb2RlLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKFwiaWRcIilcbiAgICAgIDogdW5kZWZpbmVkXG4gICAgOiBoaWdobGlnaHRBcmVhLnBhcmVudE5vZGUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiZcbiAgICAgIGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGVcbiAgICA/IGhpZ2hsaWdodEFyZWEucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUoXCJpZFwiKVxuICAgIDogdW5kZWZpbmVkO1xuICBpZiAoaWQpIHtcbiAgICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoKSA9PiB7XG4gICAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gICAgfSk7XG4gICAgaWYgKGhpZ2hsaWdodCkge1xuICAgICAgY29uc3Qgb3BhY2l0eSA9IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZO1xuICAgICAgaWYgKGlzU1ZHKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJmaWxsXCIsXG4gICAgICAgICAgYHJnYigke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9KWAsXG4gICAgICAgICAgXCJpbXBvcnRhbnRcIlxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICAgIFwiZmlsbC1vcGFjaXR5XCIsXG4gICAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcInN0cm9rZVwiLFxuICAgICAgICAgIGByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSlgLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgICBcInN0cm9rZS1vcGFjaXR5XCIsXG4gICAgICAgICAgYCR7b3BhY2l0eX1gLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCIsXG4gICAgICAgICAgYHJnYmEoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSwgJHtvcGFjaXR5fSlgLFxuICAgICAgICAgIFwiaW1wb3J0YW50XCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHByb2Nlc3NUb3VjaEV2ZW50KHdpbiwgZXYpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgeCA9IGV2LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFg7XG4gIGNvbnN0IHkgPSBldi5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRZO1xuICBpZiAoIV9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHBhZ2luYXRlZCA9IGlzUGFnaW5hdGVkKGRvY3VtZW50KTtcbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBsZXQgeE9mZnNldDtcbiAgbGV0IHlPZmZzZXQ7XG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBib2R5UmVjdC5sZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHhPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICB5T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IGJvZHlSZWN0LnRvcDtcbiAgfVxuICBsZXQgZm91bmRIaWdobGlnaHQ7XG4gIGxldCBmb3VuZEVsZW1lbnQ7XG4gIGxldCBmb3VuZFJlY3Q7XG4gIC8vICAgIF9oaWdobGlnaHRzLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAvLyAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoYS5zZWxlY3Rpb25JbmZvKSlcbiAgLy8gICAgICAgIHJldHVybiBhLnNlbGVjdGlvbkluZm8uY2xlYW5UZXh0Lmxlbmd0aCA8IGIuc2VsZWN0aW9uSW5mby5jbGVhblRleHQubGVuZ3RoXG4gIC8vICAgIH0pXG4gIGZvciAobGV0IGkgPSBfaGlnaGxpZ2h0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzW2ldO1xuICAgIGxldCBoaWdobGlnaHRQYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgJHtoaWdobGlnaHQuaWR9YCk7XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGhpZ2hsaWdodFBhcmVudCA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYCMke2hpZ2hsaWdodC5pZH1gKTtcbiAgICB9XG4gICAgaWYgKCFoaWdobGlnaHRQYXJlbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBsZXQgaGl0ID0gZmFsc2U7XG4gICAgY29uc3QgaGlnaGxpZ2h0RnJhZ21lbnRzID0gaGlnaGxpZ2h0UGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRGcmFnbWVudCBvZiBoaWdobGlnaHRGcmFnbWVudHMpIHtcbiAgICAgIGNvbnN0IHdpdGhSZWN0ID0gaGlnaGxpZ2h0RnJhZ21lbnQ7XG4gICAgICBjb25zdCBsZWZ0ID0gd2l0aFJlY3QucmVjdC5sZWZ0ICsgeE9mZnNldDtcbiAgICAgIGNvbnN0IHRvcCA9IHdpdGhSZWN0LnJlY3QudG9wICsgeU9mZnNldDtcbiAgICAgIGZvdW5kUmVjdCA9IHdpdGhSZWN0LnJlY3Q7XG4gICAgICBpZiAoXG4gICAgICAgIHggPj0gbGVmdCAmJlxuICAgICAgICB4IDwgbGVmdCArIHdpdGhSZWN0LnJlY3Qud2lkdGggJiZcbiAgICAgICAgeSA+PSB0b3AgJiZcbiAgICAgICAgeSA8IHRvcCArIHdpdGhSZWN0LnJlY3QuaGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgaGl0ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChoaXQpIHtcbiAgICAgIGZvdW5kSGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgZm91bmRFbGVtZW50ID0gaGlnaGxpZ2h0UGFyZW50O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmICghZm91bmRIaWdobGlnaHQgfHwgIWZvdW5kRWxlbWVudCkge1xuICAgIGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5ncyA9IF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICk7XG4gICAgZm9yIChjb25zdCBoaWdobGlnaHRCb3VuZGluZyBvZiBoaWdobGlnaHRCb3VuZGluZ3MpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICB9XG4gICAgY29uc3QgYWxsSGlnaGxpZ2h0QXJlYXMgPSBBcnJheS5mcm9tKFxuICAgICAgX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YClcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBhbGxIaWdobGlnaHRBcmVhcykge1xuICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGZvdW5kRWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNsaWNrXCIpKSB7XG4gICAgaWYgKGV2LnR5cGUgPT09IFwibW91c2Vtb3ZlXCIpIHtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgICAgZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0QXJlYXMgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0QXJlYSBvZiBhbGxIaWdobGlnaHRBcmVhcykge1xuICAgICAgICBpZiAoZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMuaW5kZXhPZihoaWdobGlnaHRBcmVhKSA8IDApIHtcbiAgICAgICAgICByZXNldEhpZ2hsaWdodEFyZWFTdHlsZSh3aW4sIGhpZ2hsaWdodEFyZWEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcywgZm91bmRIaWdobGlnaHQpO1xuICAgICAgY29uc3QgZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcgPSBmb3VuZEVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBjb25zdCBhbGxIaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBgLiR7Q0xBU1NfSElHSExJR0hUX0JPVU5ESU5HX0FSRUF9YFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcgfHxcbiAgICAgICAgICBoaWdobGlnaHRCb3VuZGluZyAhPT0gZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmdcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKHdpbiwgaGlnaGxpZ2h0Qm91bmRpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcpIHtcbiAgICAgICAgaWYgKERFQlVHX1ZJU1VBTFMpIHtcbiAgICAgICAgICBzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlKFxuICAgICAgICAgICAgd2luLFxuICAgICAgICAgICAgZm91bmRFbGVtZW50SGlnaGxpZ2h0Qm91bmRpbmcsXG4gICAgICAgICAgICBmb3VuZEhpZ2hsaWdodFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2LnR5cGUgPT09IFwidG91Y2hzdGFydFwiIHx8IGV2LnR5cGUgPT09IFwidG91Y2hlbmRcIikge1xuICAgICAgY29uc3Qgc2l6ZSA9IHtcbiAgICAgICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgICAgICBzY3JlZW5IZWlnaHQ6IHdpbmRvdy5vdXRlckhlaWdodCxcbiAgICAgICAgbGVmdDogZm91bmRSZWN0LmxlZnQsXG4gICAgICAgIHdpZHRoOiBmb3VuZFJlY3Qud2lkdGgsXG4gICAgICAgIHRvcDogZm91bmRSZWN0LnRvcCxcbiAgICAgICAgaGVpZ2h0OiBmb3VuZFJlY3QuaGVpZ2h0LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGhpZ2hsaWdodDogZm91bmRIaWdobGlnaHQuaWQsXG4gICAgICAgIHNpemU6IHNpemUsXG4gICAgICB9O1xuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgdHlwZW9mIHdpbmRvdy5wcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHdpbmRvdy5wcm9jZXNzLnR5cGUgPT09IFwicmVuZGVyZXJcIlxuICAgICAgKSB7XG4gICAgICAgIGVsZWN0cm9uXzEuaXBjUmVuZGVyZXIuc2VuZFRvSG9zdChSMl9FVkVOVF9ISUdITElHSFRfQ0xJQ0ssIHBheWxvYWQpO1xuICAgICAgfSBlbHNlIGlmICh3aW5kb3cud2Via2l0VVJMKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGZvdW5kSGlnaGxpZ2h0LmlkLmluY2x1ZGVzKFwiUjJfQU5OT1RBVElPTl9cIikpO1xuICAgICAgICBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfQU5OT1RBVElPTl9cIikgPj0gMCkge1xuICAgICAgICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgICAgICAgICBBbmRyb2lkLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0LmlkXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChmb3VuZEhpZ2hsaWdodC5pZC5zZWFyY2goXCJSMl9ISUdITElHSFRfXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBY3RpdmF0ZWQoZm91bmRIaWdobGlnaHQuaWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgICAgICAgICAgd2Via2l0Lm1lc3NhZ2VIYW5kbGVycy5oaWdobGlnaHRBY3RpdmF0ZWQucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICAgIGZvdW5kSGlnaGxpZ2h0LmlkXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NNb3VzZUV2ZW50KHdpbiwgZXYpIHtcbiAgY29uc3QgZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgeCA9IGV2LmNsaWVudFg7XG4gIGNvbnN0IHkgPSBldi5jbGllbnRZO1xuICBpZiAoIV9oaWdobGlnaHRzQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBib2R5UmVjdCA9IGRvY3VtZW50LmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGxldCB4T2Zmc2V0O1xuICBsZXQgeU9mZnNldDtcbiAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gLXNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCA6IGJvZHlSZWN0LmxlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCA6IGJvZHlSZWN0LnRvcDtcbiAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiAtc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICB9XG4gIGxldCBmb3VuZEhpZ2hsaWdodDtcbiAgbGV0IGZvdW5kRWxlbWVudDtcbiAgbGV0IGZvdW5kUmVjdDtcbiAgZm9yIChsZXQgaSA9IF9oaWdobGlnaHRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHNbaV07XG4gICAgbGV0IGhpZ2hsaWdodFBhcmVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGAke2hpZ2hsaWdodC5pZH1gKTtcbiAgICBpZiAoIWhpZ2hsaWdodFBhcmVudCkge1xuICAgICAgaGlnaGxpZ2h0UGFyZW50ID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvcihgIyR7aGlnaGxpZ2h0LmlkfWApO1xuICAgIH1cbiAgICBpZiAoIWhpZ2hsaWdodFBhcmVudCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGxldCBoaXQgPSBmYWxzZTtcbiAgICBjb25zdCBoaWdobGlnaHRGcmFnbWVudHMgPSBoaWdobGlnaHRQYXJlbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEZyYWdtZW50IG9mIGhpZ2hsaWdodEZyYWdtZW50cykge1xuICAgICAgY29uc3Qgd2l0aFJlY3QgPSBoaWdobGlnaHRGcmFnbWVudDtcbiAgICAgIGNvbnN0IGxlZnQgPSB3aXRoUmVjdC5yZWN0LmxlZnQgKyB4T2Zmc2V0O1xuICAgICAgY29uc3QgdG9wID0gd2l0aFJlY3QucmVjdC50b3AgKyB5T2Zmc2V0O1xuICAgICAgZm91bmRSZWN0ID0gd2l0aFJlY3QucmVjdDtcbiAgICAgIGlmIChcbiAgICAgICAgeCA+PSBsZWZ0ICYmXG4gICAgICAgIHggPCBsZWZ0ICsgd2l0aFJlY3QucmVjdC53aWR0aCAmJlxuICAgICAgICB5ID49IHRvcCAmJlxuICAgICAgICB5IDwgdG9wICsgd2l0aFJlY3QucmVjdC5oZWlnaHRcbiAgICAgICkge1xuICAgICAgICBoaXQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGhpdCkge1xuICAgICAgZm91bmRIaWdobGlnaHQgPSBoaWdobGlnaHQ7XG4gICAgICBmb3VuZEVsZW1lbnQgPSBoaWdobGlnaHRQYXJlbnQ7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoIWZvdW5kSGlnaGxpZ2h0IHx8ICFmb3VuZEVsZW1lbnQpIHtcbiAgICBjb25zdCBoaWdobGlnaHRCb3VuZGluZ3MgPSBfaGlnaGxpZ2h0c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICApO1xuICAgIGZvciAoY29uc3QgaGlnaGxpZ2h0Qm91bmRpbmcgb2YgaGlnaGxpZ2h0Qm91bmRpbmdzKSB7XG4gICAgICByZXNldEhpZ2hsaWdodEJvdW5kaW5nU3R5bGUod2luLCBoaWdobGlnaHRCb3VuZGluZyk7XG4gICAgfVxuICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gQXJyYXkuZnJvbShcbiAgICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWApXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgIHJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgaGlnaGxpZ2h0QXJlYSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmb3VuZEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jbGlja1wiKSkge1xuICAgIGlmIChldi50eXBlID09PSBcIm1vdXNlbW92ZVwiKSB7XG4gICAgICBjb25zdCBmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyA9IEFycmF5LmZyb20oXG4gICAgICAgIGZvdW5kRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19ISUdITElHSFRfQVJFQX1gKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFsbEhpZ2hsaWdodEFyZWFzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEFyZWEgb2YgYWxsSGlnaGxpZ2h0QXJlYXMpIHtcbiAgICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEFyZWFzLmluZGV4T2YoaGlnaGxpZ2h0QXJlYSkgPCAwKSB7XG4gICAgICAgICAgcmVzZXRIaWdobGlnaHRBcmVhU3R5bGUod2luLCBoaWdobGlnaHRBcmVhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2V0SGlnaGxpZ2h0QXJlYVN0eWxlKHdpbiwgZm91bmRFbGVtZW50SGlnaGxpZ2h0QXJlYXMsIGZvdW5kSGlnaGxpZ2h0KTtcbiAgICAgIGNvbnN0IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nID0gZm91bmRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgIGAuJHtDTEFTU19ISUdITElHSFRfQk9VTkRJTkdfQVJFQX1gXG4gICAgICApO1xuICAgICAgY29uc3QgYWxsSGlnaGxpZ2h0Qm91bmRpbmdzID0gX2hpZ2hsaWdodHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgYC4ke0NMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBfWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nIG9mIGFsbEhpZ2hsaWdodEJvdW5kaW5ncykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIHx8XG4gICAgICAgICAgaGlnaGxpZ2h0Qm91bmRpbmcgIT09IGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nXG4gICAgICAgICkge1xuICAgICAgICAgIHJlc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSh3aW4sIGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nKSB7XG4gICAgICAgIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgICAgICAgc2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZShcbiAgICAgICAgICAgIHdpbixcbiAgICAgICAgICAgIGZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nLFxuICAgICAgICAgICAgZm91bmRIaWdobGlnaHRcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChldi50eXBlID09PSBcIm1vdXNldXBcIiB8fCBldi50eXBlID09PSBcInRvdWNoZW5kXCIpIHtcbiAgICAgIGNvbnN0IHRvdWNoZWRQb3NpdGlvbiA9IHtcbiAgICAgICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgICAgICBzY3JlZW5IZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICAgICAgbGVmdDogZm91bmRSZWN0LmxlZnQsXG4gICAgICAgIHdpZHRoOiBmb3VuZFJlY3Qud2lkdGgsXG4gICAgICAgIHRvcDogZm91bmRSZWN0LnRvcCxcbiAgICAgICAgaGVpZ2h0OiBmb3VuZFJlY3QuaGVpZ2h0LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgaGlnaGxpZ2h0OiBmb3VuZEhpZ2hsaWdodCxcbiAgICAgICAgcG9zaXRpb246IHRvdWNoZWRQb3NpdGlvbixcbiAgICAgIH07XG5cbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICB0eXBlb2Ygd2luZG93LnByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgd2luZG93LnByb2Nlc3MudHlwZSA9PT0gXCJyZW5kZXJlclwiXG4gICAgICApIHtcbiAgICAgICAgZWxlY3Ryb25fMS5pcGNSZW5kZXJlci5zZW5kVG9Ib3N0KFIyX0VWRU5UX0hJR0hMSUdIVF9DTElDSywgcGF5bG9hZCk7XG4gICAgICB9IGVsc2UgaWYgKHdpbmRvdy53ZWJraXRVUkwpIHtcbiAgICAgICAgaWYgKGZvdW5kSGlnaGxpZ2h0LmlkLnNlYXJjaChcIlIyX0FOTk9UQVRJT05fXCIpID49IDApIHtcbiAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgICAgICAgICAgQW5kcm9pZC5oaWdobGlnaHRBbm5vdGF0aW9uTWFya0FjdGl2YXRlZChmb3VuZEhpZ2hsaWdodC5pZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmV8aVBhZHxpUG9kL2kpKSB7XG4gICAgICAgICAgICB3ZWJraXQubWVzc2FnZUhhbmRsZXJzLmhpZ2hsaWdodEFubm90YXRpb25NYXJrQWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZm91bmRIaWdobGlnaHQuaWQuc2VhcmNoKFwiUjJfSElHSExJR0hUX1wiKSA+PSAwKSB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSkpIHtcbiAgICAgICAgICAgIEFuZHJvaWQuaGlnaGxpZ2h0QWN0aXZhdGVkKGZvdW5kSGlnaGxpZ2h0LmlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICAgICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuaGlnaGxpZ2h0QWN0aXZhdGVkLnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAgICBmb3VuZEhpZ2hsaWdodC5pZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIChcbiAgICAocmVjdDEubGVmdCA8IHJlY3QyLnJpZ2h0IHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi5sZWZ0IDwgcmVjdDEucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi5sZWZ0LCByZWN0MS5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QxLnRvcCA8IHJlY3QyLmJvdHRvbSB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDIudG9wIDwgcmVjdDEuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDIudG9wLCByZWN0MS5ib3R0b20sIHRvbGVyYW5jZSkpKVxuICApO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKHJlY3RzKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCByZWN0cy5sZW5ndGg7IGorKykge1xuICAgICAgY29uc3QgcmVjdDEgPSByZWN0c1tpXTtcbiAgICAgIGNvbnN0IHJlY3QyID0gcmVjdHNbal07XG4gICAgICBpZiAocmVjdDEgPT09IHJlY3QyKSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcInJlcGxhY2VPdmVybGFwaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0c1RvdWNoT3JPdmVybGFwKHJlY3QxLCByZWN0MiwgLTEpKSB7XG4gICAgICAgIGxldCB0b0FkZCA9IFtdO1xuICAgICAgICBsZXQgdG9SZW1vdmU7XG4gICAgICAgIGxldCB0b1ByZXNlcnZlO1xuICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMSA9IHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpO1xuICAgICAgICBpZiAoc3VidHJhY3RSZWN0czEubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgdG9BZGQgPSBzdWJ0cmFjdFJlY3RzMTtcbiAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgIHRvUHJlc2VydmUgPSByZWN0MjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMiA9IHJlY3RTdWJ0cmFjdChyZWN0MiwgcmVjdDEpO1xuICAgICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPCBzdWJ0cmFjdFJlY3RzMi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgICAgdG9QcmVzZXJ2ZSA9IHJlY3QyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMyO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MjtcbiAgICAgICAgICAgIHRvUHJlc2VydmUgPSByZWN0MTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnN0IHRvQ2hlY2sgPSBbXTtcbiAgICAgICAgICB0b0NoZWNrLnB1c2godG9QcmVzZXJ2ZSk7XG4gICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkodG9DaGVjaywgdG9BZGQpO1xuICAgICAgICAgIGNoZWNrT3ZlcmxhcHModG9DaGVjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYENMSUVOVCBSRUNUOiBvdmVybGFwLCBjdXQgb25lIHJlY3QgaW50byAke3RvQWRkLmxlbmd0aH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSB0b1JlbW92ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KG5ld1JlY3RzLCB0b0FkZCk7XG4gICAgICAgIHJldHVybiByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5ld1JlY3RzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiBjaGVja092ZXJsYXBzKHJlY3RzKSB7XG4gIGNvbnN0IHN0aWxsT3ZlcmxhcGluZ1JlY3RzID0gW107XG4gIGZvciAoY29uc3QgcmVjdDEgb2YgcmVjdHMpIHtcbiAgICBmb3IgKGNvbnN0IHJlY3QyIG9mIHJlY3RzKSB7XG4gICAgICBpZiAocmVjdDEgPT09IHJlY3QyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgaGFzMSA9IHN0aWxsT3ZlcmxhcGluZ1JlY3RzLmluZGV4T2YocmVjdDEpID49IDA7XG4gICAgICBjb25zdCBoYXMyID0gc3RpbGxPdmVybGFwaW5nUmVjdHMuaW5kZXhPZihyZWN0MikgPj0gMDtcbiAgICAgIGlmICghaGFzMSB8fCAhaGFzMikge1xuICAgICAgICBpZiAocmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIC0xKSkge1xuICAgICAgICAgIGlmICghaGFzMSkge1xuICAgICAgICAgICAgc3RpbGxPdmVybGFwaW5nUmVjdHMucHVzaChyZWN0MSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghaGFzMikge1xuICAgICAgICAgICAgc3RpbGxPdmVybGFwaW5nUmVjdHMucHVzaChyZWN0Mik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IG92ZXJsYXAgLS0tXCIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYCMxIFRPUDoke3JlY3QxLnRvcH0gQk9UVE9NOiR7cmVjdDEuYm90dG9tfSBMRUZUOiR7cmVjdDEubGVmdH0gUklHSFQ6JHtyZWN0MS5yaWdodH0gV0lEVEg6JHtyZWN0MS53aWR0aH0gSEVJR0hUOiR7cmVjdDEuaGVpZ2h0fWBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYCMyIFRPUDoke3JlY3QyLnRvcH0gQk9UVE9NOiR7cmVjdDIuYm90dG9tfSBMRUZUOiR7cmVjdDIubGVmdH0gUklHSFQ6JHtyZWN0Mi5yaWdodH0gV0lEVEg6JHtyZWN0Mi53aWR0aH0gSEVJR0hUOiR7cmVjdDIuaGVpZ2h0fWBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHhPdmVybGFwID0gZ2V0UmVjdE92ZXJsYXBYKHJlY3QxLCByZWN0Mik7XG4gICAgICAgICAgY29uc29sZS5sb2coYHhPdmVybGFwOiAke3hPdmVybGFwfWApO1xuICAgICAgICAgIGNvbnN0IHlPdmVybGFwID0gZ2V0UmVjdE92ZXJsYXBZKHJlY3QxLCByZWN0Mik7XG4gICAgICAgICAgY29uc29sZS5sb2coYHlPdmVybGFwOiAke3lPdmVybGFwfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChzdGlsbE92ZXJsYXBpbmdSZWN0cy5sZW5ndGgpIHtcbiAgICBjb25zb2xlLmxvZyhgQ0xJRU5UIFJFQ1Q6IG92ZXJsYXBzICR7c3RpbGxPdmVybGFwaW5nUmVjdHMubGVuZ3RofWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNvbnRhaW5lZFJlY3RzKHJlY3RzLCB0b2xlcmFuY2UpIHtcbiAgY29uc3QgcmVjdHNUb0tlZXAgPSBuZXcgU2V0KHJlY3RzKTtcbiAgZm9yIChjb25zdCByZWN0IG9mIHJlY3RzKSB7XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCA+IDEgJiYgcmVjdC5oZWlnaHQgPiAxO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiQ0xJRU5UIFJFQ1Q6IHJlbW92ZSB0aW55XCIpO1xuICAgICAgfVxuICAgICAgcmVjdHNUb0tlZXAuZGVsZXRlKHJlY3QpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcG9zc2libHlDb250YWluaW5nUmVjdCBvZiByZWN0cykge1xuICAgICAgaWYgKHJlY3QgPT09IHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIXJlY3RzVG9LZWVwLmhhcyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWN0Q29udGFpbnMocG9zc2libHlDb250YWluaW5nUmVjdCwgcmVjdCwgdG9sZXJhbmNlKSkge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIGNvbnRhaW5lZFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gQXJyYXkuZnJvbShyZWN0c1RvS2VlcCk7XG59XG5cbmZ1bmN0aW9uIGFsbW9zdEVxdWFsKGEsIGIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gTWF0aC5hYnMoYSAtIGIpIDw9IHRvbGVyYW5jZTtcbn1cblxuZnVuY3Rpb24gcmVjdEludGVyc2VjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbWF4TGVmdCA9IE1hdGgubWF4KHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCBtaW5SaWdodCA9IE1hdGgubWluKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IG1heFRvcCA9IE1hdGgubWF4KHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgbWluQm90dG9tID0gTWF0aC5taW4ocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICBjb25zdCByZWN0ID0ge1xuICAgIGJvdHRvbTogbWluQm90dG9tLFxuICAgIGhlaWdodDogTWF0aC5tYXgoMCwgbWluQm90dG9tIC0gbWF4VG9wKSxcbiAgICBsZWZ0OiBtYXhMZWZ0LFxuICAgIHJpZ2h0OiBtaW5SaWdodCxcbiAgICB0b3A6IG1heFRvcCxcbiAgICB3aWR0aDogTWF0aC5tYXgoMCwgbWluUmlnaHQgLSBtYXhMZWZ0KSxcbiAgfTtcbiAgcmV0dXJuIHJlY3Q7XG59XG5cbmZ1bmN0aW9uIHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgcmVjdEludGVyc2VjdGVkID0gcmVjdEludGVyc2VjdChyZWN0MiwgcmVjdDEpO1xuICBpZiAocmVjdEludGVyc2VjdGVkLmhlaWdodCA9PT0gMCB8fCByZWN0SW50ZXJzZWN0ZWQud2lkdGggPT09IDApIHtcbiAgICByZXR1cm4gW3JlY3QxXTtcbiAgfVxuICBjb25zdCByZWN0cyA9IFtdO1xuICB7XG4gICAgY29uc3QgcmVjdEEgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3QxLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEEud2lkdGggPSByZWN0QS5yaWdodCAtIHJlY3RBLmxlZnQ7XG4gICAgcmVjdEEuaGVpZ2h0ID0gcmVjdEEuYm90dG9tIC0gcmVjdEEudG9wO1xuICAgIGlmIChyZWN0QS5oZWlnaHQgIT09IDAgJiYgcmVjdEEud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEEpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEIgPSB7XG4gICAgICBib3R0b206IHJlY3RJbnRlcnNlY3RlZC50b3AsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEIud2lkdGggPSByZWN0Qi5yaWdodCAtIHJlY3RCLmxlZnQ7XG4gICAgcmVjdEIuaGVpZ2h0ID0gcmVjdEIuYm90dG9tIC0gcmVjdEIudG9wO1xuICAgIGlmIChyZWN0Qi5oZWlnaHQgIT09IDAgJiYgcmVjdEIud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEIpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEMgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdEludGVyc2VjdGVkLmJvdHRvbSxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEMud2lkdGggPSByZWN0Qy5yaWdodCAtIHJlY3RDLmxlZnQ7XG4gICAgcmVjdEMuaGVpZ2h0ID0gcmVjdEMuYm90dG9tIC0gcmVjdEMudG9wO1xuICAgIGlmIChyZWN0Qy5oZWlnaHQgIT09IDAgJiYgcmVjdEMud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEMpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEQgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHJpZ2h0OiByZWN0MS5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0RC53aWR0aCA9IHJlY3RELnJpZ2h0IC0gcmVjdEQubGVmdDtcbiAgICByZWN0RC5oZWlnaHQgPSByZWN0RC5ib3R0b20gLSByZWN0RC50b3A7XG4gICAgaWYgKHJlY3RELmhlaWdodCAhPT0gMCAmJiByZWN0RC53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0RCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gcmVjdENvbnRhaW5zUG9pbnQocmVjdCwgeCwgeSwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QubGVmdCA8IHggfHwgYWxtb3N0RXF1YWwocmVjdC5sZWZ0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnJpZ2h0ID4geCB8fCBhbG1vc3RFcXVhbChyZWN0LnJpZ2h0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnRvcCA8IHkgfHwgYWxtb3N0RXF1YWwocmVjdC50b3AsIHksIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QuYm90dG9tID4geSB8fCBhbG1vc3RFcXVhbChyZWN0LmJvdHRvbSwgeSwgdG9sZXJhbmNlKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVjdENvbnRhaW5zKHJlY3QxLCByZWN0MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLmxlZnQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5yaWdodCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgcmVjdENvbnRhaW5zUG9pbnQocmVjdDEsIHJlY3QyLmxlZnQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5yaWdodCwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbGVmdCA9IE1hdGgubWluKHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCByaWdodCA9IE1hdGgubWF4KHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IHRvcCA9IE1hdGgubWluKHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgYm90dG9tID0gTWF0aC5tYXgocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbSxcbiAgICBoZWlnaHQ6IGJvdHRvbSAtIHRvcCxcbiAgICBsZWZ0LFxuICAgIHJpZ2h0LFxuICAgIHRvcCxcbiAgICB3aWR0aDogcmlnaHQgLSBsZWZ0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gIHJlY3RzLFxuICB0b2xlcmFuY2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJtZXJnZVRvdWNoaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwVmVydGljYWxseSA9XG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLnRvcCwgcmVjdDIudG9wLCB0b2xlcmFuY2UpICYmXG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tLCB0b2xlcmFuY2UpO1xuICAgICAgY29uc3QgcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0LCB0b2xlcmFuY2UpICYmXG4gICAgICAgIGFsbW9zdEVxdWFsKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IGhvcml6b250YWxBbGxvd2VkID0gIWRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHM7XG4gICAgICBjb25zdCBhbGlnbmVkID1cbiAgICAgICAgKHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ICYmIGhvcml6b250YWxBbGxvd2VkKSB8fFxuICAgICAgICAocmVjdHNMaW5lVXBWZXJ0aWNhbGx5ICYmICFyZWN0c0xpbmVVcEhvcml6b250YWxseSk7XG4gICAgICBjb25zdCBjYW5NZXJnZSA9IGFsaWduZWQgJiYgcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSk7XG4gICAgICBpZiAoY2FuTWVyZ2UpIHtcbiAgICAgICAgaWYgKElTX0RFVikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYENMSUVOVCBSRUNUOiBtZXJnaW5nIHR3byBpbnRvIG9uZSwgVkVSVElDQUw6ICR7cmVjdHNMaW5lVXBWZXJ0aWNhbGx5fSBIT1JJWk9OVEFMOiAke3JlY3RzTGluZVVwSG9yaXpvbnRhbGx5fSAoJHtkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzfSlgXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdSZWN0cyA9IHJlY3RzLmZpbHRlcigocmVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWN0ICE9PSByZWN0MSAmJiByZWN0ICE9PSByZWN0MjtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcGxhY2VtZW50Q2xpZW50UmVjdCA9IGdldEJvdW5kaW5nUmVjdChyZWN0MSwgcmVjdDIpO1xuICAgICAgICBuZXdSZWN0cy5wdXNoKHJlcGxhY2VtZW50Q2xpZW50UmVjdCk7XG4gICAgICAgIHJldHVybiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gICAgICAgICAgbmV3UmVjdHMsXG4gICAgICAgICAgdG9sZXJhbmNlLFxuICAgICAgICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlY3RzO1xufVxuXG5mdW5jdGlvbiBnZXRDbGllbnRSZWN0c05vT3ZlcmxhcChyYW5nZSwgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cykge1xuICBjb25zdCByYW5nZUNsaWVudFJlY3RzID0gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgcmV0dXJuIGdldENsaWVudFJlY3RzTm9PdmVybGFwXyhcbiAgICByYW5nZUNsaWVudFJlY3RzLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXBfKFxuICBjbGllbnRSZWN0cyxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGNvbnN0IHRvbGVyYW5jZSA9IDE7XG4gIGNvbnN0IG9yaWdpbmFsUmVjdHMgPSBbXTtcbiAgZm9yIChjb25zdCByYW5nZUNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBvcmlnaW5hbFJlY3RzLnB1c2goe1xuICAgICAgYm90dG9tOiByYW5nZUNsaWVudFJlY3QuYm90dG9tLFxuICAgICAgaGVpZ2h0OiByYW5nZUNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgbGVmdDogcmFuZ2VDbGllbnRSZWN0LmxlZnQsXG4gICAgICByaWdodDogcmFuZ2VDbGllbnRSZWN0LnJpZ2h0LFxuICAgICAgdG9wOiByYW5nZUNsaWVudFJlY3QudG9wLFxuICAgICAgd2lkdGg6IHJhbmdlQ2xpZW50UmVjdC53aWR0aCxcbiAgICB9KTtcbiAgfVxuICBjb25zdCBtZXJnZWRSZWN0cyA9IG1lcmdlVG91Y2hpbmdSZWN0cyhcbiAgICBvcmlnaW5hbFJlY3RzLFxuICAgIHRvbGVyYW5jZSxcbiAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICk7XG4gIGNvbnN0IG5vQ29udGFpbmVkUmVjdHMgPSByZW1vdmVDb250YWluZWRSZWN0cyhtZXJnZWRSZWN0cywgdG9sZXJhbmNlKTtcbiAgY29uc3QgbmV3UmVjdHMgPSByZXBsYWNlT3ZlcmxhcGluZ1JlY3RzKG5vQ29udGFpbmVkUmVjdHMpO1xuICBjb25zdCBtaW5BcmVhID0gMiAqIDI7XG4gIGZvciAobGV0IGogPSBuZXdSZWN0cy5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgIGNvbnN0IHJlY3QgPSBuZXdSZWN0c1tqXTtcbiAgICBjb25zdCBiaWdFbm91Z2ggPSByZWN0LndpZHRoICogcmVjdC5oZWlnaHQgPiBtaW5BcmVhO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBpZiAobmV3UmVjdHMubGVuZ3RoID4gMSkge1xuICAgICAgICBpZiAoSVNfREVWKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHNtYWxsXCIpO1xuICAgICAgICB9XG4gICAgICAgIG5ld1JlY3RzLnNwbGljZShqLCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChJU19ERVYpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGwsIGJ1dCBrZWVwIG90aGVyd2lzZSBlbXB0eSFcIik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChJU19ERVYpIHtcbiAgICBjaGVja092ZXJsYXBzKG5ld1JlY3RzKTtcbiAgfVxuICBpZiAoSVNfREVWKSB7XG4gICAgY29uc29sZS5sb2coXG4gICAgICBgQ0xJRU5UIFJFQ1Q6IHJlZHVjZWQgJHtvcmlnaW5hbFJlY3RzLmxlbmd0aH0gLS0+ICR7bmV3UmVjdHMubGVuZ3RofWBcbiAgICApO1xuICB9XG4gIHJldHVybiBuZXdSZWN0cztcbn1cblxuZnVuY3Rpb24gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpIHtcbiAgcmV0dXJuIChcbiAgICBkb2N1bWVudCAmJlxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJlxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfUEFHSU5BVEVEKVxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KSB7XG4gIGlmIChkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50KSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQ7XG4gIH1cbiAgcmV0dXJuIGRvY3VtZW50LmJvZHk7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUNvbnRhaW5lcih3aW4sIGFubm90YXRpb25GbGFnKSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuXG4gIGlmICghX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICBpZiAoIWJvZHlFdmVudExpc3RlbmVyc1NldCkge1xuICAgICAgYm9keUV2ZW50TGlzdGVuZXJzU2V0ID0gdHJ1ZTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJtb3VzZWRvd25cIixcbiAgICAgICAgKGV2KSA9PiB7XG4gICAgICAgICAgbGFzdE1vdXNlRG93blggPSBldi5jbGllbnRYO1xuICAgICAgICAgIGxhc3RNb3VzZURvd25ZID0gZXYuY2xpZW50WTtcbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwibW91c2V1cFwiLFxuICAgICAgICAoZXYpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBNYXRoLmFicyhsYXN0TW91c2VEb3duWCAtIGV2LmNsaWVudFgpIDwgMyAmJlxuICAgICAgICAgICAgTWF0aC5hYnMobGFzdE1vdXNlRG93blkgLSBldi5jbGllbnRZKSA8IDNcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHByb2Nlc3NNb3VzZUV2ZW50KHdpbiwgZXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIFwibW91c2Vtb3ZlXCIsXG4gICAgICAgIChldikgPT4ge1xuICAgICAgICAgIHByb2Nlc3NNb3VzZUV2ZW50KHdpbiwgZXYpO1xuICAgICAgICB9LFxuICAgICAgICBmYWxzZVxuICAgICAgKTtcblxuICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBcInRvdWNoZW5kXCIsXG4gICAgICAgIGZ1bmN0aW9uIHRvdWNoRW5kKGUpIHtcbiAgICAgICAgICBwcm9jZXNzVG91Y2hFdmVudCh3aW4sIGUpO1xuICAgICAgICB9LFxuICAgICAgICBmYWxzZVxuICAgICAgKTtcbiAgICB9XG4gICAgX2hpZ2hsaWdodHNDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSKTtcblxuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKF9oaWdobGlnaHRzQ29udGFpbmVyKTtcbiAgfVxuXG4gIHJldHVybiBfaGlnaGxpZ2h0c0NvbnRhaW5lcjtcbn1cblxuZnVuY3Rpb24gaGlkZUFsbGhpZ2hsaWdodHMoKSB7XG4gIGlmIChfaGlnaGxpZ2h0c0NvbnRhaW5lcikge1xuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyLnJlbW92ZSgpO1xuICAgIF9oaWdobGlnaHRzQ29udGFpbmVyID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZXN0cm95QWxsaGlnaGxpZ2h0cygpIHtcbiAgaGlkZUFsbGhpZ2hsaWdodHMoKTtcbiAgX2hpZ2hsaWdodHMuc3BsaWNlKDAsIF9oaWdobGlnaHRzLmxlbmd0aCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXN0cm95SGlnaGxpZ2h0KGlkKSB7XG4gIGxldCBpID0gLTE7XG4gIGxldCBfZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IF9oaWdobGlnaHRzLmZpbmQoKGgsIGopID0+IHtcbiAgICBpID0gajtcbiAgICByZXR1cm4gaC5pZCA9PT0gaWQ7XG4gIH0pO1xuICBpZiAoaGlnaGxpZ2h0ICYmIGkgPj0gMCAmJiBpIDwgX2hpZ2hsaWdodHMubGVuZ3RoKSB7XG4gICAgX2hpZ2hsaWdodHMuc3BsaWNlKGksIDEpO1xuICB9XG4gIGNvbnN0IGhpZ2hsaWdodENvbnRhaW5lciA9IF9kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gIGlmIChoaWdobGlnaHRDb250YWluZXIpIHtcbiAgICBoaWdobGlnaHRDb250YWluZXIucmVtb3ZlKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDZmlUZXh0Tm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KGVsZW1lbnQsIGNoaWxkKSB7XG4gIGxldCBmb3VuZCA9IC0xO1xuICBsZXQgdGV4dE5vZGVJbmRleCA9IC0xO1xuICBsZXQgcHJldmlvdXNXYXNFbGVtZW50ID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGROb2RlID0gZWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuICAgIGNvbnN0IGlzVGV4dCA9IGlzQ2ZpVGV4dE5vZGUoY2hpbGROb2RlKTtcbiAgICBpZiAoaXNUZXh0IHx8IHByZXZpb3VzV2FzRWxlbWVudCkge1xuICAgICAgdGV4dE5vZGVJbmRleCArPSAyO1xuICAgIH1cbiAgICBpZiAoaXNUZXh0KSB7XG4gICAgICBpZiAoY2hpbGROb2RlID09PSBjaGlsZCkge1xuICAgICAgICBmb3VuZCA9IHRleHROb2RlSW5kZXg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBwcmV2aW91c1dhc0VsZW1lbnQgPSBjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFO1xuICB9XG4gIHJldHVybiBmb3VuZDtcbn1cblxuZnVuY3Rpb24gZ2V0Q29tbW9uQW5jZXN0b3JFbGVtZW50KG5vZGUxLCBub2RlMikge1xuICBpZiAobm9kZTEubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIG5vZGUxID09PSBub2RlMikge1xuICAgIHJldHVybiBub2RlMTtcbiAgfVxuICBpZiAobm9kZTEubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIG5vZGUxLmNvbnRhaW5zKG5vZGUyKSkge1xuICAgIHJldHVybiBub2RlMTtcbiAgfVxuICBpZiAobm9kZTIubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIG5vZGUyLmNvbnRhaW5zKG5vZGUxKSkge1xuICAgIHJldHVybiBub2RlMjtcbiAgfVxuICBjb25zdCBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluID0gW107XG4gIGxldCBwYXJlbnQgPSBub2RlMS5wYXJlbnROb2RlO1xuICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICBub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluLnB1c2gocGFyZW50KTtcbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgfVxuICBjb25zdCBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluID0gW107XG4gIHBhcmVudCA9IG5vZGUyLnBhcmVudE5vZGU7XG4gIHdoaWxlIChwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIG5vZGUyRWxlbWVudEFuY2VzdG9yQ2hhaW4ucHVzaChwYXJlbnQpO1xuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xuICB9XG4gIGxldCBjb21tb25BbmNlc3RvciA9IG5vZGUxRWxlbWVudEFuY2VzdG9yQ2hhaW4uZmluZChcbiAgICAobm9kZTFFbGVtZW50QW5jZXN0b3IpID0+IHtcbiAgICAgIHJldHVybiBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluLmluZGV4T2Yobm9kZTFFbGVtZW50QW5jZXN0b3IpID49IDA7XG4gICAgfVxuICApO1xuICBpZiAoIWNvbW1vbkFuY2VzdG9yKSB7XG4gICAgY29tbW9uQW5jZXN0b3IgPSBub2RlMkVsZW1lbnRBbmNlc3RvckNoYWluLmZpbmQoKG5vZGUyRWxlbWVudEFuY2VzdG9yKSA9PiB7XG4gICAgICByZXR1cm4gbm9kZTFFbGVtZW50QW5jZXN0b3JDaGFpbi5pbmRleE9mKG5vZGUyRWxlbWVudEFuY2VzdG9yKSA+PSAwO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBjb21tb25BbmNlc3Rvcjtcbn1cblxuZnVuY3Rpb24gZnVsbFF1YWxpZmllZFNlbGVjdG9yKG5vZGUpIHtcbiAgaWYgKG5vZGUubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgY29uc3QgbG93ZXJDYXNlTmFtZSA9XG4gICAgICAobm9kZS5sb2NhbE5hbWUgJiYgbm9kZS5sb2NhbE5hbWUudG9Mb3dlckNhc2UoKSkgfHxcbiAgICAgIG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICByZXR1cm4gbG93ZXJDYXNlTmFtZTtcbiAgfVxuICAvL3JldHVybiBjc3NQYXRoKG5vZGUsIGp1c3RTZWxlY3Rvcik7XG4gIHJldHVybiBjc3NQYXRoKG5vZGUsIHRydWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8oKSB7XG4gIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBTRUxFQ1RJT04gQ09MTEFQU0VELlwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJhd1RleHQgPSBzZWxlY3Rpb24udG9TdHJpbmcoKTtcbiAgY29uc3QgY2xlYW5UZXh0ID0gcmF3VGV4dC50cmltKCkucmVwbGFjZSgvXFxuL2csIFwiIFwiKS5yZXBsYWNlKC9cXHNcXHMrL2csIFwiIFwiKTtcbiAgaWYgKGNsZWFuVGV4dC5sZW5ndGggPT09IDApIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBTRUxFQ1RJT04gVEVYVCBFTVBUWS5cIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoIXNlbGVjdGlvbi5hbmNob3JOb2RlIHx8ICFzZWxlY3Rpb24uZm9jdXNOb2RlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYW5nZSA9XG4gICAgc2VsZWN0aW9uLnJhbmdlQ291bnQgPT09IDFcbiAgICAgID8gc2VsZWN0aW9uLmdldFJhbmdlQXQoMClcbiAgICAgIDogY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNPZmZzZXRcbiAgICAgICAgKTtcbiAgaWYgKCFyYW5nZSB8fCByYW5nZS5jb2xsYXBzZWQpIHtcbiAgICBjb25zb2xlLmxvZyhcIiQkJCQkJCQkJCQkJCQkJCQkIENBTk5PVCBHRVQgTk9OLUNPTExBUFNFRCBTRUxFQ1RJT04gUkFOR0U/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJhbmdlSW5mbyA9IGNvbnZlcnRSYW5nZShyYW5nZSwgZnVsbFF1YWxpZmllZFNlbGVjdG9yLCBjb21wdXRlQ0ZJKTtcbiAgaWYgKCFyYW5nZUluZm8pIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBTRUxFQ1RJT04gUkFOR0UgSU5GTyBGQUlMPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmIChJU19ERVYgJiYgREVCVUdfVklTVUFMUykge1xuICAgIGNvbnN0IHJlc3RvcmVkUmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKHdpbi5kb2N1bWVudCwgcmFuZ2VJbmZvKTtcbiAgICBpZiAocmVzdG9yZWRSYW5nZSkge1xuICAgICAgaWYgKFxuICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0T2Zmc2V0ID09PSByYW5nZS5zdGFydE9mZnNldCAmJlxuICAgICAgICByZXN0b3JlZFJhbmdlLmVuZE9mZnNldCA9PT0gcmFuZ2UuZW5kT2Zmc2V0ICYmXG4gICAgICAgIHJlc3RvcmVkUmFuZ2Uuc3RhcnRDb250YWluZXIgPT09IHJhbmdlLnN0YXJ0Q29udGFpbmVyICYmXG4gICAgICAgIHJlc3RvcmVkUmFuZ2UuZW5kQ29udGFpbmVyID09PSByYW5nZS5lbmRDb250YWluZXJcbiAgICAgICkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIlNFTEVDVElPTiBSQU5HRSBSRVNUT1JFRCBPS0FZIChkZXYgY2hlY2spLlwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiU0VMRUNUSU9OIFJBTkdFIFJFU1RPUkUgRkFJTCAoZGV2IGNoZWNrKS5cIik7XG4gICAgICAgIGR1bXBEZWJ1ZyhcbiAgICAgICAgICBcIlNFTEVDVElPTlwiLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNPZmZzZXQsXG4gICAgICAgICAgZ2V0Q3NzU2VsZWN0b3JcbiAgICAgICAgKTtcbiAgICAgICAgZHVtcERlYnVnKFxuICAgICAgICAgIFwiT1JERVJFRCBSQU5HRSBGUk9NIFNFTEVDVElPTlwiLFxuICAgICAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgICAgIHJhbmdlLmVuZENvbnRhaW5lcixcbiAgICAgICAgICByYW5nZS5lbmRPZmZzZXQsXG4gICAgICAgICAgZ2V0Q3NzU2VsZWN0b3JcbiAgICAgICAgKTtcbiAgICAgICAgZHVtcERlYnVnKFxuICAgICAgICAgIFwiUkVTVE9SRUQgUkFOR0VcIixcbiAgICAgICAgICByZXN0b3JlZFJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgICAgIHJlc3RvcmVkUmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRDb250YWluZXIsXG4gICAgICAgICAgcmVzdG9yZWRSYW5nZS5lbmRPZmZzZXQsXG4gICAgICAgICAgZ2V0Q3NzU2VsZWN0b3JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5sb2coXCJDQU5OT1QgUkVTVE9SRSBTRUxFQ1RJT04gUkFOR0UgPz8hXCIpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbG9jYXRpb25zOiByYW5nZUluZm8yTG9jYXRpb24ocmFuZ2VJbmZvKSxcbiAgICB0ZXh0OiB7XG4gICAgICBoaWdobGlnaHQ6IHJhd1RleHQsXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2hlY2tCbGFja2xpc3RlZChlbCkge1xuICBsZXQgYmxhY2tsaXN0ZWRJZDtcbiAgY29uc3QgaWQgPSBlbC5nZXRBdHRyaWJ1dGUoXCJpZFwiKTtcbiAgaWYgKGlkICYmIF9ibGFja2xpc3RJZENsYXNzRm9yQ0ZJLmluZGV4T2YoaWQpID49IDApIHtcbiAgICBjb25zb2xlLmxvZyhcImNoZWNrQmxhY2tsaXN0ZWQgSUQ6IFwiICsgaWQpO1xuICAgIGJsYWNrbGlzdGVkSWQgPSBpZDtcbiAgfVxuICBsZXQgYmxhY2tsaXN0ZWRDbGFzcztcbiAgZm9yIChjb25zdCBpdGVtIG9mIF9ibGFja2xpc3RJZENsYXNzRm9yQ0ZJKSB7XG4gICAgaWYgKGVsLmNsYXNzTGlzdC5jb250YWlucyhpdGVtKSkge1xuICAgICAgY29uc29sZS5sb2coXCJjaGVja0JsYWNrbGlzdGVkIENMQVNTOiBcIiArIGl0ZW0pO1xuICAgICAgYmxhY2tsaXN0ZWRDbGFzcyA9IGl0ZW07XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKGJsYWNrbGlzdGVkSWQgfHwgYmxhY2tsaXN0ZWRDbGFzcykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjc3NQYXRoKG5vZGUsIG9wdGltaXplZCkge1xuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gXCJcIjtcbiAgfVxuXG4gIGNvbnN0IHN0ZXBzID0gW107XG4gIGxldCBjb250ZXh0Tm9kZSA9IG5vZGU7XG4gIHdoaWxlIChjb250ZXh0Tm9kZSkge1xuICAgIGNvbnN0IHN0ZXAgPSBfY3NzUGF0aFN0ZXAoY29udGV4dE5vZGUsICEhb3B0aW1pemVkLCBjb250ZXh0Tm9kZSA9PT0gbm9kZSk7XG4gICAgaWYgKCFzdGVwKSB7XG4gICAgICBicmVhazsgLy8gRXJyb3IgLSBiYWlsIG91dCBlYXJseS5cbiAgICB9XG4gICAgc3RlcHMucHVzaChzdGVwLnZhbHVlKTtcbiAgICBpZiAoc3RlcC5vcHRpbWl6ZWQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb250ZXh0Tm9kZSA9IGNvbnRleHROb2RlLnBhcmVudE5vZGU7XG4gIH1cbiAgc3RlcHMucmV2ZXJzZSgpO1xuICByZXR1cm4gc3RlcHMuam9pbihcIiA+IFwiKTtcbn1cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbi8vIGh0dHBzOi8vY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9ibGluay8rL21hc3Rlci9Tb3VyY2UvZGV2dG9vbHMvZnJvbnRfZW5kL2NvbXBvbmVudHMvRE9NUHJlc2VudGF0aW9uVXRpbHMuanMjMzE2XG5mdW5jdGlvbiBfY3NzUGF0aFN0ZXAobm9kZSwgb3B0aW1pemVkLCBpc1RhcmdldE5vZGUpIHtcbiAgZnVuY3Rpb24gcHJlZml4ZWRFbGVtZW50Q2xhc3NOYW1lcyhuZCkge1xuICAgIGNvbnN0IGNsYXNzQXR0cmlidXRlID0gbmQuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIik7XG4gICAgaWYgKCFjbGFzc0F0dHJpYnV0ZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBjbGFzc0F0dHJpYnV0ZVxuICAgICAgLnNwbGl0KC9cXHMrL2cpXG4gICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAubWFwKChubSkgPT4ge1xuICAgICAgICAvLyBUaGUgcHJlZml4IGlzIHJlcXVpcmVkIHRvIHN0b3JlIFwiX19wcm90b19fXCIgaW4gYSBvYmplY3QtYmFzZWQgbWFwLlxuICAgICAgICByZXR1cm4gXCIkXCIgKyBubTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaWRTZWxlY3RvcihpZGQpIHtcbiAgICByZXR1cm4gXCIjXCIgKyBlc2NhcGVJZGVudGlmaWVySWZOZWVkZWQoaWRkKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVzY2FwZUlkZW50aWZpZXJJZk5lZWRlZChpZGVudCkge1xuICAgIGlmIChpc0NTU0lkZW50aWZpZXIoaWRlbnQpKSB7XG4gICAgICByZXR1cm4gaWRlbnQ7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hvdWxkRXNjYXBlRmlyc3QgPSAvXig/OlswLTldfC1bMC05LV0/KS8udGVzdChpZGVudCk7XG4gICAgY29uc3QgbGFzdEluZGV4ID0gaWRlbnQubGVuZ3RoIC0gMTtcbiAgICByZXR1cm4gaWRlbnQucmVwbGFjZSgvLi9nLCBmdW5jdGlvbiAoYywgaWkpIHtcbiAgICAgIHJldHVybiAoc2hvdWxkRXNjYXBlRmlyc3QgJiYgaWkgPT09IDApIHx8ICFpc0NTU0lkZW50Q2hhcihjKVxuICAgICAgICA/IGVzY2FwZUFzY2lpQ2hhcihjLCBpaSA9PT0gbGFzdEluZGV4KVxuICAgICAgICA6IGM7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBlc2NhcGVBc2NpaUNoYXIoYywgaXNMYXN0KSB7XG4gICAgcmV0dXJuIFwiXFxcXFwiICsgdG9IZXhCeXRlKGMpICsgKGlzTGFzdCA/IFwiXCIgOiBcIiBcIik7XG4gIH1cblxuICBmdW5jdGlvbiB0b0hleEJ5dGUoYykge1xuICAgIGxldCBoZXhCeXRlID0gYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KTtcbiAgICBpZiAoaGV4Qnl0ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgIGhleEJ5dGUgPSBcIjBcIiArIGhleEJ5dGU7XG4gICAgfVxuICAgIHJldHVybiBoZXhCeXRlO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNDU1NJZGVudENoYXIoYykge1xuICAgIGlmICgvW2EtekEtWjAtOV8tXS8udGVzdChjKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBjLmNoYXJDb2RlQXQoMCkgPj0gMHhhMDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQ1NTSWRlbnRpZmllcih2YWx1ZSkge1xuICAgIHJldHVybiAvXi0/W2EtekEtWl9dW2EtekEtWjAtOV8tXSokLy50ZXN0KHZhbHVlKTtcbiAgfVxuXG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgbG93ZXJDYXNlTmFtZSA9XG4gICAgKG5vZGUubG9jYWxOYW1lICYmIG5vZGUubG9jYWxOYW1lLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gIGNvbnN0IGVsZW1lbnQgPSBub2RlO1xuXG4gIGNvbnN0IGlkID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJpZFwiKTtcblxuICBpZiAob3B0aW1pemVkKSB7XG4gICAgaWYgKGlkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcHRpbWl6ZWQ6IHRydWUsXG4gICAgICAgIHZhbHVlOiBpZFNlbGVjdG9yKGlkKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGxvd2VyQ2FzZU5hbWUgPT09IFwiYm9keVwiIHx8XG4gICAgICBsb3dlckNhc2VOYW1lID09PSBcImhlYWRcIiB8fFxuICAgICAgbG93ZXJDYXNlTmFtZSA9PT0gXCJodG1sXCJcbiAgICApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGxvd2VyQ2FzZU5hbWUsIC8vIG5vZGUubm9kZU5hbWVJbkNvcnJlY3RDYXNlKCksXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5vZGVOYW1lID0gbG93ZXJDYXNlTmFtZTsgLy8gbm9kZS5ub2RlTmFtZUluQ29ycmVjdENhc2UoKTtcbiAgaWYgKGlkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wdGltaXplZDogdHJ1ZSxcbiAgICAgIHZhbHVlOiBub2RlTmFtZSArIGlkU2VsZWN0b3IoaWQpLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XG5cbiAgaWYgKCFwYXJlbnQgfHwgcGFyZW50Lm5vZGVUeXBlID09PSBOb2RlLkRPQ1VNRU5UX05PREUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgb3B0aW1pemVkOiB0cnVlLFxuICAgICAgdmFsdWU6IG5vZGVOYW1lLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheV8gPSBwcmVmaXhlZEVsZW1lbnRDbGFzc05hbWVzKGVsZW1lbnQpO1xuXG4gIGNvbnN0IHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5ID0gW107IC8vIC5rZXlTZXQoKVxuICBwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheV8uZm9yRWFjaCgoYXJySXRlbSkgPT4ge1xuICAgIGlmIChwcmVmaXhlZE93bkNsYXNzTmFtZXNBcnJheS5pbmRleE9mKGFyckl0ZW0pIDwgMCkge1xuICAgICAgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkucHVzaChhcnJJdGVtKTtcbiAgICB9XG4gIH0pO1xuXG4gIGxldCBuZWVkc0NsYXNzTmFtZXMgPSBmYWxzZTtcbiAgbGV0IG5lZWRzTnRoQ2hpbGQgPSBmYWxzZTtcbiAgbGV0IG93bkluZGV4ID0gLTE7XG4gIGxldCBlbGVtZW50SW5kZXggPSAtMTtcbiAgY29uc3Qgc2libGluZ3MgPSBwYXJlbnQuY2hpbGRyZW47XG5cbiAgZm9yIChcbiAgICBsZXQgaSA9IDA7XG4gICAgKG93bkluZGV4ID09PSAtMSB8fCAhbmVlZHNOdGhDaGlsZCkgJiYgaSA8IHNpYmxpbmdzLmxlbmd0aDtcbiAgICArK2lcbiAgKSB7XG4gICAgY29uc3Qgc2libGluZyA9IHNpYmxpbmdzW2ldO1xuICAgIGlmIChzaWJsaW5nLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGVsZW1lbnRJbmRleCArPSAxO1xuICAgIGlmIChzaWJsaW5nID09PSBub2RlKSB7XG4gICAgICBvd25JbmRleCA9IGVsZW1lbnRJbmRleDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAobmVlZHNOdGhDaGlsZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gc2libGluZy5ub2RlTmFtZUluQ29ycmVjdENhc2UoKVxuICAgIGNvbnN0IHNpYmxpbmdOYW1lID1cbiAgICAgIChzaWJsaW5nLmxvY2FsTmFtZSAmJiBzaWJsaW5nLmxvY2FsTmFtZS50b0xvd2VyQ2FzZSgpKSB8fFxuICAgICAgc2libGluZy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChzaWJsaW5nTmFtZSAhPT0gbm9kZU5hbWUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBuZWVkc0NsYXNzTmFtZXMgPSB0cnVlO1xuXG4gICAgY29uc3Qgb3duQ2xhc3NOYW1lcyA9IFtdO1xuICAgIHByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5LmZvckVhY2goKGFyckl0ZW0pID0+IHtcbiAgICAgIG93bkNsYXNzTmFtZXMucHVzaChhcnJJdGVtKTtcbiAgICB9KTtcbiAgICBsZXQgb3duQ2xhc3NOYW1lQ291bnQgPSBvd25DbGFzc05hbWVzLmxlbmd0aDtcblxuICAgIGlmIChvd25DbGFzc05hbWVDb3VudCA9PT0gMCkge1xuICAgICAgbmVlZHNOdGhDaGlsZCA9IHRydWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3Qgc2libGluZ0NsYXNzTmFtZXNBcnJheV8gPSBwcmVmaXhlZEVsZW1lbnRDbGFzc05hbWVzKHNpYmxpbmcpO1xuICAgIGNvbnN0IHNpYmxpbmdDbGFzc05hbWVzQXJyYXkgPSBbXTsgLy8gLmtleVNldCgpXG4gICAgc2libGluZ0NsYXNzTmFtZXNBcnJheV8uZm9yRWFjaCgoYXJySXRlbSkgPT4ge1xuICAgICAgaWYgKHNpYmxpbmdDbGFzc05hbWVzQXJyYXkuaW5kZXhPZihhcnJJdGVtKSA8IDApIHtcbiAgICAgICAgc2libGluZ0NsYXNzTmFtZXNBcnJheS5wdXNoKGFyckl0ZW0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCBzaWJsaW5nQ2xhc3Mgb2Ygc2libGluZ0NsYXNzTmFtZXNBcnJheSkge1xuICAgICAgY29uc3QgaW5kID0gb3duQ2xhc3NOYW1lcy5pbmRleE9mKHNpYmxpbmdDbGFzcyk7XG4gICAgICBpZiAoaW5kIDwgMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgb3duQ2xhc3NOYW1lcy5zcGxpY2UoaW5kLCAxKTsgLy8gZGVsZXRlIG93bkNsYXNzTmFtZXNbc2libGluZ0NsYXNzXTtcblxuICAgICAgaWYgKCEtLW93bkNsYXNzTmFtZUNvdW50KSB7XG4gICAgICAgIG5lZWRzTnRoQ2hpbGQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgcmVzdWx0ID0gbm9kZU5hbWU7XG4gIGlmIChcbiAgICBpc1RhcmdldE5vZGUgJiZcbiAgICBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmXG4gICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpICYmXG4gICAgIWVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaWRcIikgJiZcbiAgICAhZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKVxuICApIHtcbiAgICByZXN1bHQgKz0gJ1t0eXBlPVwiJyArIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwidHlwZVwiKSArICdcIl0nO1xuICB9XG4gIGlmIChuZWVkc050aENoaWxkKSB7XG4gICAgcmVzdWx0ICs9IFwiOm50aC1jaGlsZChcIiArIChvd25JbmRleCArIDEpICsgXCIpXCI7XG4gIH0gZWxzZSBpZiAobmVlZHNDbGFzc05hbWVzKSB7XG4gICAgZm9yIChjb25zdCBwcmVmaXhlZE5hbWUgb2YgcHJlZml4ZWRPd25DbGFzc05hbWVzQXJyYXkpIHtcbiAgICAgIHJlc3VsdCArPSBcIi5cIiArIGVzY2FwZUlkZW50aWZpZXJJZk5lZWRlZChwcmVmaXhlZE5hbWUuc3Vic3RyKDEpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG9wdGltaXplZDogZmFsc2UsXG4gICAgdmFsdWU6IHJlc3VsdCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZUNGSShub2RlKSB7XG4gIC8vIFRPRE86IGhhbmRsZSBjaGFyYWN0ZXIgcG9zaXRpb24gaW5zaWRlIHRleHQgbm9kZVxuICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgbGV0IGNmaSA9IFwiXCI7XG5cbiAgbGV0IGN1cnJlbnRFbGVtZW50ID0gbm9kZTtcbiAgd2hpbGUgKFxuICAgIGN1cnJlbnRFbGVtZW50LnBhcmVudE5vZGUgJiZcbiAgICBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICApIHtcbiAgICBjb25zdCBibGFja2xpc3RlZCA9IGNoZWNrQmxhY2tsaXN0ZWQoY3VycmVudEVsZW1lbnQpO1xuICAgIGlmICghYmxhY2tsaXN0ZWQpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW4gPSBjdXJyZW50RWxlbWVudC5wYXJlbnROb2RlLmNoaWxkcmVuO1xuICAgICAgbGV0IGN1cnJlbnRFbGVtZW50SW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY3VycmVudEVsZW1lbnRQYXJlbnRDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoY3VycmVudEVsZW1lbnQgPT09IGN1cnJlbnRFbGVtZW50UGFyZW50Q2hpbGRyZW5baV0pIHtcbiAgICAgICAgICBjdXJyZW50RWxlbWVudEluZGV4ID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRFbGVtZW50SW5kZXggPj0gMCkge1xuICAgICAgICBjb25zdCBjZmlJbmRleCA9IChjdXJyZW50RWxlbWVudEluZGV4ICsgMSkgKiAyO1xuICAgICAgICBjZmkgPVxuICAgICAgICAgIGNmaUluZGV4ICtcbiAgICAgICAgICAoY3VycmVudEVsZW1lbnQuaWQgPyBcIltcIiArIGN1cnJlbnRFbGVtZW50LmlkICsgXCJdXCIgOiBcIlwiKSArXG4gICAgICAgICAgKGNmaS5sZW5ndGggPyBcIi9cIiArIGNmaSA6IFwiXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICBjdXJyZW50RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50LnBhcmVudE5vZGU7XG4gIH1cblxuICByZXR1cm4gXCIvXCIgKyBjZmk7XG59XG5cbmZ1bmN0aW9uIF9jcmVhdGVIaWdobGlnaHQobG9jYXRpb25zLCBjb2xvciwgcG9pbnRlckludGVyYWN0aW9uLCB0eXBlKSB7XG4gIGNvbnN0IHJhbmdlSW5mbyA9IGxvY2F0aW9uMlJhbmdlSW5mbyhsb2NhdGlvbnMpO1xuICBjb25zdCB1bmlxdWVTdHIgPSBgJHtyYW5nZUluZm8uY2ZpfSR7cmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yfSR7cmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4fSR7cmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0fSR7cmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcn0ke3JhbmdlSW5mby5lbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXh9JHtyYW5nZUluZm8uZW5kT2Zmc2V0fWA7XG5cbiAgY29uc3QgaGFzaCA9IHJlcXVpcmUoXCJoYXNoLmpzXCIpO1xuICBjb25zdCBzaGEyNTZIZXggPSBoYXNoLnNoYTI1NigpLnVwZGF0ZSh1bmlxdWVTdHIpLmRpZ2VzdChcImhleFwiKTtcblxuICB2YXIgaWQ7XG4gIGlmICh0eXBlID09IElEX0hJR0hMSUdIVFNfQ09OVEFJTkVSKSB7XG4gICAgaWQgPSBcIlIyX0hJR0hMSUdIVF9cIiArIHNoYTI1NkhleDtcbiAgfSBlbHNlIHtcbiAgICBpZCA9IFwiUjJfQU5OT1RBVElPTl9cIiArIHNoYTI1NkhleDtcbiAgfVxuXG4gIGRlc3Ryb3lIaWdobGlnaHQoaWQpO1xuXG4gIGNvbnN0IGhpZ2hsaWdodCA9IHtcbiAgICBjb2xvcjogY29sb3IgPyBjb2xvciA6IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUixcbiAgICBpZCxcbiAgICBwb2ludGVySW50ZXJhY3Rpb24sXG4gICAgcmFuZ2VJbmZvLFxuICB9O1xuICBfaGlnaGxpZ2h0cy5wdXNoKGhpZ2hsaWdodCk7XG4gIGNyZWF0ZUhpZ2hsaWdodERvbShcbiAgICB3aW5kb3csXG4gICAgaGlnaGxpZ2h0LFxuICAgIHR5cGUgPT0gSURfQU5OT1RBVElPTl9DT05UQUlORVIgPyB0cnVlIDogZmFsc2VcbiAgKTtcblxuICByZXR1cm4gaGlnaGxpZ2h0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSGlnaGxpZ2h0KHNlbGVjdGlvbkluZm8sIGNvbG9yLCBwb2ludGVySW50ZXJhY3Rpb24pIHtcbiAgcmV0dXJuIF9jcmVhdGVIaWdobGlnaHQoXG4gICAgc2VsZWN0aW9uSW5mbyxcbiAgICBjb2xvcixcbiAgICBwb2ludGVySW50ZXJhY3Rpb24sXG4gICAgSURfSElHSExJR0hUU19DT05UQUlORVJcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFubm90YXRpb24oaWQpIHtcbiAgbGV0IGkgPSAtMTtcblxuICBjb25zdCBoaWdobGlnaHQgPSBfaGlnaGxpZ2h0cy5maW5kKChoLCBqKSA9PiB7XG4gICAgaSA9IGo7XG4gICAgcmV0dXJuIGguaWQgPT09IGlkO1xuICB9KTtcbiAgaWYgKGkgPT0gX2hpZ2hsaWdodHMubGVuZ3RoKSByZXR1cm47XG5cbiAgdmFyIGxvY2F0aW9ucyA9IHtcbiAgICBsb2NhdGlvbnM6IHJhbmdlSW5mbzJMb2NhdGlvbihoaWdobGlnaHQucmFuZ2VJbmZvKSxcbiAgfTtcblxuICByZXR1cm4gX2NyZWF0ZUhpZ2hsaWdodChcbiAgICBsb2NhdGlvbnMsXG4gICAgaGlnaGxpZ2h0LmNvbG9yLFxuICAgIHRydWUsXG4gICAgSURfQU5OT1RBVElPTl9DT05UQUlORVJcbiAgKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSGlnaGxpZ2h0RG9tKHdpbiwgaGlnaGxpZ2h0LCBhbm5vdGF0aW9uRmxhZykge1xuICBjb25zdCBkb2N1bWVudCA9IHdpbi5kb2N1bWVudDtcblxuICBjb25zdCBzY2FsZSA9XG4gICAgMSAvXG4gICAgKHdpbi5SRUFESVVNMiAmJiB3aW4uUkVBRElVTTIuaXNGaXhlZExheW91dFxuICAgICAgPyB3aW4uUkVBRElVTTIuZnhsVmlld3BvcnRTY2FsZVxuICAgICAgOiAxKTtcblxuICBjb25zdCBzY3JvbGxFbGVtZW50ID0gZ2V0U2Nyb2xsaW5nRWxlbWVudChkb2N1bWVudCk7XG5cbiAgY29uc3QgcmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCBoaWdobGlnaHQucmFuZ2VJbmZvKTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBwYWdpbmF0ZWQgPSBpc1BhZ2luYXRlZChkb2N1bWVudCk7XG4gIGNvbnN0IGhpZ2hsaWdodHNDb250YWluZXIgPSBlbnN1cmVDb250YWluZXIod2luLCBhbm5vdGF0aW9uRmxhZyk7XG4gIGNvbnN0IGhpZ2hsaWdodFBhcmVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgaGlnaGxpZ2h0UGFyZW50LnNldEF0dHJpYnV0ZShcImlkXCIsIGhpZ2hsaWdodC5pZCk7XG4gIGhpZ2hsaWdodFBhcmVudC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSKTtcblxuICBkb2N1bWVudC5ib2R5LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuICBoaWdobGlnaHRQYXJlbnQuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gIGlmIChoaWdobGlnaHQucG9pbnRlckludGVyYWN0aW9uKSB7XG4gICAgaGlnaGxpZ2h0UGFyZW50LnNldEF0dHJpYnV0ZShcImRhdGEtY2xpY2tcIiwgXCIxXCIpO1xuICB9XG5cbiAgY29uc3QgYm9keVJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBjb25zdCB1c2VTVkcgPSAhREVCVUdfVklTVUFMUyAmJiBVU0VfU1ZHO1xuICAvL2NvbnN0IHVzZVNWRyA9IFVTRV9TVkc7XG4gIGNvbnN0IGRyYXdVbmRlcmxpbmUgPSBmYWxzZTtcbiAgY29uc3QgZHJhd1N0cmlrZVRocm91Z2ggPSBmYWxzZTtcbiAgY29uc3QgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cyA9IGRyYXdVbmRlcmxpbmUgfHwgZHJhd1N0cmlrZVRocm91Z2g7XG4gIC8vY29uc3QgY2xpZW50UmVjdHMgPSBERUJVR19WSVNVQUxTID8gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKSA6XG4gIGNvbnN0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgcmFuZ2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICBsZXQgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWc7XG4gIGNvbnN0IHJvdW5kZWRDb3JuZXIgPSAzO1xuICBjb25zdCB1bmRlcmxpbmVUaGlja25lc3MgPSAyO1xuICBjb25zdCBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyA9IDM7XG4gIGNvbnN0IG9wYWNpdHkgPSBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWTtcbiAgbGV0IGV4dHJhID0gXCJcIjtcbiAgY29uc3QgcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0ID1cbiAgICBmcmFtZUZvckhpZ2hsaWdodEFubm90YXRpb25NYXJrV2l0aElEKHdpbiwgaGlnaGxpZ2h0LmlkKTtcblxuICBsZXQgeE9mZnNldDtcbiAgbGV0IHlPZmZzZXQ7XG4gIGxldCBhbm5vdGF0aW9uT2Zmc2V0O1xuXG4gIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpKSB7XG4gICAgeE9mZnNldCA9IHBhZ2luYXRlZCA/IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQgOiBib2R5UmVjdC5sZWZ0O1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gICAgYW5ub3RhdGlvbk9mZnNldCA9XG4gICAgICBwYXJzZUludChcbiAgICAgICAgKHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5yaWdodCAtIHhPZmZzZXQpIC8gd2luZG93LmlubmVyV2lkdGhcbiAgICAgICkgKyAxO1xuICB9IGVsc2UgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvaSkpIHtcbiAgICB4T2Zmc2V0ID0gcGFnaW5hdGVkID8gMCA6IC1zY3JvbGxFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgeU9mZnNldCA9IHBhZ2luYXRlZCA/IDAgOiBib2R5UmVjdC50b3A7XG4gICAgYW5ub3RhdGlvbk9mZnNldCA9IHBhcnNlSW50KFxuICAgICAgcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnJpZ2h0IC8gd2luZG93LmlubmVyV2lkdGggKyAxXG4gICAgKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgY2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIGlmICh1c2VTVkcpIHtcbiAgICAgIGNvbnN0IGJvcmRlclRoaWNrbmVzcyA9IDA7XG4gICAgICBpZiAoIWhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnKSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgfVxuICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWR1JlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgIFNWR19YTUxfTkFNRVNQQUNFLFxuICAgICAgICBcInJlY3RcIlxuICAgICAgKTtcblxuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgIGBmaWxsOiByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke2hpZ2hsaWdodC5jb2xvci5ibHVlfSkgIWltcG9ydGFudDsgZmlsbC1vcGFjaXR5OiAke29wYWNpdHl9ICFpbXBvcnRhbnQ7IHN0cm9rZS13aWR0aDogMDtgXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2NhbGUgPSBzY2FsZTtcblxuICAgICAgLypcbiAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0ID0ge1xuICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICovXG5cbiAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QgPSB7XG4gICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJyeFwiLCBgJHtyb3VuZGVkQ29ybmVyICogc2NhbGV9YCk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJyeVwiLCBgJHtyb3VuZGVkQ29ybmVyICogc2NhbGV9YCk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwieFwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC5sZWZ0IC0gYm9yZGVyVGhpY2tuZXNzKSAqIHNjYWxlfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwieVwiLFxuICAgICAgICBgJHsoaGlnaGxpZ2h0QXJlYVNWR1JlY3QucmVjdC50b3AgLSBib3JkZXJUaGlja25lc3MpICogc2NhbGV9YFxuICAgICAgKTtcbiAgICAgIGhpZ2hsaWdodEFyZWFTVkdSZWN0LnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJoZWlnaHRcIixcbiAgICAgICAgYCR7KGhpZ2hsaWdodEFyZWFTVkdSZWN0LnJlY3QuaGVpZ2h0ICsgYm9yZGVyVGhpY2tuZXNzICogMikgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFxuICAgICAgICBcIndpZHRoXCIsXG4gICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHUmVjdC5yZWN0LndpZHRoICsgYm9yZGVyVGhpY2tuZXNzICogMikgKiBzY2FsZX1gXG4gICAgICApO1xuICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0QXJlYVNWR1JlY3QpO1xuICAgICAgaWYgKGRyYXdVbmRlcmxpbmUpIHtcbiAgICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWR0xpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgU1ZHX1hNTF9OQU1FU1BBQ0UsXG4gICAgICAgICAgXCJsaW5lXCJcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR1JlY3Quc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgQ0xBU1NfSElHSExJR0hUX0FSRUEpO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJzdHlsZVwiLFxuICAgICAgICAgIGBzdHJva2UtbGluZWNhcDogcm91bmQ7IHN0cm9rZS13aWR0aDogJHtcbiAgICAgICAgICAgIHVuZGVybGluZVRoaWNrbmVzcyAqIHNjYWxlXG4gICAgICAgICAgfTsgc3Ryb2tlOiByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke1xuICAgICAgICAgICAgaGlnaGxpZ2h0LmNvbG9yLmJsdWVcbiAgICAgICAgICB9KSAhaW1wb3J0YW50OyBzdHJva2Utb3BhY2l0eTogJHtvcGFjaXR5fSAhaW1wb3J0YW50YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zY2FsZSA9IHNjYWxlO1xuICAgICAgICAvKlxuICAgICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsaW5lT2Zmc2V0ID1cbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoID4gcm91bmRlZENvcm5lciA/IHJvdW5kZWRDb3JuZXIgOiAwO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJ4MVwiLFxuICAgICAgICAgIGAkeyhoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmxlZnQgKyBsaW5lT2Zmc2V0KSAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDJcIixcbiAgICAgICAgICBgJHtcbiAgICAgICAgICAgIChoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmxlZnQgK1xuICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoIC1cbiAgICAgICAgICAgICAgbGluZU9mZnNldCkgKlxuICAgICAgICAgICAgc2NhbGVcbiAgICAgICAgICB9YFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB5ID1cbiAgICAgICAgICAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC50b3AgK1xuICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgLVxuICAgICAgICAgICAgdW5kZXJsaW5lVGhpY2tuZXNzIC8gMikgKlxuICAgICAgICAgIHNjYWxlO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXCJ5MVwiLCBgJHt5fWApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXCJ5MlwiLCBgJHt5fWApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgXCJoZWlnaHRcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmhlaWdodCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwid2lkdGhcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LndpZHRoICogc2NhbGV9YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZy5hcHBlbmRDaGlsZChoaWdobGlnaHRBcmVhU1ZHTGluZSk7XG4gICAgICB9XG4gICAgICBpZiAoZHJhd1N0cmlrZVRocm91Z2gpIHtcbiAgICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWR0xpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgU1ZHX1hNTF9OQU1FU1BBQ0UsXG4gICAgICAgICAgXCJsaW5lXCJcbiAgICAgICAgKTtcblxuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHUmVjdC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgICAgYHN0cm9rZS1saW5lY2FwOiBidXR0OyBzdHJva2Utd2lkdGg6ICR7XG4gICAgICAgICAgICBzdHJpa2VUaHJvdWdoTGluZVRoaWNrbmVzcyAqIHNjYWxlXG4gICAgICAgICAgfTsgc3Ryb2tlOiByZ2IoJHtoaWdobGlnaHQuY29sb3IucmVkfSwgJHtoaWdobGlnaHQuY29sb3IuZ3JlZW59LCAke1xuICAgICAgICAgICAgaGlnaGxpZ2h0LmNvbG9yLmJsdWVcbiAgICAgICAgICB9KSAhaW1wb3J0YW50OyBzdHJva2Utb3BhY2l0eTogJHtvcGFjaXR5fSAhaW1wb3J0YW50YFxuICAgICAgICApO1xuICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5zY2FsZSA9IHNjYWxlO1xuXG4gICAgICAgIC8qXG4gICAgICAgICAgICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgKi9cblxuICAgICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgICBoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBBTk5PVEFUSU9OX1dJRFRILCAvL3JhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQgLSByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0LzQsXG4gICAgICAgICAgICBsZWZ0OiB3aW5kb3cuaW5uZXJXaWR0aCAqIGFubm90YXRpb25PZmZzZXQgLSBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgIHdpZHRoOiBBTk5PVEFUSU9OX1dJRFRILFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwieDFcIixcbiAgICAgICAgICBgJHtoaWdobGlnaHRBcmVhU1ZHTGluZS5yZWN0LmxlZnQgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIngyXCIsXG4gICAgICAgICAgYCR7XG4gICAgICAgICAgICAoaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5sZWZ0ICsgaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCkgKlxuICAgICAgICAgICAgc2NhbGVcbiAgICAgICAgICB9YFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBsaW5lT2Zmc2V0ID0gaGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgLyAyO1xuICAgICAgICBjb25zdCB5ID0gKGhpZ2hsaWdodEFyZWFTVkdMaW5lLnJlY3QudG9wICsgbGluZU9mZnNldCkgKiBzY2FsZTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTFcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFwieTJcIiwgYCR7eX1gKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0xpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwiaGVpZ2h0XCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC5oZWlnaHQgKiBzY2FsZX1gXG4gICAgICAgICk7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFTVkdMaW5lLnNldEF0dHJpYnV0ZShcbiAgICAgICAgICBcIndpZHRoXCIsXG4gICAgICAgICAgYCR7aGlnaGxpZ2h0QXJlYVNWR0xpbmUucmVjdC53aWR0aCAqIHNjYWxlfWBcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYVNWR0RvY0ZyYWcuYXBwZW5kQ2hpbGQoaGlnaGxpZ2h0QXJlYVNWR0xpbmUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoaWdobGlnaHRBcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuICAgICAgaGlnaGxpZ2h0QXJlYS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG5cbiAgICAgIGlmIChERUJVR19WSVNVQUxTKSB7XG4gICAgICAgIGNvbnN0IHJnYiA9IE1hdGgucm91bmQoMHhmZmZmZmYgKiBNYXRoLnJhbmRvbSgpKTtcbiAgICAgICAgY29uc3QgciA9IHJnYiA+PiAxNjtcbiAgICAgICAgY29uc3QgZyA9IChyZ2IgPj4gOCkgJiAyNTU7XG4gICAgICAgIGNvbnN0IGIgPSByZ2IgJiAyNTU7XG4gICAgICAgIGV4dHJhID0gYG91dGxpbmUtY29sb3I6IHJnYigke3J9LCAke2d9LCAke2J9KTsgb3V0bGluZS1zdHlsZTogc29saWQ7IG91dGxpbmUtd2lkdGg6IDFweDsgb3V0bGluZS1vZmZzZXQ6IC0xcHg7YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChkcmF3VW5kZXJsaW5lKSB7XG4gICAgICAgICAgZXh0cmEgKz0gYGJvcmRlci1ib3R0b206ICR7dW5kZXJsaW5lVGhpY2tuZXNzICogc2NhbGV9cHggc29saWQgcmdiYSgke1xuICAgICAgICAgICAgaGlnaGxpZ2h0LmNvbG9yLnJlZFxuICAgICAgICAgIH0sICR7aGlnaGxpZ2h0LmNvbG9yLmdyZWVufSwgJHtcbiAgICAgICAgICAgIGhpZ2hsaWdodC5jb2xvci5ibHVlXG4gICAgICAgICAgfSwgJHtvcGFjaXR5fSkgIWltcG9ydGFudGA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGhpZ2hsaWdodEFyZWEuc2V0QXR0cmlidXRlKFxuICAgICAgICBcInN0eWxlXCIsXG4gICAgICAgIGBib3JkZXItcmFkaXVzOiAke3JvdW5kZWRDb3JuZXJ9cHggIWltcG9ydGFudDsgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KSAhaW1wb3J0YW50OyAke2V4dHJhfWBcbiAgICAgICk7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgaGlnaGxpZ2h0QXJlYS5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc2NhbGUgPSBzY2FsZTtcbiAgICAgIC8qXG4gICAgICAgICAgICAgaGlnaGxpZ2h0QXJlYS5yZWN0ID0ge1xuICAgICAgICAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICovXG4gICAgICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYS5yZWN0ID0ge1xuICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICAgICAgdG9wOiByYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2hsaWdodEFyZWEucmVjdCA9IHtcbiAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCAtIHhPZmZzZXQsXG4gICAgICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUud2lkdGggPSBgJHtoaWdobGlnaHRBcmVhLnJlY3Qud2lkdGggKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLmhlaWdodCA9IGAke2hpZ2hsaWdodEFyZWEucmVjdC5oZWlnaHQgKiBzY2FsZX1weGA7XG4gICAgICBoaWdobGlnaHRBcmVhLnN0eWxlLmxlZnQgPSBgJHtoaWdobGlnaHRBcmVhLnJlY3QubGVmdCAqIHNjYWxlfXB4YDtcbiAgICAgIGhpZ2hsaWdodEFyZWEuc3R5bGUudG9wID0gYCR7aGlnaGxpZ2h0QXJlYS5yZWN0LnRvcCAqIHNjYWxlfXB4YDtcbiAgICAgIGhpZ2hsaWdodFBhcmVudC5hcHBlbmQoaGlnaGxpZ2h0QXJlYSk7XG4gICAgICBpZiAoIURFQlVHX1ZJU1VBTFMgJiYgZHJhd1N0cmlrZVRocm91Z2gpIHtcbiAgICAgICAgLy9pZiAoZHJhd1N0cmlrZVRocm91Z2gpIHtcbiAgICAgICAgY29uc3QgaGlnaGxpZ2h0QXJlYUxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19ISUdITElHSFRfQVJFQSk7XG5cbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc2V0QXR0cmlidXRlKFxuICAgICAgICAgIFwic3R5bGVcIixcbiAgICAgICAgICBgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KSAhaW1wb3J0YW50O2BcbiAgICAgICAgKTtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLnBvc2l0aW9uID0gcGFnaW5hdGVkID8gXCJmaXhlZFwiIDogXCJhYnNvbHV0ZVwiO1xuICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5zY2FsZSA9IHNjYWxlO1xuICAgICAgICAvKlxuICAgICAgICAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0ID0ge1xuICAgICAgICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgICAgICAgICAgICB0b3A6IGNsaWVudFJlY3QudG9wIC0geU9mZnNldCxcbiAgICAgICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdCA9IHtcbiAgICAgICAgICAgIGhlaWdodDogQU5OT1RBVElPTl9XSURUSCwgLy9yYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QuaGVpZ2h0IC0gcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodC80LFxuICAgICAgICAgICAgbGVmdDogd2luZG93LmlubmVyV2lkdGggKiBhbm5vdGF0aW9uT2Zmc2V0IC0gQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICAgIHRvcDogcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LnRvcCAtIHlPZmZzZXQsXG4gICAgICAgICAgICB3aWR0aDogQU5OT1RBVElPTl9XSURUSCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogY2xpZW50UmVjdC5sZWZ0IC0geE9mZnNldCxcbiAgICAgICAgICAgIHRvcDogY2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgICAgICAgd2lkdGg6IGNsaWVudFJlY3Qud2lkdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLndpZHRoID0gYCR7XG4gICAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUucmVjdC53aWR0aCAqIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLmhlaWdodCA9IGAke1xuICAgICAgICAgIHN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzICogc2NhbGVcbiAgICAgICAgfXB4YDtcbiAgICAgICAgaGlnaGxpZ2h0QXJlYUxpbmUuc3R5bGUubGVmdCA9IGAke1xuICAgICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnJlY3QubGVmdCAqIHNjYWxlXG4gICAgICAgIH1weGA7XG4gICAgICAgIGhpZ2hsaWdodEFyZWFMaW5lLnN0eWxlLnRvcCA9IGAke1xuICAgICAgICAgIChoaWdobGlnaHRBcmVhTGluZS5yZWN0LnRvcCArXG4gICAgICAgICAgICBoaWdobGlnaHRBcmVhTGluZS5yZWN0LmhlaWdodCAvIDIgLVxuICAgICAgICAgICAgc3RyaWtlVGhyb3VnaExpbmVUaGlja25lc3MgLyAyKSAqXG4gICAgICAgICAgc2NhbGVcbiAgICAgICAgfXB4YDtcbiAgICAgICAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRBcmVhTGluZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGFubm90YXRpb25GbGFnKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAodXNlU1ZHICYmIGhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnKSB7XG4gICAgY29uc3QgaGlnaGxpZ2h0QXJlYVNWRyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfWE1MX05BTUVTUEFDRSwgXCJzdmdcIik7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zZXRBdHRyaWJ1dGUoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLnN0eWxlLm92ZXJmbG93ID0gXCJ2aXNpYmxlXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS5sZWZ0ID0gXCIwXCI7XG4gICAgaGlnaGxpZ2h0QXJlYVNWRy5zdHlsZS50b3AgPSBcIjBcIjtcbiAgICBoaWdobGlnaHRBcmVhU1ZHLmFwcGVuZChoaWdobGlnaHRBcmVhU1ZHRG9jRnJhZyk7XG4gICAgaGlnaGxpZ2h0UGFyZW50LmFwcGVuZChoaWdobGlnaHRBcmVhU1ZHKTtcbiAgfVxuXG4gIGNvbnN0IGhpZ2hsaWdodEJvdW5kaW5nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuICBpZiAoYW5ub3RhdGlvbkZsYWcpIHtcbiAgICBoaWdobGlnaHRCb3VuZGluZy5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBDTEFTU19BTk5PVEFUSU9OX0JPVU5ESU5HX0FSRUEpO1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnNldEF0dHJpYnV0ZShcbiAgICAgIFwic3R5bGVcIixcbiAgICAgIGBib3JkZXItcmFkaXVzOiAke3JvdW5kZWRDb3JuZXJ9cHggIWltcG9ydGFudDsgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgke2hpZ2hsaWdodC5jb2xvci5yZWR9LCAke2hpZ2hsaWdodC5jb2xvci5ncmVlbn0sICR7aGlnaGxpZ2h0LmNvbG9yLmJsdWV9LCAke29wYWNpdHl9KSAhaW1wb3J0YW50OyAke2V4dHJhfWBcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIENMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBKTtcbiAgfVxuXG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5wb3NpdGlvbiA9IHBhZ2luYXRlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIjtcbiAgaGlnaGxpZ2h0Qm91bmRpbmcuc2NhbGUgPSBzY2FsZTtcblxuICBpZiAoREVCVUdfVklTVUFMUykge1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnNldEF0dHJpYnV0ZShcbiAgICAgIFwic3R5bGVcIixcbiAgICAgIGBvdXRsaW5lLWNvbG9yOiBtYWdlbnRhOyBvdXRsaW5lLXN0eWxlOiBzb2xpZDsgb3V0bGluZS13aWR0aDogMXB4OyBvdXRsaW5lLW9mZnNldDogLTFweDtgXG4gICAgKTtcbiAgfVxuXG4gIGlmIChhbm5vdGF0aW9uRmxhZykge1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnJlY3QgPSB7XG4gICAgICBoZWlnaHQ6IEFOTk9UQVRJT05fV0lEVEgsIC8vcmFuZ2VBbm5vdGF0aW9uQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCAtIHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC5oZWlnaHQvNCxcbiAgICAgIGxlZnQ6IHdpbmRvdy5pbm5lcldpZHRoICogYW5ub3RhdGlvbk9mZnNldCAtIEFOTk9UQVRJT05fV0lEVEgsXG4gICAgICB0b3A6IHJhbmdlQW5ub3RhdGlvbkJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgd2lkdGg6IEFOTk9UQVRJT05fV0lEVEgsXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdCA9IHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGhpZ2hsaWdodEJvdW5kaW5nLnJlY3QgPSB7XG4gICAgICBoZWlnaHQ6IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0LmhlaWdodCxcbiAgICAgIGxlZnQ6IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0LmxlZnQgLSB4T2Zmc2V0LFxuICAgICAgdG9wOiByYW5nZUJvdW5kaW5nQ2xpZW50UmVjdC50b3AgLSB5T2Zmc2V0LFxuICAgICAgd2lkdGg6IHJhbmdlQm91bmRpbmdDbGllbnRSZWN0LndpZHRoLFxuICAgIH07XG4gIH1cblxuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS53aWR0aCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3Qud2lkdGggKiBzY2FsZX1weGA7XG4gIGhpZ2hsaWdodEJvdW5kaW5nLnN0eWxlLmhlaWdodCA9IGAke2hpZ2hsaWdodEJvdW5kaW5nLnJlY3QuaGVpZ2h0ICogc2NhbGV9cHhgO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS5sZWZ0ID0gYCR7aGlnaGxpZ2h0Qm91bmRpbmcucmVjdC5sZWZ0ICogc2NhbGV9cHhgO1xuICBoaWdobGlnaHRCb3VuZGluZy5zdHlsZS50b3AgPSBgJHtoaWdobGlnaHRCb3VuZGluZy5yZWN0LnRvcCAqIHNjYWxlfXB4YDtcblxuICBoaWdobGlnaHRQYXJlbnQuYXBwZW5kKGhpZ2hsaWdodEJvdW5kaW5nKTtcbiAgaGlnaGxpZ2h0c0NvbnRhaW5lci5hcHBlbmQoaGlnaGxpZ2h0UGFyZW50KTtcblxuICByZXR1cm4gaGlnaGxpZ2h0UGFyZW50O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVPcmRlcmVkUmFuZ2Uoc3RhcnROb2RlLCBzdGFydE9mZnNldCwgZW5kTm9kZSwgZW5kT2Zmc2V0KSB7XG4gIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlLnNldFN0YXJ0KHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICByYW5nZS5zZXRFbmQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgaWYgKCFyYW5nZS5jb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgY29uc29sZS5sb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIENPTExBUFNFRCAuLi4gUkFOR0UgUkVWRVJTRT9cIik7XG4gIGNvbnN0IHJhbmdlUmV2ZXJzZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZVJldmVyc2Uuc2V0U3RhcnQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgcmFuZ2VSZXZlcnNlLnNldEVuZChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgaWYgKCFyYW5nZVJldmVyc2UuY29sbGFwc2VkKSB7XG4gICAgY29uc29sZS5sb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgT0suXCIpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBjb25zb2xlLmxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgUkFOR0UgUkVWRVJTRSBBTFNPIENPTExBUFNFRD8hXCIpO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UmFuZ2UocmFuZ2UsIGdldENzc1NlbGVjdG9yLCBjb21wdXRlRWxlbWVudENGSSkge1xuICBjb25zdCBzdGFydElzRWxlbWVudCA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERTtcbiAgY29uc3Qgc3RhcnRDb250YWluZXJFbGVtZW50ID0gc3RhcnRJc0VsZW1lbnRcbiAgICA/IHJhbmdlLnN0YXJ0Q29udGFpbmVyXG4gICAgOiByYW5nZS5zdGFydENvbnRhaW5lci5wYXJlbnROb2RlICYmXG4gICAgICByYW5nZS5zdGFydENvbnRhaW5lci5wYXJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgID8gcmFuZ2Uuc3RhcnRDb250YWluZXIucGFyZW50Tm9kZVxuICAgIDogdW5kZWZpbmVkO1xuICBpZiAoIXN0YXJ0Q29udGFpbmVyRWxlbWVudCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPSBzdGFydElzRWxlbWVudFxuICAgID8gLTFcbiAgICA6IEFycmF5LmZyb20oc3RhcnRDb250YWluZXJFbGVtZW50LmNoaWxkTm9kZXMpLmluZGV4T2YoXG4gICAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyXG4gICAgICApO1xuICBpZiAoc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPCAtMSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IgPSBnZXRDc3NTZWxlY3RvcihcbiAgICBzdGFydENvbnRhaW5lckVsZW1lbnRcbiAgKTtcbiAgY29uc3QgZW5kSXNFbGVtZW50ID0gcmFuZ2UuZW5kQ29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERTtcbiAgY29uc3QgZW5kQ29udGFpbmVyRWxlbWVudCA9IGVuZElzRWxlbWVudFxuICAgID8gcmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgOiByYW5nZS5lbmRDb250YWluZXIucGFyZW50Tm9kZSAmJlxuICAgICAgcmFuZ2UuZW5kQ29udGFpbmVyLnBhcmVudE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXG4gICAgPyByYW5nZS5lbmRDb250YWluZXIucGFyZW50Tm9kZVxuICAgIDogdW5kZWZpbmVkO1xuICBpZiAoIWVuZENvbnRhaW5lckVsZW1lbnQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA9IGVuZElzRWxlbWVudFxuICAgID8gLTFcbiAgICA6IEFycmF5LmZyb20oZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzKS5pbmRleE9mKHJhbmdlLmVuZENvbnRhaW5lcik7XG4gIGlmIChlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPCAtMSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yID0gZ2V0Q3NzU2VsZWN0b3IoZW5kQ29udGFpbmVyRWxlbWVudCk7XG4gIGNvbnN0IGNvbW1vbkVsZW1lbnRBbmNlc3RvciA9IGdldENvbW1vbkFuY2VzdG9yRWxlbWVudChcbiAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICByYW5nZS5lbmRDb250YWluZXJcbiAgKTtcbiAgaWYgKCFjb21tb25FbGVtZW50QW5jZXN0b3IpIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBOTyBSQU5HRSBDT01NT04gQU5DRVNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChyYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lcikge1xuICAgIGNvbnN0IHJhbmdlQ29tbW9uQW5jZXN0b3JFbGVtZW50ID1cbiAgICAgIHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERVxuICAgICAgICA/IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyXG4gICAgICAgIDogcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIucGFyZW50Tm9kZTtcbiAgICBpZiAoXG4gICAgICByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCAmJlxuICAgICAgcmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXG4gICAgKSB7XG4gICAgICBpZiAoY29tbW9uRWxlbWVudEFuY2VzdG9yICE9PSByYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIj4+Pj4+PiBDT01NT04gQU5DRVNUT1IgQ09OVEFJTkVSIERJRkY/PyFcIik7XG4gICAgICAgIGNvbnNvbGUubG9nKGdldENzc1NlbGVjdG9yKGNvbW1vbkVsZW1lbnRBbmNlc3RvcikpO1xuICAgICAgICBjb25zb2xlLmxvZyhnZXRDc3NTZWxlY3RvcihyYW5nZUNvbW1vbkFuY2VzdG9yRWxlbWVudCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCByb290RWxlbWVudENmaSA9IGNvbXB1dGVFbGVtZW50Q0ZJKGNvbW1vbkVsZW1lbnRBbmNlc3Rvcik7XG4gIGNvbnN0IHN0YXJ0RWxlbWVudENmaSA9IGNvbXB1dGVFbGVtZW50Q0ZJKHN0YXJ0Q29udGFpbmVyRWxlbWVudCk7XG4gIGNvbnN0IGVuZEVsZW1lbnRDZmkgPSBjb21wdXRlRWxlbWVudENGSShlbmRDb250YWluZXJFbGVtZW50KTtcbiAgbGV0IGNmaTtcbiAgaWYgKHJvb3RFbGVtZW50Q2ZpICYmIHN0YXJ0RWxlbWVudENmaSAmJiBlbmRFbGVtZW50Q2ZpKSB7XG4gICAgbGV0IHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9IHN0YXJ0RWxlbWVudENmaTtcbiAgICBpZiAoIXN0YXJ0SXNFbGVtZW50KSB7XG4gICAgICBjb25zdCBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSA9IGdldENoaWxkVGV4dE5vZGVDZmlJbmRleChcbiAgICAgICAgc3RhcnRDb250YWluZXJFbGVtZW50LFxuICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lclxuICAgICAgKTtcbiAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgIHN0YXJ0RWxlbWVudENmaSArXG4gICAgICAgIFwiL1wiICtcbiAgICAgICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhGb3JDZmkgK1xuICAgICAgICBcIjpcIiArXG4gICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0ID49IDAgJiZcbiAgICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQgPCBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZS5zdGFydE9mZnNldF07XG4gICAgICAgIGlmIChjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgKHJhbmdlLnN0YXJ0T2Zmc2V0ICsgMSkgKiAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNmaVRleHROb2RlSW5kZXggPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQsXG4gICAgICAgICAgICBjaGlsZE5vZGVcbiAgICAgICAgICApO1xuICAgICAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaSA9IHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgY2ZpVGV4dE5vZGVJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY2ZpSW5kZXhPZkxhc3RFbGVtZW50ID1cbiAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQgKiAyO1xuICAgICAgICBjb25zdCBsYXN0Q2hpbGROb2RlID1cbiAgICAgICAgICBzdGFydENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tcbiAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICBdO1xuICAgICAgICBpZiAobGFzdENoaWxkTm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgICBzdGFydEVsZW1lbnRPclRleHRDZmkgPVxuICAgICAgICAgICAgc3RhcnRFbGVtZW50Q2ZpICsgXCIvXCIgKyAoY2ZpSW5kZXhPZkxhc3RFbGVtZW50ICsgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RhcnRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgICAgIHN0YXJ0RWxlbWVudENmaSArIFwiL1wiICsgKGNmaUluZGV4T2ZMYXN0RWxlbWVudCArIDIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGxldCBlbmRFbGVtZW50T3JUZXh0Q2ZpID0gZW5kRWxlbWVudENmaTtcbiAgICBpZiAoIWVuZElzRWxlbWVudCkge1xuICAgICAgY29uc3QgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpID0gZ2V0Q2hpbGRUZXh0Tm9kZUNmaUluZGV4KFxuICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LFxuICAgICAgICByYW5nZS5lbmRDb250YWluZXJcbiAgICAgICk7XG4gICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID1cbiAgICAgICAgZW5kRWxlbWVudENmaSArXG4gICAgICAgIFwiL1wiICtcbiAgICAgICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpICtcbiAgICAgICAgXCI6XCIgK1xuICAgICAgICByYW5nZS5lbmRPZmZzZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChcbiAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0ID49IDAgJiZcbiAgICAgICAgcmFuZ2UuZW5kT2Zmc2V0IDwgZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aFxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkTm9kZSA9IGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZS5lbmRPZmZzZXRdO1xuICAgICAgICBpZiAoY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIGVuZEVsZW1lbnRPclRleHRDZmkgPSBlbmRFbGVtZW50Q2ZpICsgXCIvXCIgKyAocmFuZ2UuZW5kT2Zmc2V0ICsgMSkgKiAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNmaVRleHROb2RlSW5kZXggPSBnZXRDaGlsZFRleHROb2RlQ2ZpSW5kZXgoXG4gICAgICAgICAgICBlbmRDb250YWluZXJFbGVtZW50LFxuICAgICAgICAgICAgY2hpbGROb2RlXG4gICAgICAgICAgKTtcbiAgICAgICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpID0gZW5kRWxlbWVudENmaSArIFwiL1wiICsgY2ZpVGV4dE5vZGVJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY2ZpSW5kZXhPZkxhc3RFbGVtZW50ID0gZW5kQ29udGFpbmVyRWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudCAqIDI7XG4gICAgICAgIGNvbnN0IGxhc3RDaGlsZE5vZGUgPVxuICAgICAgICAgIGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlc1tcbiAgICAgICAgICAgIGVuZENvbnRhaW5lckVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggLSAxXG4gICAgICAgICAgXTtcbiAgICAgICAgaWYgKGxhc3RDaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBlbmRFbGVtZW50Q2ZpICsgXCIvXCIgKyAoY2ZpSW5kZXhPZkxhc3RFbGVtZW50ICsgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5kRWxlbWVudE9yVGV4dENmaSA9XG4gICAgICAgICAgICBlbmRFbGVtZW50Q2ZpICsgXCIvXCIgKyAoY2ZpSW5kZXhPZkxhc3RFbGVtZW50ICsgMik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgY2ZpID1cbiAgICAgIHJvb3RFbGVtZW50Q2ZpICtcbiAgICAgIFwiLFwiICtcbiAgICAgIHN0YXJ0RWxlbWVudE9yVGV4dENmaS5yZXBsYWNlKHJvb3RFbGVtZW50Q2ZpLCBcIlwiKSArXG4gICAgICBcIixcIiArXG4gICAgICBlbmRFbGVtZW50T3JUZXh0Q2ZpLnJlcGxhY2Uocm9vdEVsZW1lbnRDZmksIFwiXCIpO1xuICB9XG4gIHJldHVybiB7XG4gICAgY2ZpLFxuICAgIGVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgZW5kT2Zmc2V0OiByYW5nZS5lbmRPZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgc3RhcnRPZmZzZXQ6IHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCByYW5nZUluZm8pIHtcbiAgY29uc3Qgc3RhcnRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFzdGFydEVsZW1lbnQpIHtcbiAgICBjb25zb2xlLmxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIFNUQVJUIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgc3RhcnRDb250YWluZXIgPSBzdGFydEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHN0YXJ0Q29udGFpbmVyID1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gc3RhcnRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIGNvbnN0IGVuZEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5lbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3JcbiAgKTtcbiAgaWYgKCFlbmRFbGVtZW50KSB7XG4gICAgY29uc29sZS5sb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBFTkQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBlbmRDb250YWluZXIgPSBlbmRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IGVuZEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZW5kQ29udGFpbmVyID1cbiAgICAgIGVuZEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4XTtcbiAgICBpZiAoZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgIHN0YXJ0Q29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5zdGFydE9mZnNldCxcbiAgICBlbmRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLmVuZE9mZnNldFxuICApO1xufVxuXG5mdW5jdGlvbiBmcmFtZUZvckhpZ2hsaWdodEFubm90YXRpb25NYXJrV2l0aElEKHdpbiwgaWQpIHtcbiAgbGV0IGNsaWVudFJlY3RzID0gZnJhbWVGb3JIaWdobGlnaHRXaXRoSUQoaWQpO1xuICBpZiAoIWNsaWVudFJlY3RzKSByZXR1cm47XG5cbiAgdmFyIHRvcENsaWVudFJlY3QgPSBjbGllbnRSZWN0c1swXTtcbiAgdmFyIG1heEhlaWdodCA9IHRvcENsaWVudFJlY3QuaGVpZ2h0O1xuICBmb3IgKGNvbnN0IGNsaWVudFJlY3Qgb2YgY2xpZW50UmVjdHMpIHtcbiAgICBpZiAoY2xpZW50UmVjdC50b3AgPCB0b3BDbGllbnRSZWN0LnRvcCkgdG9wQ2xpZW50UmVjdCA9IGNsaWVudFJlY3Q7XG4gICAgaWYgKGNsaWVudFJlY3QuaGVpZ2h0ID4gbWF4SGVpZ2h0KSBtYXhIZWlnaHQgPSBjbGllbnRSZWN0LmhlaWdodDtcbiAgfVxuXG4gIGNvbnN0IGRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuXG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgcGFnaW5hdGVkID0gaXNQYWdpbmF0ZWQoZG9jdW1lbnQpO1xuICBjb25zdCBib2R5UmVjdCA9IGRvY3VtZW50LmJvZHkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGxldCB5T2Zmc2V0O1xuICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSkge1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAtc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgOiBib2R5UmVjdC50b3A7XG4gIH0gZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC9pKSkge1xuICAgIHlPZmZzZXQgPSBwYWdpbmF0ZWQgPyAwIDogYm9keVJlY3QudG9wO1xuICB9XG4gIHZhciBuZXdUb3AgPSB0b3BDbGllbnRSZWN0LnRvcDtcblxuICBpZiAoX2hpZ2hsaWdodHNDb250YWluZXIpIHtcbiAgICBkbyB7XG4gICAgICB2YXIgYm91bmRpbmdBcmVhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAgIENMQVNTX0FOTk9UQVRJT05fQk9VTkRJTkdfQVJFQVxuICAgICAgKTtcbiAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgICAgLy9mb3IgKGxldCBpID0gMCwgbGVuZ3RoID0gYm91bmRpbmdBcmVhcy5zbmFwc2hvdExlbmd0aDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICBmb3IgKFxuICAgICAgICB2YXIgaSA9IDAsIGxlbiA9IGJvdW5kaW5nQXJlYXMubGVuZ3RoIHwgMDtcbiAgICAgICAgaSA8IGxlbjtcbiAgICAgICAgaSA9IChpICsgMSkgfCAwXG4gICAgICApIHtcbiAgICAgICAgdmFyIGJvdW5kaW5nQXJlYSA9IGJvdW5kaW5nQXJlYXNbaV07XG4gICAgICAgIGlmIChNYXRoLmFicyhib3VuZGluZ0FyZWEucmVjdC50b3AgLSAobmV3VG9wIC0geU9mZnNldCkpIDwgMykge1xuICAgICAgICAgIG5ld1RvcCArPSBib3VuZGluZ0FyZWEucmVjdC5oZWlnaHQ7XG4gICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAoZm91bmQpO1xuICB9XG5cbiAgdG9wQ2xpZW50UmVjdC50b3AgPSBuZXdUb3A7XG4gIHRvcENsaWVudFJlY3QuaGVpZ2h0ID0gbWF4SGVpZ2h0O1xuXG4gIHJldHVybiB0b3BDbGllbnRSZWN0O1xufVxuXG5mdW5jdGlvbiBoaWdobGlnaHRXaXRoSUQoaWQpIHtcbiAgbGV0IGkgPSAtMTtcbiAgY29uc3QgaGlnaGxpZ2h0ID0gX2hpZ2hsaWdodHMuZmluZCgoaCwgaikgPT4ge1xuICAgIGkgPSBqO1xuICAgIHJldHVybiBoLmlkID09PSBpZDtcbiAgfSk7XG4gIHJldHVybiBoaWdobGlnaHQ7XG59XG5cbmZ1bmN0aW9uIGZyYW1lRm9ySGlnaGxpZ2h0V2l0aElEKGlkKSB7XG4gIGNvbnN0IGhpZ2hsaWdodCA9IGhpZ2hsaWdodFdpdGhJRChpZCk7XG4gIGlmICghaGlnaGxpZ2h0KSByZXR1cm47XG5cbiAgY29uc3QgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG4gIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSBnZXRTY3JvbGxpbmdFbGVtZW50KGRvY3VtZW50KTtcbiAgY29uc3QgcmFuZ2UgPSBjb252ZXJ0UmFuZ2VJbmZvKGRvY3VtZW50LCBoaWdobGlnaHQucmFuZ2VJbmZvKTtcbiAgaWYgKCFyYW5nZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkcmF3VW5kZXJsaW5lID0gZmFsc2U7XG4gIGNvbnN0IGRyYXdTdHJpa2VUaHJvdWdoID0gZmFsc2U7XG4gIGNvbnN0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSBkcmF3VW5kZXJsaW5lIHx8IGRyYXdTdHJpa2VUaHJvdWdoO1xuICAvL2NvbnN0IGNsaWVudFJlY3RzID0gREVCVUdfVklTVUFMUyA/IHJhbmdlLmdldENsaWVudFJlY3RzKCkgOlxuICBjb25zdCBjbGllbnRSZWN0cyA9IGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICAgIHJhbmdlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcblxuICByZXR1cm4gY2xpZW50UmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJhbmdlSW5mbzJMb2NhdGlvbihyYW5nZUluZm8pIHtcbiAgcmV0dXJuIHtcbiAgICBjc3NTZWxlY3RvcjogcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgIHBhcnRpYWxDZmk6IHJhbmdlSW5mby5jZmksXG4gICAgZG9tUmFuZ2U6IHtcbiAgICAgIHN0YXJ0OiB7XG4gICAgICAgIGNzc1NlbGVjdG9yOiByYW5nZUluZm8uc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IsXG4gICAgICAgIHRleHROb2RlSW5kZXg6IHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCxcbiAgICAgICAgb2Zmc2V0OiByYW5nZUluZm8uc3RhcnRPZmZzZXQsXG4gICAgICB9LFxuICAgICAgZW5kOiB7XG4gICAgICAgIGNzc1NlbGVjdG9yOiByYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yLFxuICAgICAgICB0ZXh0Tm9kZUluZGV4OiByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4LFxuICAgICAgICBvZmZzZXQ6IHJhbmdlSW5mby5lbmRPZmZzZXQsXG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvY2F0aW9uMlJhbmdlSW5mbyhsb2NhdGlvbikge1xuICBjb25zdCBsb2NhdGlvbnMgPSBsb2NhdGlvbi5sb2NhdGlvbnM7XG4gIGNvbnN0IGRvbVJhbmdlID0gbG9jYXRpb25zLmRvbVJhbmdlO1xuICBjb25zdCBzdGFydCA9IGRvbVJhbmdlLnN0YXJ0O1xuICBjb25zdCBlbmQgPSBkb21SYW5nZS5lbmQ7XG5cbiAgcmV0dXJuIHtcbiAgICBjZmk6IGxvY2F0aW9uLnBhcnRpYWxDZmksXG4gICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBlbmQudGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IGVuZC5jc3NTZWxlY3RvcixcbiAgICBlbmRPZmZzZXQ6IGVuZC5vZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IHN0YXJ0LnRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IHN0YXJ0LmNzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiBzdGFydC5vZmZzZXQsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQoaWQpIHtcbiAgY29uc3QgaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0V2l0aElEKGlkKTtcbiAgaWYgKCFoaWdobGlnaHQpIHJldHVybjtcblxuICBjb25zdCBkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDtcbiAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IGdldFNjcm9sbGluZ0VsZW1lbnQoZG9jdW1lbnQpO1xuICBjb25zdCByYW5nZSA9IGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIGhpZ2hsaWdodC5yYW5nZUluZm8pO1xuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGRyYXdVbmRlcmxpbmUgPSBmYWxzZTtcbiAgY29uc3QgZHJhd1N0cmlrZVRocm91Z2ggPSBmYWxzZTtcbiAgY29uc3QgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0cyA9IGRyYXdVbmRlcmxpbmUgfHwgZHJhd1N0cmlrZVRocm91Z2g7XG4gIC8vY29uc3QgY2xpZW50UmVjdHMgPSBERUJVR19WSVNVQUxTID8gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKSA6XG4gIGNvbnN0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgcmFuZ2UsXG4gICAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuICApO1xuICB2YXIgc2l6ZSA9IHtcbiAgICBzY3JlZW5XaWR0aDogd2luZG93Lm91dGVyV2lkdGgsXG4gICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cub3V0ZXJIZWlnaHQsXG4gICAgbGVmdDogY2xpZW50UmVjdHNbMF0ubGVmdCxcbiAgICB3aWR0aDogY2xpZW50UmVjdHNbMF0ud2lkdGgsXG4gICAgdG9wOiBjbGllbnRSZWN0c1swXS50b3AsXG4gICAgaGVpZ2h0OiBjbGllbnRSZWN0c1swXS5oZWlnaHQsXG4gIH07XG5cbiAgcmV0dXJuIHNpemU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZWxlY3Rpb25SZWN0KCkge1xuICB0cnkge1xuICAgIHZhciBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCk7XG5cbiAgICBjb25zdCBjbGllbnRSZWN0ID0gcmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB2YXIgaGFuZGxlQm91bmRzID0ge1xuICAgICAgc2NyZWVuV2lkdGg6IHdpbmRvdy5vdXRlcldpZHRoLFxuICAgICAgc2NyZWVuSGVpZ2h0OiB3aW5kb3cub3V0ZXJIZWlnaHQsXG4gICAgICBsZWZ0OiBjbGllbnRSZWN0LmxlZnQsXG4gICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCxcbiAgICAgIHRvcDogY2xpZW50UmVjdC50b3AsXG4gICAgICBoZWlnaHQ6IGNsaWVudFJlY3QuaGVpZ2h0LFxuICAgIH07XG4gICAgcmV0dXJuIGhhbmRsZUJvdW5kcztcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRTY3JvbGxNb2RlKGZsYWcpIHtcbiAgaWYgKCFmbGFnKSB7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfUEFHSU5BVEVEKTtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19QQUdJTkFURUQpO1xuICB9XG59XG5cbi8qXG4gaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsgLy8gSUUgPj0gOTsgb3RoZXIgYnJvd3NlcnNcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAvL2FsZXJ0KFwiWW91J3ZlIHRyaWVkIHRvIG9wZW4gY29udGV4dCBtZW51XCIpOyAvL2hlcmUgeW91IGRyYXcgeW91ciBvd24gbWVudVxuICAgICAgICAgICAgLy9lLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAvL2xldCBnZXRDc3NTZWxlY3RvciA9IGZ1bGxRdWFsaWZpZWRTZWxlY3RvcjtcbiAgICAgICAgICAgIFxuXHRcdFx0bGV0IHN0ciA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcblx0XHRcdGxldCBzZWxlY3Rpb25JbmZvID0gZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8oKTtcblx0XHRcdGxldCBwb3MgPSBjcmVhdGVIaWdobGlnaHQoc2VsZWN0aW9uSW5mbyx7cmVkOjEwLGdyZWVuOjUwLGJsdWU6MjMwfSx0cnVlKTtcblx0XHRcdGxldCByZXQyID0gY3JlYXRlQW5ub3RhdGlvbihwb3MuaWQpO1xuXHRcdFx0XG4gIH0sIGZhbHNlKTtcbiAgICB9IGVsc2UgeyAvLyBJRSA8IDlcbiAgICAgICAgZG9jdW1lbnQuYXR0YWNoRXZlbnQoJ29uY29udGV4dG1lbnUnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGFsZXJ0KFwiWW91J3ZlIHRyaWVkIHRvIG9wZW4gY29udGV4dCBtZW51XCIpO1xuICAgICAgICAgICAgd2luZG93LmV2ZW50LnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbiovXG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBsb2cgYXMgbG9nTmF0aXZlLCBsb2dFcnJvciwgc25hcEN1cnJlbnRPZmZzZXQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgdG9OYXRpdmVSZWN0IH0gZnJvbSBcIi4vcmVjdFwiO1xuaW1wb3J0IHsgVGV4dFJhbmdlIH0gZnJvbSBcIi4vdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3RleHQtcmFuZ2VcIjtcblxuLy8gUG9seWZpbGwgZm9yIEFuZHJvaWQgQVBJIDI2XG5pbXBvcnQgbWF0Y2hBbGwgZnJvbSBcInN0cmluZy5wcm90b3R5cGUubWF0Y2hhbGxcIjtcbm1hdGNoQWxsLnNoaW0oKTtcblxuY29uc3QgZGVidWcgPSB0cnVlO1xuXG4vLyBOb3RpZnkgbmF0aXZlIGNvZGUgdGhhdCB0aGUgc2VsZWN0aW9uIGNoYW5nZXMuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgXCJsb2FkXCIsXG4gIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2VsZWN0aW9uY2hhbmdlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbGxhcHNlZCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5pc0NvbGxhcHNlZDtcblxuICAgICAgaWYgKGNvbGxhcHNlZCAmJiBpc1NlbGVjdGluZykge1xuICAgICAgICBpc1NlbGVjdGluZyA9IGZhbHNlO1xuICAgICAgICBBbmRyb2lkLm9uU2VsZWN0aW9uRW5kKCk7XG4gICAgICAgIC8vIFNuYXBzIHRoZSBjdXJyZW50IGNvbHVtbiBpbiBjYXNlIHRoZSB1c2VyIHNoaWZ0ZWQgdGhlIHNjcm9sbCBieSBkcmFnZ2luZyB0aGUgdGV4dCBzZWxlY3Rpb24uXG4gICAgICAgIHNuYXBDdXJyZW50T2Zmc2V0KCk7XG4gICAgICB9IGVsc2UgaWYgKCFjb2xsYXBzZWQgJiYgIWlzU2VsZWN0aW5nKSB7XG4gICAgICAgIGlzU2VsZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgQW5kcm9pZC5vblNlbGVjdGlvblN0YXJ0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvbigpIHtcbiAgY29uc3QgdGV4dCA9IGdldEN1cnJlbnRTZWxlY3Rpb25UZXh0KCk7XG4gIGlmICghdGV4dCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IHJlY3QgPSBnZXRTZWxlY3Rpb25SZWN0KCk7XG4gIHJldHVybiB7IHRleHQsIHJlY3QgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uUmVjdCgpIHtcbiAgdHJ5IHtcbiAgICBsZXQgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCByYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuXG4gICAgcmV0dXJuIHRvTmF0aXZlUmVjdChyYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dFcnJvcihlKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCgpIHtcbiAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICBpZiAoIXNlbGVjdGlvbikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHNlbGVjdGlvbi5pc0NvbGxhcHNlZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgaGlnaGxpZ2h0ID0gc2VsZWN0aW9uLnRvU3RyaW5nKCk7XG4gIGNvbnN0IGNsZWFuSGlnaGxpZ2h0ID0gaGlnaGxpZ2h0XG4gICAgLnRyaW0oKVxuICAgIC5yZXBsYWNlKC9cXG4vZywgXCIgXCIpXG4gICAgLnJlcGxhY2UoL1xcc1xccysvZywgXCIgXCIpO1xuICBpZiAoY2xlYW5IaWdobGlnaHQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoIXNlbGVjdGlvbi5hbmNob3JOb2RlIHx8ICFzZWxlY3Rpb24uZm9jdXNOb2RlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByYW5nZSA9XG4gICAgc2VsZWN0aW9uLnJhbmdlQ291bnQgPT09IDFcbiAgICAgID8gc2VsZWN0aW9uLmdldFJhbmdlQXQoMClcbiAgICAgIDogY3JlYXRlT3JkZXJlZFJhbmdlKFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uZm9jdXNPZmZzZXRcbiAgICAgICAgKTtcbiAgaWYgKCFyYW5nZSB8fCByYW5nZS5jb2xsYXBzZWQpIHtcbiAgICBsb2coXCIkJCQkJCQkJCQkJCQkJCQkJCBDQU5OT1QgR0VUIE5PTi1DT0xMQVBTRUQgU0VMRUNUSU9OIFJBTkdFPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHRleHQgPSBkb2N1bWVudC5ib2R5LnRleHRDb250ZW50O1xuICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKGRvY3VtZW50LmJvZHkpO1xuICBjb25zdCBzdGFydCA9IHRleHRSYW5nZS5zdGFydC5vZmZzZXQ7XG4gIGNvbnN0IGVuZCA9IHRleHRSYW5nZS5lbmQub2Zmc2V0O1xuXG4gIGNvbnN0IHNuaXBwZXRMZW5ndGggPSAyMDA7XG5cbiAgLy8gQ29tcHV0ZSB0aGUgdGV4dCBiZWZvcmUgdGhlIGhpZ2hsaWdodCwgaWdub3JpbmcgdGhlIGZpcnN0IFwid29yZFwiLCB3aGljaCBtaWdodCBiZSBjdXQuXG4gIGxldCBiZWZvcmUgPSB0ZXh0LnNsaWNlKE1hdGgubWF4KDAsIHN0YXJ0IC0gc25pcHBldExlbmd0aCksIHN0YXJ0KTtcbiAgbGV0IGZpcnN0V29yZFN0YXJ0ID0gYmVmb3JlLnNlYXJjaCgvXFxQe0x9XFxwe0x9L2d1KTtcbiAgaWYgKGZpcnN0V29yZFN0YXJ0ICE9PSAtMSkge1xuICAgIGJlZm9yZSA9IGJlZm9yZS5zbGljZShmaXJzdFdvcmRTdGFydCArIDEpO1xuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUgdGV4dCBhZnRlciB0aGUgaGlnaGxpZ2h0LCBpZ25vcmluZyB0aGUgbGFzdCBcIndvcmRcIiwgd2hpY2ggbWlnaHQgYmUgY3V0LlxuICBsZXQgYWZ0ZXIgPSB0ZXh0LnNsaWNlKGVuZCwgTWF0aC5taW4odGV4dC5sZW5ndGgsIGVuZCArIHNuaXBwZXRMZW5ndGgpKTtcbiAgbGV0IGxhc3RXb3JkRW5kID0gQXJyYXkuZnJvbShhZnRlci5tYXRjaEFsbCgvXFxwe0x9XFxQe0x9L2d1KSkucG9wKCk7XG4gIGlmIChsYXN0V29yZEVuZCAhPT0gdW5kZWZpbmVkICYmIGxhc3RXb3JkRW5kLmluZGV4ID4gMSkge1xuICAgIGFmdGVyID0gYWZ0ZXIuc2xpY2UoMCwgbGFzdFdvcmRFbmQuaW5kZXggKyAxKTtcbiAgfVxuXG4gIHJldHVybiB7IGhpZ2hsaWdodCwgYmVmb3JlLCBhZnRlciB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVPcmRlcmVkUmFuZ2Uoc3RhcnROb2RlLCBzdGFydE9mZnNldCwgZW5kTm9kZSwgZW5kT2Zmc2V0KSB7XG4gIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlLnNldFN0YXJ0KHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICByYW5nZS5zZXRFbmQoZW5kTm9kZSwgZW5kT2Zmc2V0KTtcbiAgaWYgKCFyYW5nZS5jb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cbiAgbG9nKFwiPj4+IGNyZWF0ZU9yZGVyZWRSYW5nZSBDT0xMQVBTRUQgLi4uIFJBTkdFIFJFVkVSU0U/XCIpO1xuICBjb25zdCByYW5nZVJldmVyc2UgPSBuZXcgUmFuZ2UoKTtcbiAgcmFuZ2VSZXZlcnNlLnNldFN0YXJ0KGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRFbmQoc3RhcnROb2RlLCBzdGFydE9mZnNldCk7XG4gIGlmICghcmFuZ2VSZXZlcnNlLmNvbGxhcHNlZCkge1xuICAgIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgUkFOR0UgUkVWRVJTRSBPSy5cIik7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgUkFOR0UgUkVWRVJTRSBBTFNPIENPTExBUFNFRD8hXCIpO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFJhbmdlSW5mbyhkb2N1bWVudCwgcmFuZ2VJbmZvKSB7XG4gIGNvbnN0IHN0YXJ0RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghc3RhcnRFbGVtZW50KSB7XG4gICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gTk8gU1RBUlQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBzdGFydENvbnRhaW5lciA9IHN0YXJ0RWxlbWVudDtcbiAgaWYgKHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICApIHtcbiAgICAgIGxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHN0YXJ0Q29udGFpbmVyID1cbiAgICAgIHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzW3JhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gc3RhcnRDb250YWluZXIubm9kZVR5cGUgIT09IE5vZGUuVEVYVF9OT0RFPyFcIik7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICBjb25zdCBlbmRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yXG4gICk7XG4gIGlmICghZW5kRWxlbWVudCkge1xuICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIEVORCBFTEVNRU5UIENTUyBTRUxFQ1RPUj8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgbGV0IGVuZENvbnRhaW5lciA9IGVuZEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IDApIHtcbiAgICBpZiAoXG4gICAgICByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IGVuZEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGhcbiAgICApIHtcbiAgICAgIGxvZyhcbiAgICAgICAgXCJeXl4gY29udmVydFJhbmdlSW5mbyByYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IGVuZEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg/IVwiXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZW5kQ29udGFpbmVyID1cbiAgICAgIGVuZEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4XTtcbiAgICBpZiAoZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgbG9nKFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCIpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICBzdGFydENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uc3RhcnRPZmZzZXQsXG4gICAgZW5kQ29udGFpbmVyLFxuICAgIHJhbmdlSW5mby5lbmRPZmZzZXRcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvY2F0aW9uMlJhbmdlSW5mbyhsb2NhdGlvbikge1xuICBjb25zdCBsb2NhdGlvbnMgPSBsb2NhdGlvbi5sb2NhdGlvbnM7XG4gIGNvbnN0IGRvbVJhbmdlID0gbG9jYXRpb25zLmRvbVJhbmdlO1xuICBjb25zdCBzdGFydCA9IGRvbVJhbmdlLnN0YXJ0O1xuICBjb25zdCBlbmQgPSBkb21SYW5nZS5lbmQ7XG5cbiAgcmV0dXJuIHtcbiAgICBlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IGVuZC50ZXh0Tm9kZUluZGV4LFxuICAgIGVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvcjogZW5kLmNzc1NlbGVjdG9yLFxuICAgIGVuZE9mZnNldDogZW5kLm9mZnNldCxcbiAgICBzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleDogc3RhcnQudGV4dE5vZGVJbmRleCxcbiAgICBzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3Rvcjogc3RhcnQuY3NzU2VsZWN0b3IsXG4gICAgc3RhcnRPZmZzZXQ6IHN0YXJ0Lm9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9nKCkge1xuICBpZiAoZGVidWcpIHtcbiAgICBsb2dOYXRpdmUuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuLy8gQmFzZSBzY3JpcHQgdXNlZCBieSBib3RoIHJlZmxvd2FibGUgYW5kIGZpeGVkIGxheW91dCByZXNvdXJjZXMuXG5cbmltcG9ydCBcIi4vZ2VzdHVyZXNcIjtcbmltcG9ydCBcIi4va2V5Ym9hcmRcIjtcbmltcG9ydCB7XG4gIHJlbW92ZVByb3BlcnR5LFxuICBzY3JvbGxMZWZ0LFxuICBzY3JvbGxSaWdodCxcbiAgc2Nyb2xsVG9FbmQsXG4gIHNjcm9sbFRvSWQsXG4gIHNjcm9sbFRvUG9zaXRpb24sXG4gIHNjcm9sbFRvU3RhcnQsXG4gIHNjcm9sbFRvVGV4dCxcbiAgc2V0UHJvcGVydHksXG4gIHNldENTU1Byb3BlcnRpZXMsXG59IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQge1xuICBjcmVhdGVBbm5vdGF0aW9uLFxuICBjcmVhdGVIaWdobGlnaHQsXG4gIGRlc3Ryb3lIaWdobGlnaHQsXG4gIGdldEN1cnJlbnRTZWxlY3Rpb25JbmZvLFxuICBnZXRTZWxlY3Rpb25SZWN0LFxuICByZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQsXG4gIHNldFNjcm9sbE1vZGUsXG59IGZyb20gXCIuL2hpZ2hsaWdodFwiO1xuaW1wb3J0IHsgZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IgfSBmcm9tIFwiLi9kb21cIjtcbmltcG9ydCB7IGdldEN1cnJlbnRTZWxlY3Rpb24gfSBmcm9tIFwiLi9zZWxlY3Rpb25cIjtcbmltcG9ydCB7IGdldERlY29yYXRpb25zLCByZWdpc3RlclRlbXBsYXRlcyB9IGZyb20gXCIuL2RlY29yYXRvclwiO1xuXG4vLyBQdWJsaWMgQVBJIHVzZWQgYnkgdGhlIG5hdmlnYXRvci5cbndpbmRvdy5yZWFkaXVtID0ge1xuICAvLyB1dGlsc1xuICBzY3JvbGxUb0lkOiBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1Bvc2l0aW9uOiBzY3JvbGxUb1Bvc2l0aW9uLFxuICBzY3JvbGxUb1RleHQ6IHNjcm9sbFRvVGV4dCxcbiAgc2Nyb2xsTGVmdDogc2Nyb2xsTGVmdCxcbiAgc2Nyb2xsUmlnaHQ6IHNjcm9sbFJpZ2h0LFxuICBzY3JvbGxUb1N0YXJ0OiBzY3JvbGxUb1N0YXJ0LFxuICBzY3JvbGxUb0VuZDogc2Nyb2xsVG9FbmQsXG4gIHNldENTU1Byb3BlcnRpZXM6IHNldENTU1Byb3BlcnRpZXMsXG4gIHNldFByb3BlcnR5OiBzZXRQcm9wZXJ0eSxcbiAgcmVtb3ZlUHJvcGVydHk6IHJlbW92ZVByb3BlcnR5LFxuXG4gIC8vIHNlbGVjdGlvblxuICBnZXRDdXJyZW50U2VsZWN0aW9uOiBnZXRDdXJyZW50U2VsZWN0aW9uLFxuXG4gIC8vIGRlY29yYXRpb25cbiAgcmVnaXN0ZXJEZWNvcmF0aW9uVGVtcGxhdGVzOiByZWdpc3RlclRlbXBsYXRlcyxcbiAgZ2V0RGVjb3JhdGlvbnM6IGdldERlY29yYXRpb25zLFxuXG4gIC8vIERPTVxuICBmaW5kRmlyc3RWaXNpYmxlTG9jYXRvcjogZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IsXG59O1xuXG4vLyBMZWdhY3kgaGlnaGxpZ2h0cyBBUEkuXG53aW5kb3cuY3JlYXRlQW5ub3RhdGlvbiA9IGNyZWF0ZUFubm90YXRpb247XG53aW5kb3cuY3JlYXRlSGlnaGxpZ2h0ID0gY3JlYXRlSGlnaGxpZ2h0O1xud2luZG93LmRlc3Ryb3lIaWdobGlnaHQgPSBkZXN0cm95SGlnaGxpZ2h0O1xud2luZG93LmdldEN1cnJlbnRTZWxlY3Rpb25JbmZvID0gZ2V0Q3VycmVudFNlbGVjdGlvbkluZm87XG53aW5kb3cuZ2V0U2VsZWN0aW9uUmVjdCA9IGdldFNlbGVjdGlvblJlY3Q7XG53aW5kb3cucmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEID0gcmVjdGFuZ2xlRm9ySGlnaGxpZ2h0V2l0aElEO1xud2luZG93LnNldFNjcm9sbE1vZGUgPSBzZXRTY3JvbGxNb2RlO1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuLy8gU2NyaXB0IHVzZWQgZm9yIHJlZmxvd2FibGUgcmVzb3VyY2VzLlxuXG5pbXBvcnQgXCIuL2luZGV4XCI7XG5cbndpbmRvdy5yZWFkaXVtLmlzUmVmbG93YWJsZSA9IHRydWU7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbiAgLy8gU2V0dXBzIHRoZSBgdmlld3BvcnRgIG1ldGEgdGFnIHRvIGRpc2FibGUgem9vbWluZy5cbiAgbGV0IG1ldGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibWV0YVwiKTtcbiAgbWV0YS5zZXRBdHRyaWJ1dGUoXCJuYW1lXCIsIFwidmlld3BvcnRcIik7XG4gIG1ldGEuc2V0QXR0cmlidXRlKFxuICAgIFwiY29udGVudFwiLFxuICAgIFwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWF4aW11bS1zY2FsZT0xLjAsIHVzZXItc2NhbGFibGU9bm8sIHNocmluay10by1maXQ9bm9cIlxuICApO1xuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGEpO1xufSk7XG4iXSwibmFtZXMiOlsiYXBwcm94U2VhcmNoIiwic2VhcmNoIiwidGV4dCIsInN0ciIsIm1heEVycm9ycyIsIm1hdGNoUG9zIiwiZXhhY3RNYXRjaGVzIiwiaW5kZXhPZiIsInB1c2giLCJzdGFydCIsImVuZCIsImxlbmd0aCIsImVycm9ycyIsInRleHRNYXRjaFNjb3JlIiwibWF0Y2hlcyIsIm1hdGNoUXVvdGUiLCJxdW90ZSIsImNvbnRleHQiLCJNYXRoIiwibWluIiwic2NvcmVNYXRjaCIsIm1hdGNoIiwicXVvdGVXZWlnaHQiLCJwcmVmaXhXZWlnaHQiLCJzdWZmaXhXZWlnaHQiLCJwb3NXZWlnaHQiLCJxdW90ZVNjb3JlIiwicHJlZml4U2NvcmUiLCJwcmVmaXgiLCJzbGljZSIsIm1heCIsInN1ZmZpeFNjb3JlIiwic3VmZml4IiwicG9zU2NvcmUiLCJoaW50Iiwib2Zmc2V0IiwiYWJzIiwicmF3U2NvcmUiLCJtYXhTY29yZSIsIm5vcm1hbGl6ZWRTY29yZSIsInNjb3JlZE1hdGNoZXMiLCJtYXAiLCJtIiwic2NvcmUiLCJzb3J0IiwiYSIsImIiLCJub2RlVGV4dExlbmd0aCIsIm5vZGUiLCJub2RlVHlwZSIsIk5vZGUiLCJFTEVNRU5UX05PREUiLCJURVhUX05PREUiLCJ0ZXh0Q29udGVudCIsInByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoIiwic2libGluZyIsInByZXZpb3VzU2libGluZyIsInJlc29sdmVPZmZzZXRzIiwiZWxlbWVudCIsIm9mZnNldHMiLCJuZXh0T2Zmc2V0Iiwic2hpZnQiLCJub2RlSXRlciIsIm93bmVyRG9jdW1lbnQiLCJjcmVhdGVOb2RlSXRlcmF0b3IiLCJOb2RlRmlsdGVyIiwiU0hPV19URVhUIiwicmVzdWx0cyIsImN1cnJlbnROb2RlIiwibmV4dE5vZGUiLCJ0ZXh0Tm9kZSIsInVuZGVmaW5lZCIsImRhdGEiLCJSYW5nZUVycm9yIiwiUkVTT0xWRV9GT1JXQVJEUyIsIlJFU09MVkVfQkFDS1dBUkRTIiwiVGV4dFBvc2l0aW9uIiwiRXJyb3IiLCJwYXJlbnQiLCJjb250YWlucyIsImVsIiwicGFyZW50RWxlbWVudCIsIm9wdGlvbnMiLCJlcnIiLCJkaXJlY3Rpb24iLCJ0dyIsImRvY3VtZW50IiwiY3JlYXRlVHJlZVdhbGtlciIsImdldFJvb3ROb2RlIiwiZm9yd2FyZHMiLCJwcmV2aW91c05vZGUiLCJmcm9tUG9pbnQiLCJ0ZXh0T2Zmc2V0IiwiY2hpbGROb2RlcyIsImkiLCJUZXh0UmFuZ2UiLCJyZWxhdGl2ZVRvIiwicmVzb2x2ZSIsInJhbmdlIiwiUmFuZ2UiLCJzZXRTdGFydCIsInNldEVuZCIsInN0YXJ0Q29udGFpbmVyIiwic3RhcnRPZmZzZXQiLCJlbmRDb250YWluZXIiLCJlbmRPZmZzZXQiLCJyb290Iiwibm9kZUZyb21YUGF0aCIsInhwYXRoRnJvbU5vZGUiLCJSYW5nZUFuY2hvciIsIm5vcm1hbGl6ZWRSYW5nZSIsImZyb21SYW5nZSIsInRvUmFuZ2UiLCJ0ZXh0UmFuZ2UiLCJ0eXBlIiwic2VsZWN0b3IiLCJzdGFydFBvcyIsImZyb21DaGFyT2Zmc2V0IiwiZW5kUG9zIiwiVGV4dFBvc2l0aW9uQW5jaG9yIiwiZnJvbU9mZnNldHMiLCJUZXh0UXVvdGVBbmNob3IiLCJleGFjdCIsInRvUG9zaXRpb25BbmNob3IiLCJjb250ZXh0TGVuIiwid2luZG93IiwiYWRkRXZlbnRMaXN0ZW5lciIsImV2ZW50IiwiQW5kcm9pZCIsImxvZ0Vycm9yIiwibWVzc2FnZSIsImZpbGVuYW1lIiwibGluZW5vIiwib2JzZXJ2ZXIiLCJSZXNpemVPYnNlcnZlciIsIm9uVmlld3BvcnRXaWR0aENoYW5nZWQiLCJzbmFwQ3VycmVudE9mZnNldCIsIm9ic2VydmUiLCJib2R5IiwiYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkIiwiaWQiLCJ2aXJ0dWFsQ29sIiwiZ2V0RWxlbWVudEJ5SWQiLCJpc1Njcm9sbE1vZGVFbmFibGVkIiwiZ2V0Q29sdW1uQ291bnRQZXJTY3JlZW4iLCJyZW1vdmUiLCJkb2N1bWVudFdpZHRoIiwic2Nyb2xsaW5nRWxlbWVudCIsInNjcm9sbFdpZHRoIiwiY29sQ291bnQiLCJwYWdlV2lkdGgiLCJoYXNPZGRDb2xDb3VudCIsInJvdW5kIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsInN0eWxlIiwiYnJlYWtCZWZvcmUiLCJpbm5lckhUTUwiLCJhcHBlbmRDaGlsZCIsIndpZHRoIiwiZ2V0Vmlld3BvcnRXaWR0aCIsImRldmljZVBpeGVsUmF0aW8iLCJzZXRQcm9wZXJ0eSIsInBhcnNlSW50IiwiZ2V0Q29tcHV0ZWRTdHlsZSIsImRvY3VtZW50RWxlbWVudCIsImdldFByb3BlcnR5VmFsdWUiLCJ0cmltIiwiaXNSVEwiLCJkaXIiLCJ0b0xvd2VyQ2FzZSIsInNjcm9sbFRvSWQiLCJzY3JvbGxUb1JlY3QiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJzY3JvbGxUb1Bvc2l0aW9uIiwicG9zaXRpb24iLCJzY3JvbGxIZWlnaHQiLCJzY3JvbGxUb3AiLCJmYWN0b3IiLCJzY3JvbGxMZWZ0Iiwic25hcE9mZnNldCIsInNjcm9sbFRvVGV4dCIsInJhbmdlRnJvbUxvY2F0b3IiLCJzY3JvbGxUb1JhbmdlIiwicmVjdCIsInRvcCIsInNjcm9sbFkiLCJpbm5lckhlaWdodCIsImxlZnQiLCJzY3JvbGxYIiwic2Nyb2xsVG9TdGFydCIsInNjcm9sbFRvIiwic2Nyb2xsVG9FbmQiLCJtaW5PZmZzZXQiLCJzY3JvbGxUb09mZnNldCIsInNjcm9sbFJpZ2h0IiwibWF4T2Zmc2V0IiwiY3VycmVudE9mZnNldCIsImRpZmYiLCJ2YWx1ZSIsImRlbHRhIiwibG9jYXRvciIsImxvY2F0aW9ucyIsImhpZ2hsaWdodCIsImNzc1NlbGVjdG9yIiwicXVlcnlTZWxlY3RvciIsImFuY2hvciIsImJlZm9yZSIsImFmdGVyIiwiZnJhZ21lbnRzIiwiaHRtbElkIiwiY3JlYXRlUmFuZ2UiLCJzZXRTdGFydEJlZm9yZSIsInNldEVuZEFmdGVyIiwiZSIsInNldENTU1Byb3BlcnRpZXMiLCJwcm9wZXJ0aWVzIiwibmFtZSIsImtleSIsInJlbW92ZVByb3BlcnR5IiwibG9nIiwiQXJyYXkiLCJwcm90b3R5cGUiLCJjYWxsIiwiYXJndW1lbnRzIiwiam9pbiIsImxvZ05hdGl2ZSIsImRlYnVnIiwidG9OYXRpdmVSZWN0IiwicGl4ZWxSYXRpbyIsImhlaWdodCIsInJpZ2h0IiwiYm90dG9tIiwiZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAiLCJkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzIiwiY2xpZW50UmVjdHMiLCJnZXRDbGllbnRSZWN0cyIsInRvbGVyYW5jZSIsIm9yaWdpbmFsUmVjdHMiLCJyYW5nZUNsaWVudFJlY3QiLCJtZXJnZWRSZWN0cyIsIm1lcmdlVG91Y2hpbmdSZWN0cyIsIm5vQ29udGFpbmVkUmVjdHMiLCJyZW1vdmVDb250YWluZWRSZWN0cyIsIm5ld1JlY3RzIiwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyIsIm1pbkFyZWEiLCJqIiwiYmlnRW5vdWdoIiwic3BsaWNlIiwicmVjdHMiLCJyZWN0MSIsInJlY3QyIiwicmVjdHNMaW5lVXBWZXJ0aWNhbGx5IiwiYWxtb3N0RXF1YWwiLCJyZWN0c0xpbmVVcEhvcml6b250YWxseSIsImhvcml6b250YWxBbGxvd2VkIiwiYWxpZ25lZCIsImNhbk1lcmdlIiwicmVjdHNUb3VjaE9yT3ZlcmxhcCIsImZpbHRlciIsInJlcGxhY2VtZW50Q2xpZW50UmVjdCIsImdldEJvdW5kaW5nUmVjdCIsInJlY3RzVG9LZWVwIiwiU2V0IiwiZGVsZXRlIiwicG9zc2libHlDb250YWluaW5nUmVjdCIsImhhcyIsInJlY3RDb250YWlucyIsImZyb20iLCJyZWN0Q29udGFpbnNQb2ludCIsIngiLCJ5IiwidG9BZGQiLCJ0b1JlbW92ZSIsInN1YnRyYWN0UmVjdHMxIiwicmVjdFN1YnRyYWN0Iiwic3VidHJhY3RSZWN0czIiLCJhcHBseSIsInJlY3RJbnRlcnNlY3RlZCIsInJlY3RJbnRlcnNlY3QiLCJyZWN0QSIsInJlY3RCIiwicmVjdEMiLCJyZWN0RCIsIm1heExlZnQiLCJtaW5SaWdodCIsIm1heFRvcCIsIm1pbkJvdHRvbSIsInN0eWxlcyIsIk1hcCIsImdyb3VwcyIsImxhc3RHcm91cElkIiwicmVnaXN0ZXJUZW1wbGF0ZXMiLCJuZXdTdHlsZXMiLCJzdHlsZXNoZWV0IiwiT2JqZWN0IiwiZW50cmllcyIsInNldCIsInN0eWxlRWxlbWVudCIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwiZ2V0RGVjb3JhdGlvbnMiLCJncm91cE5hbWUiLCJncm91cCIsImdldCIsIkRlY29yYXRpb25Hcm91cCIsImhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50IiwiY2xpY2tFdmVudCIsInNpemUiLCJmaW5kVGFyZ2V0IiwiZ3JvdXBDb250ZW50IiwiaXRlbXMiLCJyZXZlcnNlIiwiaXRlbSIsImNsaWNrYWJsZUVsZW1lbnRzIiwidG9KU09OIiwiY2xpZW50WCIsImNsaWVudFkiLCJ0YXJnZXQiLCJvbkRlY29yYXRpb25BY3RpdmF0ZWQiLCJKU09OIiwic3RyaW5naWZ5IiwiZGVjb3JhdGlvbiIsImNsaWNrIiwiZ3JvdXBJZCIsImxhc3RJdGVtSWQiLCJjb250YWluZXIiLCJhZGQiLCJsYXlvdXQiLCJkZWNvcmF0aW9uSWQiLCJpbmRleCIsImZpbmRJbmRleCIsInVwZGF0ZSIsImNsZWFyIiwiY2xlYXJDb250YWluZXIiLCJyZXF1ZXN0TGF5b3V0IiwiZm9yRWFjaCIsImdyb3VwQ29udGFpbmVyIiwicmVxdWlyZUNvbnRhaW5lciIsIml0ZW1Db250YWluZXIiLCJ2aWV3cG9ydFdpZHRoIiwiaW5uZXJXaWR0aCIsImNvbHVtbkNvdW50IiwieE9mZnNldCIsInlPZmZzZXQiLCJwb3NpdGlvbkVsZW1lbnQiLCJib3VuZGluZ1JlY3QiLCJmbG9vciIsImVsZW1lbnRUZW1wbGF0ZSIsInRlbXBsYXRlIiwiY29udGVudCIsImZpcnN0RWxlbWVudENoaWxkIiwiZXJyb3IiLCJyMSIsInIyIiwiY2xpZW50UmVjdCIsImxpbmUiLCJjbG9uZU5vZGUiLCJhcHBlbmQiLCJib3VuZHMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiY2hpbGRyZW4iLCJsYXN0U2l6ZSIsImNsaWVudFdpZHRoIiwiY2xpZW50SGVpZ2h0IiwiZ2V0Q3NzU2VsZWN0b3IiLCJuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50IiwiaW50ZXJhY3RpdmVUYWdzIiwibm9kZU5hbWUiLCJvdXRlckhUTUwiLCJoYXNBdHRyaWJ1dGUiLCJnZXRBdHRyaWJ1dGUiLCJmaW5kRmlyc3RWaXNpYmxlTG9jYXRvciIsImZpbmRFbGVtZW50IiwiaHJlZiIsInJvb3RFbGVtZW50IiwiY2hpbGQiLCJzaG91bGRJZ25vcmVFbGVtZW50IiwiaXNFbGVtZW50VmlzaWJsZSIsInJlYWRpdW0iLCJpc0ZpeGVkTGF5b3V0IiwiZWxTdHlsZSIsImRpc3BsYXkiLCJvcGFjaXR5Iiwib25DbGljayIsImJpbmREcmFnR2VzdHVyZSIsImdldFNlbGVjdGlvbiIsImlzQ29sbGFwc2VkIiwiZGVmYXVsdFByZXZlbnRlZCIsInRhcmdldEVsZW1lbnQiLCJpbnRlcmFjdGl2ZUVsZW1lbnQiLCJzaG91bGRQcmV2ZW50RGVmYXVsdCIsIm9uVGFwIiwic3RvcFByb3BhZ2F0aW9uIiwicHJldmVudERlZmF1bHQiLCJvblN0YXJ0IiwicGFzc2l2ZSIsIm9uRW5kIiwib25Nb3ZlIiwic3RhdGUiLCJpc1N0YXJ0aW5nRHJhZyIsInN0YXJ0WCIsInRvdWNoZXMiLCJzdGFydFkiLCJjdXJyZW50WCIsImN1cnJlbnRZIiwib2Zmc2V0WCIsIm9mZnNldFkiLCJvbkRyYWdTdGFydCIsIm9uRHJhZ01vdmUiLCJvbkRyYWdFbmQiLCJzaG91bGRJZ25vcmVFdmVudCIsInNlbmRQcmVzc0tleU1lc3NhZ2UiLCJhY3RpdmVFbGVtZW50IiwicmVwZWF0Iiwia2V5RXZlbnQiLCJjb2RlIiwiY2hhcmFjdGVycyIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsImtleUNvZGUiLCJhbHQiLCJhbHRLZXkiLCJjb250cm9sIiwiY3RybEtleSIsInNoaWZ0S2V5IiwibWV0YSIsIm1ldGFLZXkiLCJvbktleSIsIlJPT1RfQ0xBU1NfUkVEVUNFX01PVElPTiIsIlJPT1RfQ0xBU1NfTk9fRk9PVE5PVEVTIiwiUE9QVVBfRElBTE9HX0NMQVNTIiwiRk9PVE5PVEVTX0NPTlRBSU5FUl9DTEFTUyIsIkZPT1ROT1RFU19DTE9TRV9CVVRUT05fQ0xBU1MiLCJGT09UTk9URV9GT1JDRV9TSE9XIiwiVFRTX0lEX1BSRVZJT1VTIiwiVFRTX0lEX05FWFQiLCJUVFNfSURfU0xJREVSIiwiVFRTX0lEX0FDVElWRV9XT1JEIiwiVFRTX0lEX0NPTlRBSU5FUiIsIlRUU19JRF9JTkZPIiwiVFRTX05BVl9CVVRUT05fQ0xBU1MiLCJUVFNfSURfU1BFQUtJTkdfRE9DX0VMRU1FTlQiLCJUVFNfQ0xBU1NfSU5KRUNURURfU1BBTiIsIlRUU19DTEFTU19JTkpFQ1RFRF9TVUJTUEFOIiwiVFRTX0lEX0lOSkVDVEVEX1BBUkVOVCIsIklEX0hJR0hMSUdIVFNfQ09OVEFJTkVSIiwiSURfQU5OT1RBVElPTl9DT05UQUlORVIiLCJDTEFTU19ISUdITElHSFRfQ09OVEFJTkVSIiwiQ0xBU1NfQU5OT1RBVElPTl9DT05UQUlORVIiLCJDTEFTU19ISUdITElHSFRfQVJFQSIsIkNMQVNTX0FOTk9UQVRJT05fQVJFQSIsIkNMQVNTX0hJR0hMSUdIVF9CT1VORElOR19BUkVBIiwiQ0xBU1NfQU5OT1RBVElPTl9CT1VORElOR19BUkVBIiwiX2JsYWNrbGlzdElkQ2xhc3NGb3JDRkkiLCJDTEFTU19QQUdJTkFURUQiLCJJU19ERVYiLCJfaGlnaGxpZ2h0cyIsIl9oaWdobGlnaHRzQ29udGFpbmVyIiwiX2Fubm90YXRpb25Db250YWluZXIiLCJsYXN0TW91c2VEb3duWCIsImxhc3RNb3VzZURvd25ZIiwiYm9keUV2ZW50TGlzdGVuZXJzU2V0IiwiVVNFX1NWRyIsIkRFRkFVTFRfQkFDS0dST1VORF9DT0xPUl9PUEFDSVRZIiwiQUxUX0JBQ0tHUk9VTkRfQ09MT1JfT1BBQ0lUWSIsIkRFQlVHX1ZJU1VBTFMiLCJERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IiLCJibHVlIiwiZ3JlZW4iLCJyZWQiLCJBTk5PVEFUSU9OX1dJRFRIIiwicmVzZXRIaWdobGlnaHRCb3VuZGluZ1N0eWxlIiwiX3dpbiIsImhpZ2hsaWdodEJvdW5kaW5nIiwib3V0bGluZSIsInNldEhpZ2hsaWdodEFyZWFTdHlsZSIsIndpbiIsImhpZ2hsaWdodEFyZWFzIiwidXNlU1ZHIiwiaGlnaGxpZ2h0QXJlYSIsImlzU1ZHIiwibmFtZXNwYWNlVVJJIiwiU1ZHX1hNTF9OQU1FU1BBQ0UiLCJjb2xvciIsInJlc2V0SGlnaGxpZ2h0QXJlYVN0eWxlIiwicGFyZW50Tm9kZSIsImZpbmQiLCJoIiwicHJvY2Vzc1RvdWNoRXZlbnQiLCJldiIsInNjcm9sbEVsZW1lbnQiLCJnZXRTY3JvbGxpbmdFbGVtZW50IiwiY2hhbmdlZFRvdWNoZXMiLCJwYWdpbmF0ZWQiLCJpc1BhZ2luYXRlZCIsImJvZHlSZWN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiZm91bmRIaWdobGlnaHQiLCJmb3VuZEVsZW1lbnQiLCJmb3VuZFJlY3QiLCJoaWdobGlnaHRQYXJlbnQiLCJoaXQiLCJoaWdobGlnaHRGcmFnbWVudHMiLCJoaWdobGlnaHRGcmFnbWVudCIsIndpdGhSZWN0IiwiaGlnaGxpZ2h0Qm91bmRpbmdzIiwiYWxsSGlnaGxpZ2h0QXJlYXMiLCJmb3VuZEVsZW1lbnRIaWdobGlnaHRBcmVhcyIsImZvdW5kRWxlbWVudEhpZ2hsaWdodEJvdW5kaW5nIiwiYWxsSGlnaGxpZ2h0Qm91bmRpbmdzIiwic2V0SGlnaGxpZ2h0Qm91bmRpbmdTdHlsZSIsInNjcmVlbldpZHRoIiwib3V0ZXJXaWR0aCIsInNjcmVlbkhlaWdodCIsIm91dGVySGVpZ2h0IiwicGF5bG9hZCIsInByb2Nlc3MiLCJlbGVjdHJvbl8xIiwiaXBjUmVuZGVyZXIiLCJzZW5kVG9Ib3N0IiwiUjJfRVZFTlRfSElHSExJR0hUX0NMSUNLIiwid2Via2l0VVJMIiwiY29uc29sZSIsImluY2x1ZGVzIiwiaGlnaGxpZ2h0QW5ub3RhdGlvbk1hcmtBY3RpdmF0ZWQiLCJ3ZWJraXQiLCJtZXNzYWdlSGFuZGxlcnMiLCJwb3N0TWVzc2FnZSIsImhpZ2hsaWdodEFjdGl2YXRlZCIsInByb2Nlc3NNb3VzZUV2ZW50IiwidG91Y2hlZFBvc2l0aW9uIiwidG9QcmVzZXJ2ZSIsInRvQ2hlY2siLCJjaGVja092ZXJsYXBzIiwic3RpbGxPdmVybGFwaW5nUmVjdHMiLCJoYXMxIiwiaGFzMiIsInhPdmVybGFwIiwiZ2V0UmVjdE92ZXJsYXBYIiwieU92ZXJsYXAiLCJnZXRSZWN0T3ZlcmxhcFkiLCJyYW5nZUNsaWVudFJlY3RzIiwiZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXBfIiwiY2xhc3NMaXN0IiwiZW5zdXJlQ29udGFpbmVyIiwiYW5ub3RhdGlvbkZsYWciLCJ0b3VjaEVuZCIsImhpZGVBbGxoaWdobGlnaHRzIiwiZGVzdHJveUFsbGhpZ2hsaWdodHMiLCJkZXN0cm95SGlnaGxpZ2h0IiwiX2RvY3VtZW50IiwiaGlnaGxpZ2h0Q29udGFpbmVyIiwiaXNDZmlUZXh0Tm9kZSIsImdldENoaWxkVGV4dE5vZGVDZmlJbmRleCIsImZvdW5kIiwidGV4dE5vZGVJbmRleCIsInByZXZpb3VzV2FzRWxlbWVudCIsImNoaWxkTm9kZSIsImlzVGV4dCIsImdldENvbW1vbkFuY2VzdG9yRWxlbWVudCIsIm5vZGUxIiwibm9kZTIiLCJub2RlMUVsZW1lbnRBbmNlc3RvckNoYWluIiwibm9kZTJFbGVtZW50QW5jZXN0b3JDaGFpbiIsImNvbW1vbkFuY2VzdG9yIiwibm9kZTFFbGVtZW50QW5jZXN0b3IiLCJub2RlMkVsZW1lbnRBbmNlc3RvciIsImZ1bGxRdWFsaWZpZWRTZWxlY3RvciIsImxvd2VyQ2FzZU5hbWUiLCJsb2NhbE5hbWUiLCJjc3NQYXRoIiwiZ2V0Q3VycmVudFNlbGVjdGlvbkluZm8iLCJzZWxlY3Rpb24iLCJyYXdUZXh0IiwidG9TdHJpbmciLCJjbGVhblRleHQiLCJyZXBsYWNlIiwiYW5jaG9yTm9kZSIsImZvY3VzTm9kZSIsInJhbmdlQ291bnQiLCJnZXRSYW5nZUF0IiwiY3JlYXRlT3JkZXJlZFJhbmdlIiwiYW5jaG9yT2Zmc2V0IiwiZm9jdXNPZmZzZXQiLCJjb2xsYXBzZWQiLCJyYW5nZUluZm8iLCJjb252ZXJ0UmFuZ2UiLCJjb21wdXRlQ0ZJIiwicmVzdG9yZWRSYW5nZSIsImNvbnZlcnRSYW5nZUluZm8iLCJkdW1wRGVidWciLCJyYW5nZUluZm8yTG9jYXRpb24iLCJjaGVja0JsYWNrbGlzdGVkIiwiYmxhY2tsaXN0ZWRJZCIsImJsYWNrbGlzdGVkQ2xhc3MiLCJvcHRpbWl6ZWQiLCJzdGVwcyIsImNvbnRleHROb2RlIiwic3RlcCIsIl9jc3NQYXRoU3RlcCIsImlzVGFyZ2V0Tm9kZSIsInByZWZpeGVkRWxlbWVudENsYXNzTmFtZXMiLCJuZCIsImNsYXNzQXR0cmlidXRlIiwic3BsaXQiLCJCb29sZWFuIiwibm0iLCJpZFNlbGVjdG9yIiwiaWRkIiwiZXNjYXBlSWRlbnRpZmllcklmTmVlZGVkIiwiaWRlbnQiLCJpc0NTU0lkZW50aWZpZXIiLCJzaG91bGRFc2NhcGVGaXJzdCIsInRlc3QiLCJsYXN0SW5kZXgiLCJjIiwiaWkiLCJpc0NTU0lkZW50Q2hhciIsImVzY2FwZUFzY2lpQ2hhciIsImlzTGFzdCIsInRvSGV4Qnl0ZSIsImhleEJ5dGUiLCJjaGFyQ29kZUF0IiwiRE9DVU1FTlRfTk9ERSIsInByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5XyIsInByZWZpeGVkT3duQ2xhc3NOYW1lc0FycmF5IiwiYXJySXRlbSIsIm5lZWRzQ2xhc3NOYW1lcyIsIm5lZWRzTnRoQ2hpbGQiLCJvd25JbmRleCIsImVsZW1lbnRJbmRleCIsInNpYmxpbmdzIiwic2libGluZ05hbWUiLCJvd25DbGFzc05hbWVzIiwib3duQ2xhc3NOYW1lQ291bnQiLCJzaWJsaW5nQ2xhc3NOYW1lc0FycmF5XyIsInNpYmxpbmdDbGFzc05hbWVzQXJyYXkiLCJzaWJsaW5nQ2xhc3MiLCJpbmQiLCJyZXN1bHQiLCJwcmVmaXhlZE5hbWUiLCJzdWJzdHIiLCJjZmkiLCJjdXJyZW50RWxlbWVudCIsImJsYWNrbGlzdGVkIiwiY3VycmVudEVsZW1lbnRQYXJlbnRDaGlsZHJlbiIsImN1cnJlbnRFbGVtZW50SW5kZXgiLCJjZmlJbmRleCIsIl9jcmVhdGVIaWdobGlnaHQiLCJwb2ludGVySW50ZXJhY3Rpb24iLCJsb2NhdGlvbjJSYW5nZUluZm8iLCJ1bmlxdWVTdHIiLCJzdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvciIsInN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IiwiZW5kQ29udGFpbmVyRWxlbWVudENzc1NlbGVjdG9yIiwiZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4IiwiaGFzaCIsInJlcXVpcmUiLCJzaGEyNTZIZXgiLCJzaGEyNTYiLCJkaWdlc3QiLCJjcmVhdGVIaWdobGlnaHREb20iLCJjcmVhdGVIaWdobGlnaHQiLCJzZWxlY3Rpb25JbmZvIiwiY3JlYXRlQW5ub3RhdGlvbiIsInNjYWxlIiwiUkVBRElVTTIiLCJmeGxWaWV3cG9ydFNjYWxlIiwiaGlnaGxpZ2h0c0NvbnRhaW5lciIsImRyYXdVbmRlcmxpbmUiLCJkcmF3U3RyaWtlVGhyb3VnaCIsImhpZ2hsaWdodEFyZWFTVkdEb2NGcmFnIiwicm91bmRlZENvcm5lciIsInVuZGVybGluZVRoaWNrbmVzcyIsInN0cmlrZVRocm91Z2hMaW5lVGhpY2tuZXNzIiwiZXh0cmEiLCJyYW5nZUFubm90YXRpb25Cb3VuZGluZ0NsaWVudFJlY3QiLCJmcmFtZUZvckhpZ2hsaWdodEFubm90YXRpb25NYXJrV2l0aElEIiwiYW5ub3RhdGlvbk9mZnNldCIsImJvcmRlclRoaWNrbmVzcyIsImNyZWF0ZURvY3VtZW50RnJhZ21lbnQiLCJoaWdobGlnaHRBcmVhU1ZHUmVjdCIsImNyZWF0ZUVsZW1lbnROUyIsImhpZ2hsaWdodEFyZWFTVkdMaW5lIiwibGluZU9mZnNldCIsInJnYiIsInJhbmRvbSIsInIiLCJnIiwiaGlnaGxpZ2h0QXJlYUxpbmUiLCJoaWdobGlnaHRBcmVhU1ZHIiwib3ZlcmZsb3ciLCJyYW5nZUJvdW5kaW5nQ2xpZW50UmVjdCIsInN0YXJ0Tm9kZSIsImVuZE5vZGUiLCJyYW5nZVJldmVyc2UiLCJjb21wdXRlRWxlbWVudENGSSIsInN0YXJ0SXNFbGVtZW50Iiwic3RhcnRDb250YWluZXJFbGVtZW50IiwiZW5kSXNFbGVtZW50IiwiZW5kQ29udGFpbmVyRWxlbWVudCIsImNvbW1vbkVsZW1lbnRBbmNlc3RvciIsImNvbW1vbkFuY2VzdG9yQ29udGFpbmVyIiwicmFuZ2VDb21tb25BbmNlc3RvckVsZW1lbnQiLCJyb290RWxlbWVudENmaSIsInN0YXJ0RWxlbWVudENmaSIsImVuZEVsZW1lbnRDZmkiLCJzdGFydEVsZW1lbnRPclRleHRDZmkiLCJzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleEZvckNmaSIsImNmaVRleHROb2RlSW5kZXgiLCJjZmlJbmRleE9mTGFzdEVsZW1lbnQiLCJjaGlsZEVsZW1lbnRDb3VudCIsImxhc3RDaGlsZE5vZGUiLCJlbmRFbGVtZW50T3JUZXh0Q2ZpIiwiZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4Rm9yQ2ZpIiwic3RhcnRFbGVtZW50IiwiZW5kRWxlbWVudCIsImZyYW1lRm9ySGlnaGxpZ2h0V2l0aElEIiwidG9wQ2xpZW50UmVjdCIsIm1heEhlaWdodCIsIm5ld1RvcCIsImJvdW5kaW5nQXJlYXMiLCJnZXRFbGVtZW50c0J5Q2xhc3NOYW1lIiwibGVuIiwiYm91bmRpbmdBcmVhIiwiaGlnaGxpZ2h0V2l0aElEIiwicGFydGlhbENmaSIsImRvbVJhbmdlIiwibG9jYXRpb24iLCJyZWN0YW5nbGVGb3JIaWdobGlnaHRXaXRoSUQiLCJnZXRTZWxlY3Rpb25SZWN0Iiwic2VsIiwiaGFuZGxlQm91bmRzIiwic2V0U2Nyb2xsTW9kZSIsImZsYWciLCJtYXRjaEFsbCIsInNoaW0iLCJpc1NlbGVjdGluZyIsIm9uU2VsZWN0aW9uRW5kIiwib25TZWxlY3Rpb25TdGFydCIsImdldEN1cnJlbnRTZWxlY3Rpb24iLCJnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCIsImNsZWFuSGlnaGxpZ2h0Iiwic25pcHBldExlbmd0aCIsImZpcnN0V29yZFN0YXJ0IiwibGFzdFdvcmRFbmQiLCJwb3AiLCJyZWdpc3RlckRlY29yYXRpb25UZW1wbGF0ZXMiLCJpc1JlZmxvd2FibGUiLCJoZWFkIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6960\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},3715:function(__unused_webpack_module,exports,__webpack_require__){eval("var hash = exports;\n\nhash.utils = __webpack_require__(6436);\nhash.common = __webpack_require__(5772);\nhash.sha = __webpack_require__(9041);\nhash.ripemd = __webpack_require__(2949);\nhash.hmac = __webpack_require__(2344);\n\n// Proxy hash functions to the main object\nhash.sha1 = hash.sha.sha1;\nhash.sha256 = hash.sha.sha256;\nhash.sha224 = hash.sha.sha224;\nhash.sha384 = hash.sha.sha384;\nhash.sha512 = hash.sha.sha512;\nhash.ripemd160 = hash.ripemd.ripemd160;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcxNS5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQSxhQUFhLG1CQUFPLENBQUMsSUFBYztBQUNuQyxjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBWTtBQUMvQixjQUFjLG1CQUFPLENBQUMsSUFBZTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsSUFBYTs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanM/N2Q5MiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3715\n")},5772:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction BlockHash() {\n this.pending = null;\n this.pendingTotal = 0;\n this.blockSize = this.constructor.blockSize;\n this.outSize = this.constructor.outSize;\n this.hmacStrength = this.constructor.hmacStrength;\n this.padLength = this.constructor.padLength / 8;\n this.endian = 'big';\n\n this._delta8 = this.blockSize / 8;\n this._delta32 = this.blockSize / 32;\n}\nexports.BlockHash = BlockHash;\n\nBlockHash.prototype.update = function update(msg, enc) {\n // Convert message to array, pad it, and join into 32bit blocks\n msg = utils.toArray(msg, enc);\n if (!this.pending)\n this.pending = msg;\n else\n this.pending = this.pending.concat(msg);\n this.pendingTotal += msg.length;\n\n // Enough data, try updating\n if (this.pending.length >= this._delta8) {\n msg = this.pending;\n\n // Process pending data in blocks\n var r = msg.length % this._delta8;\n this.pending = msg.slice(msg.length - r, msg.length);\n if (this.pending.length === 0)\n this.pending = null;\n\n msg = utils.join32(msg, 0, msg.length - r, this.endian);\n for (var i = 0; i < msg.length; i += this._delta32)\n this._update(msg, i, i + this._delta32);\n }\n\n return this;\n};\n\nBlockHash.prototype.digest = function digest(enc) {\n this.update(this._pad());\n assert(this.pending === null);\n\n return this._digest(enc);\n};\n\nBlockHash.prototype._pad = function pad() {\n var len = this.pendingTotal;\n var bytes = this._delta8;\n var k = bytes - ((len + this.padLength) % bytes);\n var res = new Array(k + this.padLength);\n res[0] = 0x80;\n for (var i = 1; i < k; i++)\n res[i] = 0;\n\n // Append length\n len <<= 3;\n if (this.endian === 'big') {\n for (var t = 8; t < this.padLength; t++)\n res[i++] = 0;\n\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = len & 0xff;\n } else {\n res[i++] = len & 0xff;\n res[i++] = (len >>> 8) & 0xff;\n res[i++] = (len >>> 16) & 0xff;\n res[i++] = (len >>> 24) & 0xff;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n res[i++] = 0;\n\n for (t = 8; t < this.padLength; t++)\n res[i++] = 0;\n }\n\n return res;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTc3Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLE9BQU87QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzP2VkYzkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5772\n")},2344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar assert = __webpack_require__(9746);\n\nfunction Hmac(hash, key, enc) {\n if (!(this instanceof Hmac))\n return new Hmac(hash, key, enc);\n this.Hash = hash;\n this.blockSize = hash.blockSize / 8;\n this.outSize = hash.outSize / 8;\n this.inner = null;\n this.outer = null;\n\n this._init(utils.toArray(key, enc));\n}\nmodule.exports = Hmac;\n\nHmac.prototype._init = function init(key) {\n // Shorten key, if needed\n if (key.length > this.blockSize)\n key = new this.Hash().update(key).digest();\n assert(key.length <= this.blockSize);\n\n // Add padding to key\n for (var i = key.length; i < this.blockSize; i++)\n key.push(0);\n\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x36;\n this.inner = new this.Hash().update(key);\n\n // 0x36 ^ 0x5c = 0x6a\n for (i = 0; i < key.length; i++)\n key[i] ^= 0x6a;\n this.outer = new this.Hash().update(key);\n};\n\nHmac.prototype.update = function update(msg, enc) {\n this.inner.update(msg, enc);\n return this;\n};\n\nHmac.prototype.digest = function digest(enc) {\n this.outer.update(this.inner.digest());\n return this.outer.digest(enc);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsb0JBQW9CO0FBQy9DOztBQUVBLGNBQWMsZ0JBQWdCO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvaG1hYy5qcz8yMTM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gSG1hYyhoYXNoLCBrZXksIGVuYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hYykpXG4gICAgcmV0dXJuIG5ldyBIbWFjKGhhc2gsIGtleSwgZW5jKTtcbiAgdGhpcy5IYXNoID0gaGFzaDtcbiAgdGhpcy5ibG9ja1NpemUgPSBoYXNoLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMub3V0U2l6ZSA9IGhhc2gub3V0U2l6ZSAvIDg7XG4gIHRoaXMuaW5uZXIgPSBudWxsO1xuICB0aGlzLm91dGVyID0gbnVsbDtcblxuICB0aGlzLl9pbml0KHV0aWxzLnRvQXJyYXkoa2V5LCBlbmMpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hYztcblxuSG1hYy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGtleSkge1xuICAvLyBTaG9ydGVuIGtleSwgaWYgbmVlZGVkXG4gIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpXG4gICAga2V5ID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xuICBhc3NlcnQoa2V5Lmxlbmd0aCA8PSB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gQWRkIHBhZGRpbmcgdG8ga2V5XG4gIGZvciAodmFyIGkgPSBrZXkubGVuZ3RoOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKylcbiAgICBrZXkucHVzaCgwKTtcblxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDM2O1xuICB0aGlzLmlubmVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xuXG4gIC8vIDB4MzYgXiAweDVjID0gMHg2YVxuICBmb3IgKGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2344\n")},2949:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_3 = utils.sum32_3;\nvar sum32_4 = utils.sum32_4;\nvar BlockHash = common.BlockHash;\n\nfunction RIPEMD160() {\n if (!(this instanceof RIPEMD160))\n return new RIPEMD160();\n\n BlockHash.call(this);\n\n this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];\n this.endian = 'little';\n}\nutils.inherits(RIPEMD160, BlockHash);\nexports.ripemd160 = RIPEMD160;\n\nRIPEMD160.blockSize = 512;\nRIPEMD160.outSize = 160;\nRIPEMD160.hmacStrength = 192;\nRIPEMD160.padLength = 64;\n\nRIPEMD160.prototype._update = function update(msg, start) {\n var A = this.h[0];\n var B = this.h[1];\n var C = this.h[2];\n var D = this.h[3];\n var E = this.h[4];\n var Ah = A;\n var Bh = B;\n var Ch = C;\n var Dh = D;\n var Eh = E;\n for (var j = 0; j < 80; j++) {\n var T = sum32(\n rotl32(\n sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),\n s[j]),\n E);\n A = E;\n E = D;\n D = rotl32(C, 10);\n C = B;\n B = T;\n T = sum32(\n rotl32(\n sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),\n sh[j]),\n Eh);\n Ah = Eh;\n Eh = Dh;\n Dh = rotl32(Ch, 10);\n Ch = Bh;\n Bh = T;\n }\n T = sum32_3(this.h[1], C, Dh);\n this.h[1] = sum32_3(this.h[2], D, Eh);\n this.h[2] = sum32_3(this.h[3], E, Ah);\n this.h[3] = sum32_3(this.h[4], A, Bh);\n this.h[4] = sum32_3(this.h[0], B, Ch);\n this.h[0] = T;\n};\n\nRIPEMD160.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'little');\n else\n return utils.split32(this.h, 'little');\n};\n\nfunction f(j, x, y, z) {\n if (j <= 15)\n return x ^ y ^ z;\n else if (j <= 31)\n return (x & y) | ((~x) & z);\n else if (j <= 47)\n return (x | (~y)) ^ z;\n else if (j <= 63)\n return (x & z) | (y & (~z));\n else\n return x ^ (y | (~z));\n}\n\nfunction K(j) {\n if (j <= 15)\n return 0x00000000;\n else if (j <= 31)\n return 0x5a827999;\n else if (j <= 47)\n return 0x6ed9eba1;\n else if (j <= 63)\n return 0x8f1bbcdc;\n else\n return 0xa953fd4e;\n}\n\nfunction Kh(j) {\n if (j <= 15)\n return 0x50a28be6;\n else if (j <= 31)\n return 0x5c4dd124;\n else if (j <= 47)\n return 0x6d703ef3;\n else if (j <= 63)\n return 0x7a6d76e9;\n else\n return 0x00000000;\n}\n\nvar r = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,\n 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,\n 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13\n];\n\nvar rh = [\n 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,\n 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,\n 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,\n 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,\n 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11\n];\n\nvar s = [\n 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,\n 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,\n 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,\n 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,\n 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6\n];\n\nvar sh = [\n 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,\n 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,\n 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,\n 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,\n 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11\n];\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBUztBQUM3QixhQUFhLG1CQUFPLENBQUMsSUFBVTs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzP2JiNDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2949\n")},9041:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nexports.sha1 = __webpack_require__(4761);\nexports.sha224 = __webpack_require__(799);\nexports.sha256 = __webpack_require__(9344);\nexports.sha384 = __webpack_require__(772);\nexports.sha512 = __webpack_require__(5900);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA0MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix3Q0FBaUM7QUFDakMseUNBQXFDO0FBQ3JDLDBDQUFxQztBQUNyQyx5Q0FBcUM7QUFDckMsMENBQXFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcz81OTE5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGEvMScpO1xuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYS8yMjQnKTtcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEvMjU2Jyk7XG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhLzM4NCcpO1xuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYS81MTInKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9041\n")},4761:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\n\nvar rotl32 = utils.rotl32;\nvar sum32 = utils.sum32;\nvar sum32_5 = utils.sum32_5;\nvar ft_1 = shaCommon.ft_1;\nvar BlockHash = common.BlockHash;\n\nvar sha1_K = [\n 0x5A827999, 0x6ED9EBA1,\n 0x8F1BBCDC, 0xCA62C1D6\n];\n\nfunction SHA1() {\n if (!(this instanceof SHA1))\n return new SHA1();\n\n BlockHash.call(this);\n this.h = [\n 0x67452301, 0xefcdab89, 0x98badcfe,\n 0x10325476, 0xc3d2e1f0 ];\n this.W = new Array(80);\n}\n\nutils.inherits(SHA1, BlockHash);\nmodule.exports = SHA1;\n\nSHA1.blockSize = 512;\nSHA1.outSize = 160;\nSHA1.hmacStrength = 80;\nSHA1.padLength = 64;\n\nSHA1.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n\n for(; i < W.length; i++)\n W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n\n for (i = 0; i < W.length; i++) {\n var s = ~~(i / 20);\n var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);\n e = d;\n d = c;\n c = rotl32(b, 30);\n b = a;\n a = t;\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n};\n\nSHA1.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc2MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVOztBQUVsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixRQUFRO0FBQzFCOztBQUVBLFFBQVEsY0FBYztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzEuanM/MTNlMiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGZ0XzEgPSBzaGFDb21tb24uZnRfMTtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMTtcblxuU0hBMS5ibG9ja1NpemUgPSA1MTI7XG5TSEExLm91dFNpemUgPSAxNjA7XG5TSEExLmhtYWNTdHJlbmd0aCA9IDgwO1xuU0hBMS5wYWRMZW5ndGggPSA2NDtcblxuU0hBMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuXG4gIGZvcig7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSByb3RsMzIoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSwgMSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4761\n")},799:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar SHA256 = __webpack_require__(9344);\n\nfunction SHA224() {\n if (!(this instanceof SHA224))\n return new SHA224();\n\n SHA256.call(this);\n this.h = [\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];\n}\nutils.inherits(SHA224, SHA256);\nmodule.exports = SHA224;\n\nSHA224.blockSize = 512;\nSHA224.outSize = 224;\nSHA224.hmacStrength = 192;\nSHA224.padLength = 64;\n\nSHA224.prototype._digest = function digest(enc) {\n // Just truncate output\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 7), 'big');\n else\n return utils.split32(this.h.slice(0, 7), 'big');\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVO0FBQzlCLGFBQWEsbUJBQU8sQ0FBQyxJQUFPOztBQUU1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzIyNC5qcz8wN2YyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBTSEEyNTYgPSByZXF1aXJlKCcuLzI1NicpO1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///799\n")},9344:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar shaCommon = __webpack_require__(7038);\nvar assert = __webpack_require__(9746);\n\nvar sum32 = utils.sum32;\nvar sum32_4 = utils.sum32_4;\nvar sum32_5 = utils.sum32_5;\nvar ch32 = shaCommon.ch32;\nvar maj32 = shaCommon.maj32;\nvar s0_256 = shaCommon.s0_256;\nvar s1_256 = shaCommon.s1_256;\nvar g0_256 = shaCommon.g0_256;\nvar g1_256 = shaCommon.g1_256;\n\nvar BlockHash = common.BlockHash;\n\nvar sha256_K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n];\n\nfunction SHA256() {\n if (!(this instanceof SHA256))\n return new SHA256();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n ];\n this.k = sha256_K;\n this.W = new Array(64);\n}\nutils.inherits(SHA256, BlockHash);\nmodule.exports = SHA256;\n\nSHA256.blockSize = 512;\nSHA256.outSize = 256;\nSHA256.hmacStrength = 192;\nSHA256.padLength = 64;\n\nSHA256.prototype._update = function _update(msg, start) {\n var W = this.W;\n\n for (var i = 0; i < 16; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i++)\n W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);\n\n var a = this.h[0];\n var b = this.h[1];\n var c = this.h[2];\n var d = this.h[3];\n var e = this.h[4];\n var f = this.h[5];\n var g = this.h[6];\n var h = this.h[7];\n\n assert(this.k.length === W.length);\n for (i = 0; i < W.length; i++) {\n var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);\n var T2 = sum32(s0_256(a), maj32(a, b, c));\n h = g;\n g = f;\n f = e;\n e = sum32(d, T1);\n d = c;\n c = b;\n b = a;\n a = sum32(T1, T2);\n }\n\n this.h[0] = sum32(this.h[0], a);\n this.h[1] = sum32(this.h[1], b);\n this.h[2] = sum32(this.h[2], c);\n this.h[3] = sum32(this.h[3], d);\n this.h[4] = sum32(this.h[4], e);\n this.h[5] = sum32(this.h[5], f);\n this.h[6] = sum32(this.h[6], g);\n this.h[7] = sum32(this.h[7], h);\n};\n\nSHA256.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFVO0FBQ2xDLGFBQWEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsUUFBUTtBQUMxQjtBQUNBLFNBQVMsY0FBYztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMjU2LmpzPzZlZWQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIHNoYUNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciBjaDMyID0gc2hhQ29tbW9uLmNoMzI7XG52YXIgbWFqMzIgPSBzaGFDb21tb24ubWFqMzI7XG52YXIgczBfMjU2ID0gc2hhQ29tbW9uLnMwXzI1NjtcbnZhciBzMV8yNTYgPSBzaGFDb21tb24uczFfMjU2O1xudmFyIGcwXzI1NiA9IHNoYUNvbW1vbi5nMF8yNTY7XG52YXIgZzFfMjU2ID0gc2hhQ29tbW9uLmcxXzI1NjtcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG4gIF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBUMSA9IHN1bTMyXzUoaCwgczFfMjU2KGUpLCBjaDMyKGUsIGYsIGcpLCB0aGlzLmtbaV0sIFdbaV0pO1xuICAgIHZhciBUMiA9IHN1bTMyKHMwXzI1NihhKSwgbWFqMzIoYSwgYiwgYykpO1xuICAgIGggPSBnO1xuICAgIGcgPSBmO1xuICAgIGYgPSBlO1xuICAgIGUgPSBzdW0zMihkLCBUMSk7XG4gICAgZCA9IGM7XG4gICAgYyA9IGI7XG4gICAgYiA9IGE7XG4gICAgYSA9IHN1bTMyKFQxLCBUMik7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xuICB0aGlzLmhbNV0gPSBzdW0zMih0aGlzLmhbNV0sIGYpO1xuICB0aGlzLmhbNl0gPSBzdW0zMih0aGlzLmhbNl0sIGcpO1xuICB0aGlzLmhbN10gPSBzdW0zMih0aGlzLmhbN10sIGgpO1xufTtcblxuU0hBMjU2LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9344\n")},772:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\n\nvar SHA512 = __webpack_require__(5900);\n\nfunction SHA384() {\n if (!(this instanceof SHA384))\n return new SHA384();\n\n SHA512.call(this);\n this.h = [\n 0xcbbb9d5d, 0xc1059ed8,\n 0x629a292a, 0x367cd507,\n 0x9159015a, 0x3070dd17,\n 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31,\n 0x8eb44a87, 0x68581511,\n 0xdb0c2e0d, 0x64f98fa7,\n 0x47b5481d, 0xbefa4fa4 ];\n}\nutils.inherits(SHA384, SHA512);\nmodule.exports = SHA384;\n\nSHA384.blockSize = 1024;\nSHA384.outSize = 384;\nSHA384.hmacStrength = 192;\nSHA384.padLength = 128;\n\nSHA384.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h.slice(0, 12), 'big');\n else\n return utils.split32(this.h.slice(0, 12), 'big');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcyLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxJQUFVOztBQUU5QixhQUFhLG1CQUFPLENBQUMsSUFBTzs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMzg0LmpzPzhiOTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi81MTInKTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///772\n")},5900:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar common = __webpack_require__(5772);\nvar assert = __webpack_require__(9746);\n\nvar rotr64_hi = utils.rotr64_hi;\nvar rotr64_lo = utils.rotr64_lo;\nvar shr64_hi = utils.shr64_hi;\nvar shr64_lo = utils.shr64_lo;\nvar sum64 = utils.sum64;\nvar sum64_hi = utils.sum64_hi;\nvar sum64_lo = utils.sum64_lo;\nvar sum64_4_hi = utils.sum64_4_hi;\nvar sum64_4_lo = utils.sum64_4_lo;\nvar sum64_5_hi = utils.sum64_5_hi;\nvar sum64_5_lo = utils.sum64_5_lo;\n\nvar BlockHash = common.BlockHash;\n\nvar sha512_K = [\n 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,\n 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,\n 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,\n 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,\n 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,\n 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,\n 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,\n 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,\n 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,\n 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,\n 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,\n 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,\n 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,\n 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,\n 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,\n 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,\n 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,\n 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,\n 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,\n 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,\n 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,\n 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,\n 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,\n 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,\n 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,\n 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,\n 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,\n 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,\n 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,\n 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,\n 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,\n 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,\n 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,\n 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,\n 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,\n 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,\n 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,\n 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,\n 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,\n 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817\n];\n\nfunction SHA512() {\n if (!(this instanceof SHA512))\n return new SHA512();\n\n BlockHash.call(this);\n this.h = [\n 0x6a09e667, 0xf3bcc908,\n 0xbb67ae85, 0x84caa73b,\n 0x3c6ef372, 0xfe94f82b,\n 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1,\n 0x9b05688c, 0x2b3e6c1f,\n 0x1f83d9ab, 0xfb41bd6b,\n 0x5be0cd19, 0x137e2179 ];\n this.k = sha512_K;\n this.W = new Array(160);\n}\nutils.inherits(SHA512, BlockHash);\nmodule.exports = SHA512;\n\nSHA512.blockSize = 1024;\nSHA512.outSize = 512;\nSHA512.hmacStrength = 192;\nSHA512.padLength = 128;\n\nSHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {\n var W = this.W;\n\n // 32 x 32bit words\n for (var i = 0; i < 32; i++)\n W[i] = msg[start + i];\n for (; i < W.length; i += 2) {\n var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2\n var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);\n var c1_hi = W[i - 14]; // i - 7\n var c1_lo = W[i - 13];\n var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15\n var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);\n var c3_hi = W[i - 32]; // i - 16\n var c3_lo = W[i - 31];\n\n W[i] = sum64_4_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n W[i + 1] = sum64_4_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo);\n }\n};\n\nSHA512.prototype._update = function _update(msg, start) {\n this._prepareBlock(msg, start);\n\n var W = this.W;\n\n var ah = this.h[0];\n var al = this.h[1];\n var bh = this.h[2];\n var bl = this.h[3];\n var ch = this.h[4];\n var cl = this.h[5];\n var dh = this.h[6];\n var dl = this.h[7];\n var eh = this.h[8];\n var el = this.h[9];\n var fh = this.h[10];\n var fl = this.h[11];\n var gh = this.h[12];\n var gl = this.h[13];\n var hh = this.h[14];\n var hl = this.h[15];\n\n assert(this.k.length === W.length);\n for (var i = 0; i < W.length; i += 2) {\n var c0_hi = hh;\n var c0_lo = hl;\n var c1_hi = s1_512_hi(eh, el);\n var c1_lo = s1_512_lo(eh, el);\n var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);\n var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);\n var c3_hi = this.k[i];\n var c3_lo = this.k[i + 1];\n var c4_hi = W[i];\n var c4_lo = W[i + 1];\n\n var T1_hi = sum64_5_hi(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n var T1_lo = sum64_5_lo(\n c0_hi, c0_lo,\n c1_hi, c1_lo,\n c2_hi, c2_lo,\n c3_hi, c3_lo,\n c4_hi, c4_lo);\n\n c0_hi = s0_512_hi(ah, al);\n c0_lo = s0_512_lo(ah, al);\n c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);\n c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);\n\n var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);\n var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);\n\n hh = gh;\n hl = gl;\n\n gh = fh;\n gl = fl;\n\n fh = eh;\n fl = el;\n\n eh = sum64_hi(dh, dl, T1_hi, T1_lo);\n el = sum64_lo(dl, dl, T1_hi, T1_lo);\n\n dh = ch;\n dl = cl;\n\n ch = bh;\n cl = bl;\n\n bh = ah;\n bl = al;\n\n ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);\n al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);\n }\n\n sum64(this.h, 0, ah, al);\n sum64(this.h, 2, bh, bl);\n sum64(this.h, 4, ch, cl);\n sum64(this.h, 6, dh, dl);\n sum64(this.h, 8, eh, el);\n sum64(this.h, 10, fh, fl);\n sum64(this.h, 12, gh, gl);\n sum64(this.h, 14, hh, hl);\n};\n\nSHA512.prototype._digest = function digest(enc) {\n if (enc === 'hex')\n return utils.toHex32(this.h, 'big');\n else\n return utils.split32(this.h, 'big');\n};\n\nfunction ch64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ ((~xh) & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction ch64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ ((~xl) & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_hi(xh, xl, yh, yl, zh) {\n var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction maj64_lo(xh, xl, yh, yl, zh, zl) {\n var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 28);\n var c1_hi = rotr64_hi(xl, xh, 2); // 34\n var c2_hi = rotr64_hi(xl, xh, 7); // 39\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 28);\n var c1_lo = rotr64_lo(xl, xh, 2); // 34\n var c2_lo = rotr64_lo(xl, xh, 7); // 39\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 14);\n var c1_hi = rotr64_hi(xh, xl, 18);\n var c2_hi = rotr64_hi(xl, xh, 9); // 41\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction s1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 14);\n var c1_lo = rotr64_lo(xh, xl, 18);\n var c2_lo = rotr64_lo(xl, xh, 9); // 41\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 1);\n var c1_hi = rotr64_hi(xh, xl, 8);\n var c2_hi = shr64_hi(xh, xl, 7);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g0_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 1);\n var c1_lo = rotr64_lo(xh, xl, 8);\n var c2_lo = shr64_lo(xh, xl, 7);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_hi(xh, xl) {\n var c0_hi = rotr64_hi(xh, xl, 19);\n var c1_hi = rotr64_hi(xl, xh, 29); // 61\n var c2_hi = shr64_hi(xh, xl, 6);\n\n var r = c0_hi ^ c1_hi ^ c2_hi;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n\nfunction g1_512_lo(xh, xl) {\n var c0_lo = rotr64_lo(xh, xl, 19);\n var c1_lo = rotr64_lo(xl, xh, 29); // 61\n var c2_lo = shr64_lo(xh, xl, 6);\n\n var r = c0_lo ^ c1_lo ^ c2_lo;\n if (r < 0)\n r += 0x100000000;\n return r;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTkwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5QixhQUFhLG1CQUFPLENBQUMsSUFBVztBQUNoQyxhQUFhLG1CQUFPLENBQUMsSUFBcUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixRQUFRO0FBQzFCO0FBQ0EsU0FBUyxjQUFjO0FBQ3ZCLGdEQUFnRDtBQUNoRDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckMscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzUxMi5qcz9iNTI1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbnZhciByb3RyNjRfaGkgPSB1dGlscy5yb3RyNjRfaGk7XG52YXIgcm90cjY0X2xvID0gdXRpbHMucm90cjY0X2xvO1xudmFyIHNocjY0X2hpID0gdXRpbHMuc2hyNjRfaGk7XG52YXIgc2hyNjRfbG8gPSB1dGlscy5zaHI2NF9sbztcbnZhciBzdW02NCA9IHV0aWxzLnN1bTY0O1xudmFyIHN1bTY0X2hpID0gdXRpbHMuc3VtNjRfaGk7XG52YXIgc3VtNjRfbG8gPSB1dGlscy5zdW02NF9sbztcbnZhciBzdW02NF80X2hpID0gdXRpbHMuc3VtNjRfNF9oaTtcbnZhciBzdW02NF80X2xvID0gdXRpbHMuc3VtNjRfNF9sbztcbnZhciBzdW02NF81X2hpID0gdXRpbHMuc3VtNjRfNV9oaTtcbnZhciBzdW02NF81X2xvID0gdXRpbHMuc3VtNjRfNV9sbztcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCxcbiAgICAweGJiNjdhZTg1LCAweDg0Y2FhNzNiLFxuICAgIDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIsXG4gICAgMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSxcbiAgICAweDUxMGU1MjdmLCAweGFkZTY4MmQxLFxuICAgIDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYsXG4gICAgMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YixcbiAgICAweDViZTBjZDE5LCAweDEzN2UyMTc5IF07XG4gIHRoaXMuayA9IHNoYTUxMl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoMTYwKTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTUxMiwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBNTEyO1xuXG5TSEE1MTIuYmxvY2tTaXplID0gMTAyNDtcblNIQTUxMi5vdXRTaXplID0gNTEyO1xuU0hBNTEyLmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTUxMi5wYWRMZW5ndGggPSAxMjg7XG5cblNIQTUxMi5wcm90b3R5cGUuX3ByZXBhcmVCbG9jayA9IGZ1bmN0aW9uIF9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICAvLyAzMiB4IDMyYml0IHdvcmRzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGcxXzUxMl9oaShXW2kgLSA0XSwgV1tpIC0gM10pOyAgLy8gaSAtIDJcbiAgICB2YXIgYzBfbG8gPSBnMV81MTJfbG8oV1tpIC0gNF0sIFdbaSAtIDNdKTtcbiAgICB2YXIgYzFfaGkgPSBXW2kgLSAxNF07ICAvLyBpIC0gN1xuICAgIHZhciBjMV9sbyA9IFdbaSAtIDEzXTtcbiAgICB2YXIgYzJfaGkgPSBnMF81MTJfaGkoV1tpIC0gMzBdLCBXW2kgLSAyOV0pOyAgLy8gaSAtIDE1XG4gICAgdmFyIGMyX2xvID0gZzBfNTEyX2xvKFdbaSAtIDMwXSwgV1tpIC0gMjldKTtcbiAgICB2YXIgYzNfaGkgPSBXW2kgLSAzMl07ICAvLyBpIC0gMTZcbiAgICB2YXIgYzNfbG8gPSBXW2kgLSAzMV07XG5cbiAgICBXW2ldID0gc3VtNjRfNF9oaShcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyk7XG4gICAgV1tpICsgMV0gPSBzdW02NF80X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcbiAgICB2YXIgVDFfbG8gPSBzdW02NF81X2xvKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgYzRfaGksIGM0X2xvKTtcblxuICAgIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgYzBfbG8gPSBzMF81MTJfbG8oYWgsIGFsKTtcbiAgICBjMV9oaSA9IG1hajY0X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wpO1xuICAgIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gY2g2NF9oaSh4aCwgeGwsIHloLCB5bCwgemgpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICh4aCAmIHpoKSBeICh5aCAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKHhsICYgemwpIF4gKHlsICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDEpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDEpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5900\n")},7038:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar utils = __webpack_require__(6436);\nvar rotr32 = utils.rotr32;\n\nfunction ft_1(s, x, y, z) {\n if (s === 0)\n return ch32(x, y, z);\n if (s === 1 || s === 3)\n return p32(x, y, z);\n if (s === 2)\n return maj32(x, y, z);\n}\nexports.ft_1 = ft_1;\n\nfunction ch32(x, y, z) {\n return (x & y) ^ ((~x) & z);\n}\nexports.ch32 = ch32;\n\nfunction maj32(x, y, z) {\n return (x & y) ^ (x & z) ^ (y & z);\n}\nexports.maj32 = maj32;\n\nfunction p32(x, y, z) {\n return x ^ y ^ z;\n}\nexports.p32 = p32;\n\nfunction s0_256(x) {\n return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);\n}\nexports.s0_256 = s0_256;\n\nfunction s1_256(x) {\n return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);\n}\nexports.s1_256 = s1_256;\n\nfunction g0_256(x) {\n return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);\n}\nexports.g0_256 = g0_256;\n\nfunction g1_256(x) {\n return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);\n}\nexports.g1_256 = g1_256;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAzOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsSUFBVTtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTs7QUFFWjtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0EsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxjQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS9jb21tb24uanM/YWE1NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgcm90cjMyID0gdXRpbHMucm90cjMyO1xuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuZXhwb3J0cy5mdF8xID0gZnRfMTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cbmV4cG9ydHMuY2gzMiA9IGNoMzI7XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cbmV4cG9ydHMubWFqMzIgPSBtYWozMjtcblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cbmV4cG9ydHMucDMyID0gcDMyO1xuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5leHBvcnRzLnMwXzI1NiA9IHMwXzI1NjtcblxuZnVuY3Rpb24gczFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA2KSBeIHJvdHIzMih4LCAxMSkgXiByb3RyMzIoeCwgMjUpO1xufVxuZXhwb3J0cy5zMV8yNTYgPSBzMV8yNTY7XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuZXhwb3J0cy5nMF8yNTYgPSBnMF8yNTY7XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5leHBvcnRzLmcxXzI1NiA9IGcxXzI1NjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7038\n")},6436:function(__unused_webpack_module,exports,__webpack_require__){"use strict";eval("\n\nvar assert = __webpack_require__(9746);\nvar inherits = __webpack_require__(5717);\n\nexports.inherits = inherits;\n\nfunction isSurrogatePair(msg, i) {\n if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {\n return false;\n }\n if (i < 0 || i + 1 >= msg.length) {\n return false;\n }\n return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;\n}\n\nfunction toArray(msg, enc) {\n if (Array.isArray(msg))\n return msg.slice();\n if (!msg)\n return [];\n var res = [];\n if (typeof msg === 'string') {\n if (!enc) {\n // Inspired by stringToUtf8ByteArray() in closure-library by Google\n // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143\n // Apache License 2.0\n // https://github.com/google/closure-library/blob/master/LICENSE\n var p = 0;\n for (var i = 0; i < msg.length; i++) {\n var c = msg.charCodeAt(i);\n if (c < 128) {\n res[p++] = c;\n } else if (c < 2048) {\n res[p++] = (c >> 6) | 192;\n res[p++] = (c & 63) | 128;\n } else if (isSurrogatePair(msg, i)) {\n c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);\n res[p++] = (c >> 18) | 240;\n res[p++] = ((c >> 12) & 63) | 128;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n } else {\n res[p++] = (c >> 12) | 224;\n res[p++] = ((c >> 6) & 63) | 128;\n res[p++] = (c & 63) | 128;\n }\n }\n } else if (enc === 'hex') {\n msg = msg.replace(/[^a-z0-9]+/ig, '');\n if (msg.length % 2 !== 0)\n msg = '0' + msg;\n for (i = 0; i < msg.length; i += 2)\n res.push(parseInt(msg[i] + msg[i + 1], 16));\n }\n } else {\n for (i = 0; i < msg.length; i++)\n res[i] = msg[i] | 0;\n }\n return res;\n}\nexports.toArray = toArray;\n\nfunction toHex(msg) {\n var res = '';\n for (var i = 0; i < msg.length; i++)\n res += zero2(msg[i].toString(16));\n return res;\n}\nexports.toHex = toHex;\n\nfunction htonl(w) {\n var res = (w >>> 24) |\n ((w >>> 8) & 0xff00) |\n ((w << 8) & 0xff0000) |\n ((w & 0xff) << 24);\n return res >>> 0;\n}\nexports.htonl = htonl;\n\nfunction toHex32(msg, endian) {\n var res = '';\n for (var i = 0; i < msg.length; i++) {\n var w = msg[i];\n if (endian === 'little')\n w = htonl(w);\n res += zero8(w.toString(16));\n }\n return res;\n}\nexports.toHex32 = toHex32;\n\nfunction zero2(word) {\n if (word.length === 1)\n return '0' + word;\n else\n return word;\n}\nexports.zero2 = zero2;\n\nfunction zero8(word) {\n if (word.length === 7)\n return '0' + word;\n else if (word.length === 6)\n return '00' + word;\n else if (word.length === 5)\n return '000' + word;\n else if (word.length === 4)\n return '0000' + word;\n else if (word.length === 3)\n return '00000' + word;\n else if (word.length === 2)\n return '000000' + word;\n else if (word.length === 1)\n return '0000000' + word;\n else\n return word;\n}\nexports.zero8 = zero8;\n\nfunction join32(msg, start, end, endian) {\n var len = end - start;\n assert(len % 4 === 0);\n var res = new Array(len / 4);\n for (var i = 0, k = start; i < res.length; i++, k += 4) {\n var w;\n if (endian === 'big')\n w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];\n else\n w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];\n res[i] = w >>> 0;\n }\n return res;\n}\nexports.join32 = join32;\n\nfunction split32(msg, endian) {\n var res = new Array(msg.length * 4);\n for (var i = 0, k = 0; i < msg.length; i++, k += 4) {\n var m = msg[i];\n if (endian === 'big') {\n res[k] = m >>> 24;\n res[k + 1] = (m >>> 16) & 0xff;\n res[k + 2] = (m >>> 8) & 0xff;\n res[k + 3] = m & 0xff;\n } else {\n res[k + 3] = m >>> 24;\n res[k + 2] = (m >>> 16) & 0xff;\n res[k + 1] = (m >>> 8) & 0xff;\n res[k] = m & 0xff;\n }\n }\n return res;\n}\nexports.split32 = split32;\n\nfunction rotr32(w, b) {\n return (w >>> b) | (w << (32 - b));\n}\nexports.rotr32 = rotr32;\n\nfunction rotl32(w, b) {\n return (w << b) | (w >>> (32 - b));\n}\nexports.rotl32 = rotl32;\n\nfunction sum32(a, b) {\n return (a + b) >>> 0;\n}\nexports.sum32 = sum32;\n\nfunction sum32_3(a, b, c) {\n return (a + b + c) >>> 0;\n}\nexports.sum32_3 = sum32_3;\n\nfunction sum32_4(a, b, c, d) {\n return (a + b + c + d) >>> 0;\n}\nexports.sum32_4 = sum32_4;\n\nfunction sum32_5(a, b, c, d, e) {\n return (a + b + c + d + e) >>> 0;\n}\nexports.sum32_5 = sum32_5;\n\nfunction sum64(buf, pos, ah, al) {\n var bh = buf[pos];\n var bl = buf[pos + 1];\n\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n buf[pos] = hi >>> 0;\n buf[pos + 1] = lo;\n}\nexports.sum64 = sum64;\n\nfunction sum64_hi(ah, al, bh, bl) {\n var lo = (al + bl) >>> 0;\n var hi = (lo < al ? 1 : 0) + ah + bh;\n return hi >>> 0;\n}\nexports.sum64_hi = sum64_hi;\n\nfunction sum64_lo(ah, al, bh, bl) {\n var lo = al + bl;\n return lo >>> 0;\n}\nexports.sum64_lo = sum64_lo;\n\nfunction sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n\n var hi = ah + bh + ch + dh + carry;\n return hi >>> 0;\n}\nexports.sum64_4_hi = sum64_4_hi;\n\nfunction sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {\n var lo = al + bl + cl + dl;\n return lo >>> 0;\n}\nexports.sum64_4_lo = sum64_4_lo;\n\nfunction sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var carry = 0;\n var lo = al;\n lo = (lo + bl) >>> 0;\n carry += lo < al ? 1 : 0;\n lo = (lo + cl) >>> 0;\n carry += lo < cl ? 1 : 0;\n lo = (lo + dl) >>> 0;\n carry += lo < dl ? 1 : 0;\n lo = (lo + el) >>> 0;\n carry += lo < el ? 1 : 0;\n\n var hi = ah + bh + ch + dh + eh + carry;\n return hi >>> 0;\n}\nexports.sum64_5_hi = sum64_5_hi;\n\nfunction sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {\n var lo = al + bl + cl + dl + el;\n\n return lo >>> 0;\n}\nexports.sum64_5_lo = sum64_5_lo;\n\nfunction rotr64_hi(ah, al, num) {\n var r = (al << (32 - num)) | (ah >>> num);\n return r >>> 0;\n}\nexports.rotr64_hi = rotr64_hi;\n\nfunction rotr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.rotr64_lo = rotr64_lo;\n\nfunction shr64_hi(ah, al, num) {\n return ah >>> num;\n}\nexports.shr64_hi = shr64_hi;\n\nfunction shr64_lo(ah, al, num) {\n var r = (ah << (32 - num)) | (al >>> num);\n return r >>> 0;\n}\nexports.shr64_lo = shr64_lo;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBcUI7QUFDMUMsZUFBZSxtQkFBTyxDQUFDLElBQVU7O0FBRWpDLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGdCQUFnQjtBQUN0QztBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0EsSUFBSTtBQUNKLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsZ0JBQWdCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBLGNBQWM7O0FBRWQ7QUFDQTtBQUNBO0FBQ0EsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcz9jM2MwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuaW5oZXJpdHMgPSBpbmhlcml0cztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkge1xuICBpZiAoKG1zZy5jaGFyQ29kZUF0KGkpICYgMHhGQzAwKSAhPT0gMHhEODAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpIDwgMCB8fCBpICsgMSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAobXNnLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwO1xufVxuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIC8vIEluc3BpcmVkIGJ5IHN0cmluZ1RvVXRmOEJ5dGVBcnJheSgpIGluIGNsb3N1cmUtbGlicmFyeSBieSBHb29nbGVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvODU5OGQ4NzI0MmFmNTlhYWMyMzMyNzA3NDJjODk4NGUyYjJiZGJlMC9jbG9zdXJlL2dvb2cvY3J5cHQvY3J5cHQuanMjTDExNy1MMTQzXG4gICAgICAvLyBBcGFjaGUgTGljZW5zZSAyLjBcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAgICAgIHZhciBwID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSBjO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPCAyMDQ4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyA+PiA2KSB8IDE5MjtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3Vycm9nYXRlUGFpcihtc2csIGkpKSB7XG4gICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgJiAweDAzRkYpIDw8IDEwKSArIChtc2cuY2hhckNvZGVBdCgrK2kpICYgMHgwM0ZGKTtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDE4KSB8IDI0MDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiAxMikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoKGMgPj4gNikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyAmIDYzKSB8IDEyODtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDEyKSB8IDIyNDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleCA9IHRvSGV4O1xuXG5mdW5jdGlvbiBodG9ubCh3KSB7XG4gIHZhciByZXMgPSAodyA+Pj4gMjQpIHxcbiAgICAgICAgICAgICgodyA+Pj4gOCkgJiAweGZmMDApIHxcbiAgICAgICAgICAgICgodyA8PCA4KSAmIDB4ZmYwMDAwKSB8XG4gICAgICAgICAgICAoKHcgJiAweGZmKSA8PCAyNCk7XG4gIHJldHVybiByZXMgPj4+IDA7XG59XG5leHBvcnRzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHplcm84KHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSA3KVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNilcbiAgICByZXR1cm4gJzAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA1KVxuICAgIHJldHVybiAnMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA0KVxuICAgIHJldHVybiAnMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMylcbiAgICByZXR1cm4gJzAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAyKVxuICAgIHJldHVybiAnMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMDAwMDAwMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5zcGxpdDMyID0gc3BsaXQzMjtcblxuZnVuY3Rpb24gcm90cjMyKHcsIGIpIHtcbiAgcmV0dXJuICh3ID4+PiBiKSB8ICh3IDw8ICgzMiAtIGIpKTtcbn1cbmV4cG9ydHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyID0gc3VtMzI7XG5cbmZ1bmN0aW9uIHN1bTMyXzMoYSwgYiwgYykge1xuICByZXR1cm4gKGEgKyBiICsgYykgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNSA9IHN1bTMyXzU7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0X2hpID0gc3VtNjRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0X2xvKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IGFsICsgYmw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNF9sbyA9IHN1bTY0XzRfbG87XG5cbmZ1bmN0aW9uIHN1bTY0XzVfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZWwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGVsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBlaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMucm90cjY0X2hpID0gcm90cjY0X2hpO1xuXG5mdW5jdGlvbiByb3RyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufVxuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnNocjY0X2xvID0gc2hyNjRfbG87XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6436\n")},5717:function(module){eval("if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTcxNy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzPzNmYjUiXSwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5717\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},9746:function(module){eval("module.exports = assert;\n\nfunction assert(val, msg) {\n if (!val)\n throw new Error(msg || 'Assertion failed');\n}\n\nassert.equal = function assertEqual(l, r, msg) {\n if (l != r)\n throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvbWluaW1hbGlzdGljLWFzc2VydC9pbmRleC5qcz9kYTNlIl0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXNzZXJ0O1xuXG5mdW5jdGlvbiBhc3NlcnQodmFsLCBtc2cpIHtcbiAgaWYgKCF2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBhc3NlcnRFcXVhbChsLCByLCBtc2cpIHtcbiAgaWYgKGwgIT0gcilcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICgnQXNzZXJ0aW9uIGZhaWxlZDogJyArIGwgKyAnICE9ICcgKyByKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9746\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz81OWY4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz8zNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/MWJmMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzP2I4OGUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NmRiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/ZmI1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz9mMGYzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/YjMwZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz82OTY3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzP2E4ZjciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz83NzYwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/Yjg2MiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzc0OWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz9hYTJiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82ZGMxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz83ZmY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZDJhYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzPzYwOGYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzPzY5NDciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz83YTkyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz80NTY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YjY2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzP2FhYTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz9lZDA1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz9mMTM2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZWVlNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz84MTA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzPzdmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz8zNTA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz9iYTg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz9jZGZlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz8zNGI3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzkxOWUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9jZjY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz8wZjA5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/ZTQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz8zMmFlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzJjNTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/ZThjZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/M2Q3NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9jNmVmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/MGFlMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/MmI4ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/NzczNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzPzViNGEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzPzY4MWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz81NmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzPzUxYTAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/M2JkYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz9iN2UzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzPzA5YmMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZThlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/MDY5OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/ZjhkMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz9lNGZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzPzJhMmYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/MTNkNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9jNjA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(Q){var t=__webpack_module_cache__[Q];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[Q]={exports:{}};return __webpack_modules__[Q](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=function(Q){var t=Q&&Q.__esModule?function(){return Q.default}:function(){return Q};return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=function(Q,t){for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(Q,n)&&Object.defineProperty(Q,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=function(Q,t){return Object.prototype.hasOwnProperty.call(Q,t)};var __webpack_exports__=__webpack_require__(6960)})(); \ No newline at end of file +(function(){var __webpack_modules__={3089:function(__unused_webpack_module,exports){"use strict";eval('var __webpack_unused_export__;\n\n/**\n * Implementation of Myers\' online approximate string matching algorithm [1],\n * with additional optimizations suggested by [2].\n *\n * This has O((k/w) * n) complexity where `n` is the length of the text, `k` is\n * the maximum number of errors allowed (always <= the pattern length) and `w`\n * is the word size. Because JS only supports bitwise operations on 32 bit\n * integers, `w` is 32.\n *\n * As far as I am aware, there aren\'t any online algorithms which are\n * significantly better for a wide range of input parameters. The problem can be\n * solved faster using "filter then verify" approaches which first filter out\n * regions of the text that cannot match using a "cheap" check and then verify\n * the remaining potential matches. The verify step requires an algorithm such\n * as this one however.\n *\n * The algorithm\'s approach is essentially to optimize the classic dynamic\n * programming solution to the problem by computing columns of the matrix in\n * word-sized chunks (ie. dealing with 32 chars of the pattern at a time) and\n * avoiding calculating regions of the matrix where the minimum error count is\n * guaranteed to exceed the input threshold.\n *\n * The paper consists of two parts, the first describes the core algorithm for\n * matching patterns <= the size of a word (implemented by `advanceBlock` here).\n * The second uses the core algorithm as part of a larger block-based algorithm\n * to handle longer patterns.\n *\n * [1] G. Myers, “A Fast Bit-Vector Algorithm for Approximate String Matching\n * Based on Dynamic Programming,” vol. 46, no. 3, pp. 395–415, 1999.\n *\n * [2] Šošić, M. (2014). An simd dynamic programming c/c++ library (Doctoral\n * dissertation, Fakultet Elektrotehnike i računarstva, Sveučilište u Zagrebu).\n */\n__webpack_unused_export__ = ({ value: true });\nfunction reverse(s) {\n return s\n .split("")\n .reverse()\n .join("");\n}\n/**\n * Given the ends of approximate matches for `pattern` in `text`, find\n * the start of the matches.\n *\n * @param findEndFn - Function for finding the end of matches in\n * text.\n * @return Matches with the `start` property set.\n */\nfunction findMatchStarts(text, pattern, matches) {\n var patRev = reverse(pattern);\n return matches.map(function (m) {\n // Find start of each match by reversing the pattern and matching segment\n // of text and searching for an approx match with the same number of\n // errors.\n var minStart = Math.max(0, m.end - pattern.length - m.errors);\n var textRev = reverse(text.slice(minStart, m.end));\n // If there are multiple possible start points, choose the one that\n // maximizes the length of the match.\n var start = findMatchEnds(textRev, patRev, m.errors).reduce(function (min, rm) {\n if (m.end - rm.end < min) {\n return m.end - rm.end;\n }\n return min;\n }, m.end);\n return {\n start: start,\n end: m.end,\n errors: m.errors\n };\n });\n}\n/**\n * Return 1 if a number is non-zero or zero otherwise, without using\n * conditional operators.\n *\n * This should get inlined into `advanceBlock` below by the JIT.\n *\n * Adapted from https://stackoverflow.com/a/3912218/434243\n */\nfunction oneIfNotZero(n) {\n return ((n | -n) >> 31) & 1;\n}\n/**\n * Block calculation step of the algorithm.\n *\n * From Fig 8. on p. 408 of [1], additionally optimized to replace conditional\n * checks with bitwise operations as per Section 4.2.3 of [2].\n *\n * @param ctx - The pattern context object\n * @param peq - The `peq` array for the current character (`ctx.peq.get(ch)`)\n * @param b - The block level\n * @param hIn - Horizontal input delta ∈ {1,0,-1}\n * @return Horizontal output delta ∈ {1,0,-1}\n */\nfunction advanceBlock(ctx, peq, b, hIn) {\n var pV = ctx.P[b];\n var mV = ctx.M[b];\n var hInIsNegative = hIn >>> 31; // 1 if hIn < 0 or 0 otherwise.\n var eq = peq[b] | hInIsNegative;\n // Step 1: Compute horizontal deltas.\n var xV = eq | mV;\n var xH = (((eq & pV) + pV) ^ pV) | eq;\n var pH = mV | ~(xH | pV);\n var mH = pV & xH;\n // Step 2: Update score (value of last row of this block).\n var hOut = oneIfNotZero(pH & ctx.lastRowMask[b]) -\n oneIfNotZero(mH & ctx.lastRowMask[b]);\n // Step 3: Update vertical deltas for use when processing next char.\n pH <<= 1;\n mH <<= 1;\n mH |= hInIsNegative;\n pH |= oneIfNotZero(hIn) - hInIsNegative; // set pH[0] if hIn > 0\n pV = mH | ~(xV | pH);\n mV = pH & xV;\n ctx.P[b] = pV;\n ctx.M[b] = mV;\n return hOut;\n}\n/**\n * Find the ends and error counts for matches of `pattern` in `text`.\n *\n * Only the matches with the lowest error count are reported. Other matches\n * with error counts <= maxErrors are discarded.\n *\n * This is the block-based search algorithm from Fig. 9 on p.410 of [1].\n */\nfunction findMatchEnds(text, pattern, maxErrors) {\n if (pattern.length === 0) {\n return [];\n }\n // Clamp error count so we can rely on the `maxErrors` and `pattern.length`\n // rows being in the same block below.\n maxErrors = Math.min(maxErrors, pattern.length);\n var matches = [];\n // Word size.\n var w = 32;\n // Index of maximum block level.\n var bMax = Math.ceil(pattern.length / w) - 1;\n // Context used across block calculations.\n var ctx = {\n P: new Uint32Array(bMax + 1),\n M: new Uint32Array(bMax + 1),\n lastRowMask: new Uint32Array(bMax + 1)\n };\n ctx.lastRowMask.fill(1 << 31);\n ctx.lastRowMask[bMax] = 1 << (pattern.length - 1) % w;\n // Dummy "peq" array for chars in the text which do not occur in the pattern.\n var emptyPeq = new Uint32Array(bMax + 1);\n // Map of UTF-16 character code to bit vector indicating positions in the\n // pattern that equal that character.\n var peq = new Map();\n // Version of `peq` that only stores mappings for small characters. This\n // allows faster lookups when iterating through the text because a simple\n // array lookup can be done instead of a hash table lookup.\n var asciiPeq = [];\n for (var i = 0; i < 256; i++) {\n asciiPeq.push(emptyPeq);\n }\n // Calculate `ctx.peq` - a map of character values to bitmasks indicating\n // positions of that character within the pattern, where each bit represents\n // a position in the pattern.\n for (var c = 0; c < pattern.length; c += 1) {\n var val = pattern.charCodeAt(c);\n if (peq.has(val)) {\n // Duplicate char in pattern.\n continue;\n }\n var charPeq = new Uint32Array(bMax + 1);\n peq.set(val, charPeq);\n if (val < asciiPeq.length) {\n asciiPeq[val] = charPeq;\n }\n for (var b = 0; b <= bMax; b += 1) {\n charPeq[b] = 0;\n // Set all the bits where the pattern matches the current char (ch).\n // For indexes beyond the end of the pattern, always set the bit as if the\n // pattern contained a wildcard char in that position.\n for (var r = 0; r < w; r += 1) {\n var idx = b * w + r;\n if (idx >= pattern.length) {\n continue;\n }\n var match = pattern.charCodeAt(idx) === val;\n if (match) {\n charPeq[b] |= 1 << r;\n }\n }\n }\n }\n // Index of last-active block level in the column.\n var y = Math.max(0, Math.ceil(maxErrors / w) - 1);\n // Initialize maximum error count at bottom of each block.\n var score = new Uint32Array(bMax + 1);\n for (var b = 0; b <= y; b += 1) {\n score[b] = (b + 1) * w;\n }\n score[bMax] = pattern.length;\n // Initialize vertical deltas for each block.\n for (var b = 0; b <= y; b += 1) {\n ctx.P[b] = ~0;\n ctx.M[b] = 0;\n }\n // Process each char of the text, computing the error count for `w` chars of\n // the pattern at a time.\n for (var j = 0; j < text.length; j += 1) {\n // Lookup the bitmask representing the positions of the current char from\n // the text within the pattern.\n var charCode = text.charCodeAt(j);\n var charPeq = void 0;\n if (charCode < asciiPeq.length) {\n // Fast array lookup.\n charPeq = asciiPeq[charCode];\n }\n else {\n // Slower hash table lookup.\n charPeq = peq.get(charCode);\n if (typeof charPeq === "undefined") {\n charPeq = emptyPeq;\n }\n }\n // Calculate error count for blocks that we definitely have to process for\n // this column.\n var carry = 0;\n for (var b = 0; b <= y; b += 1) {\n carry = advanceBlock(ctx, charPeq, b, carry);\n score[b] += carry;\n }\n // Check if we also need to compute an additional block, or if we can reduce\n // the number of blocks processed for the next column.\n if (score[y] - carry <= maxErrors &&\n y < bMax &&\n (charPeq[y + 1] & 1 || carry < 0)) {\n // Error count for bottom block is under threshold, increase the number of\n // blocks processed for this column & next by 1.\n y += 1;\n ctx.P[y] = ~0;\n ctx.M[y] = 0;\n var maxBlockScore = y === bMax ? pattern.length % w : w;\n score[y] =\n score[y - 1] +\n maxBlockScore -\n carry +\n advanceBlock(ctx, charPeq, y, carry);\n }\n else {\n // Error count for bottom block exceeds threshold, reduce the number of\n // blocks processed for the next column.\n while (y > 0 && score[y] >= maxErrors + w) {\n y -= 1;\n }\n }\n // If error count is under threshold, report a match.\n if (y === bMax && score[y] <= maxErrors) {\n if (score[y] < maxErrors) {\n // Discard any earlier, worse matches.\n matches.splice(0, matches.length);\n }\n matches.push({\n start: -1,\n end: j + 1,\n errors: score[y]\n });\n // Because `search` only reports the matches with the lowest error count,\n // we can "ratchet down" the max error threshold whenever a match is\n // encountered and thereby save a small amount of work for the remainder\n // of the text.\n maxErrors = score[y];\n }\n }\n return matches;\n}\n/**\n * Search for matches for `pattern` in `text` allowing up to `maxErrors` errors.\n *\n * Returns the start, and end positions and error counts for each lowest-cost\n * match. Only the "best" matches are returned.\n */\nfunction search(text, pattern, maxErrors) {\n var matches = findMatchEnds(text, pattern, maxErrors);\n return findMatchStarts(text, pattern, matches);\n}\nexports.Z = search;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzA4OS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkMsRUFBRSxhQUFhLENBQUM7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG9CQUFvQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLE9BQU87QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2FwcHJveC1zdHJpbmctbWF0Y2gvZGlzdC9pbmRleC5qcz83MjMwIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBNeWVycycgb25saW5lIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBhbGdvcml0aG0gWzFdLFxuICogd2l0aCBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgc3VnZ2VzdGVkIGJ5IFsyXS5cbiAqXG4gKiBUaGlzIGhhcyBPKChrL3cpICogbikgY29tcGxleGl0eSB3aGVyZSBgbmAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCwgYGtgIGlzXG4gKiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIGFsbG93ZWQgKGFsd2F5cyA8PSB0aGUgcGF0dGVybiBsZW5ndGgpIGFuZCBgd2BcbiAqIGlzIHRoZSB3b3JkIHNpemUuIEJlY2F1c2UgSlMgb25seSBzdXBwb3J0cyBiaXR3aXNlIG9wZXJhdGlvbnMgb24gMzIgYml0XG4gKiBpbnRlZ2VycywgYHdgIGlzIDMyLlxuICpcbiAqIEFzIGZhciBhcyBJIGFtIGF3YXJlLCB0aGVyZSBhcmVuJ3QgYW55IG9ubGluZSBhbGdvcml0aG1zIHdoaWNoIGFyZVxuICogc2lnbmlmaWNhbnRseSBiZXR0ZXIgZm9yIGEgd2lkZSByYW5nZSBvZiBpbnB1dCBwYXJhbWV0ZXJzLiBUaGUgcHJvYmxlbSBjYW4gYmVcbiAqIHNvbHZlZCBmYXN0ZXIgdXNpbmcgXCJmaWx0ZXIgdGhlbiB2ZXJpZnlcIiBhcHByb2FjaGVzIHdoaWNoIGZpcnN0IGZpbHRlciBvdXRcbiAqIHJlZ2lvbnMgb2YgdGhlIHRleHQgdGhhdCBjYW5ub3QgbWF0Y2ggdXNpbmcgYSBcImNoZWFwXCIgY2hlY2sgYW5kIHRoZW4gdmVyaWZ5XG4gKiB0aGUgcmVtYWluaW5nIHBvdGVudGlhbCBtYXRjaGVzLiBUaGUgdmVyaWZ5IHN0ZXAgcmVxdWlyZXMgYW4gYWxnb3JpdGhtIHN1Y2hcbiAqIGFzIHRoaXMgb25lIGhvd2V2ZXIuXG4gKlxuICogVGhlIGFsZ29yaXRobSdzIGFwcHJvYWNoIGlzIGVzc2VudGlhbGx5IHRvIG9wdGltaXplIHRoZSBjbGFzc2ljIGR5bmFtaWNcbiAqIHByb2dyYW1taW5nIHNvbHV0aW9uIHRvIHRoZSBwcm9ibGVtIGJ5IGNvbXB1dGluZyBjb2x1bW5zIG9mIHRoZSBtYXRyaXggaW5cbiAqIHdvcmQtc2l6ZWQgY2h1bmtzIChpZS4gZGVhbGluZyB3aXRoIDMyIGNoYXJzIG9mIHRoZSBwYXR0ZXJuIGF0IGEgdGltZSkgYW5kXG4gKiBhdm9pZGluZyBjYWxjdWxhdGluZyByZWdpb25zIG9mIHRoZSBtYXRyaXggd2hlcmUgdGhlIG1pbmltdW0gZXJyb3IgY291bnQgaXNcbiAqIGd1YXJhbnRlZWQgdG8gZXhjZWVkIHRoZSBpbnB1dCB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHBhcGVyIGNvbnNpc3RzIG9mIHR3byBwYXJ0cywgdGhlIGZpcnN0IGRlc2NyaWJlcyB0aGUgY29yZSBhbGdvcml0aG0gZm9yXG4gKiBtYXRjaGluZyBwYXR0ZXJucyA8PSB0aGUgc2l6ZSBvZiBhIHdvcmQgKGltcGxlbWVudGVkIGJ5IGBhZHZhbmNlQmxvY2tgIGhlcmUpLlxuICogVGhlIHNlY29uZCB1c2VzIHRoZSBjb3JlIGFsZ29yaXRobSBhcyBwYXJ0IG9mIGEgbGFyZ2VyIGJsb2NrLWJhc2VkIGFsZ29yaXRobVxuICogdG8gaGFuZGxlIGxvbmdlciBwYXR0ZXJucy5cbiAqXG4gKiBbMV0gRy4gTXllcnMsIOKAnEEgRmFzdCBCaXQtVmVjdG9yIEFsZ29yaXRobSBmb3IgQXBwcm94aW1hdGUgU3RyaW5nIE1hdGNoaW5nXG4gKiBCYXNlZCBvbiBEeW5hbWljIFByb2dyYW1taW5nLOKAnSB2b2wuIDQ2LCBuby4gMywgcHAuIDM5NeKAkzQxNSwgMTk5OS5cbiAqXG4gKiBbMl0gxaBvxaFpxIcsIE0uICgyMDE0KS4gQW4gc2ltZCBkeW5hbWljIHByb2dyYW1taW5nIGMvYysrIGxpYnJhcnkgKERvY3RvcmFsXG4gKiBkaXNzZXJ0YXRpb24sIEZha3VsdGV0IEVsZWt0cm90ZWhuaWtlIGkgcmHEjXVuYXJzdHZhLCBTdmV1xI1pbGnFoXRlIHUgWmFncmVidSkuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJldmVyc2Uocykge1xuICAgIHJldHVybiBzXG4gICAgICAgIC5zcGxpdChcIlwiKVxuICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgIC5qb2luKFwiXCIpO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgZW5kcyBvZiBhcHByb3hpbWF0ZSBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHRleHRgLCBmaW5kXG4gKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMuXG4gKlxuICogQHBhcmFtIGZpbmRFbmRGbiAtIEZ1bmN0aW9uIGZvciBmaW5kaW5nIHRoZSBlbmQgb2YgbWF0Y2hlcyBpblxuICogdGV4dC5cbiAqIEByZXR1cm4gTWF0Y2hlcyB3aXRoIHRoZSBgc3RhcnRgIHByb3BlcnR5IHNldC5cbiAqL1xuZnVuY3Rpb24gZmluZE1hdGNoU3RhcnRzKHRleHQsIHBhdHRlcm4sIG1hdGNoZXMpIHtcbiAgICB2YXIgcGF0UmV2ID0gcmV2ZXJzZShwYXR0ZXJuKTtcbiAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgLy8gRmluZCBzdGFydCBvZiBlYWNoIG1hdGNoIGJ5IHJldmVyc2luZyB0aGUgcGF0dGVybiBhbmQgbWF0Y2hpbmcgc2VnbWVudFxuICAgICAgICAvLyBvZiB0ZXh0IGFuZCBzZWFyY2hpbmcgZm9yIGFuIGFwcHJveCBtYXRjaCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZlxuICAgICAgICAvLyBlcnJvcnMuXG4gICAgICAgIHZhciBtaW5TdGFydCA9IE1hdGgubWF4KDAsIG0uZW5kIC0gcGF0dGVybi5sZW5ndGggLSBtLmVycm9ycyk7XG4gICAgICAgIHZhciB0ZXh0UmV2ID0gcmV2ZXJzZSh0ZXh0LnNsaWNlKG1pblN0YXJ0LCBtLmVuZCkpO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgcG9zc2libGUgc3RhcnQgcG9pbnRzLCBjaG9vc2UgdGhlIG9uZSB0aGF0XG4gICAgICAgIC8vIG1heGltaXplcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaC5cbiAgICAgICAgdmFyIHN0YXJ0ID0gZmluZE1hdGNoRW5kcyh0ZXh0UmV2LCBwYXRSZXYsIG0uZXJyb3JzKS5yZWR1Y2UoZnVuY3Rpb24gKG1pbiwgcm0pIHtcbiAgICAgICAgICAgIGlmIChtLmVuZCAtIHJtLmVuZCA8IG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmVuZCAtIHJtLmVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtaW47XG4gICAgICAgIH0sIG0uZW5kKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogbS5lbmQsXG4gICAgICAgICAgICBlcnJvcnM6IG0uZXJyb3JzXG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybiAxIGlmIGEgbnVtYmVyIGlzIG5vbi16ZXJvIG9yIHplcm8gb3RoZXJ3aXNlLCB3aXRob3V0IHVzaW5nXG4gKiBjb25kaXRpb25hbCBvcGVyYXRvcnMuXG4gKlxuICogVGhpcyBzaG91bGQgZ2V0IGlubGluZWQgaW50byBgYWR2YW5jZUJsb2NrYCBiZWxvdyBieSB0aGUgSklULlxuICpcbiAqIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzkxMjIxOC80MzQyNDNcbiAqL1xuZnVuY3Rpb24gb25lSWZOb3RaZXJvKG4pIHtcbiAgICByZXR1cm4gKChuIHwgLW4pID4+IDMxKSAmIDE7XG59XG4vKipcbiAqIEJsb2NrIGNhbGN1bGF0aW9uIHN0ZXAgb2YgdGhlIGFsZ29yaXRobS5cbiAqXG4gKiBGcm9tIEZpZyA4LiBvbiBwLiA0MDggb2YgWzFdLCBhZGRpdGlvbmFsbHkgb3B0aW1pemVkIHRvIHJlcGxhY2UgY29uZGl0aW9uYWxcbiAqIGNoZWNrcyB3aXRoIGJpdHdpc2Ugb3BlcmF0aW9ucyBhcyBwZXIgU2VjdGlvbiA0LjIuMyBvZiBbMl0uXG4gKlxuICogQHBhcmFtIGN0eCAtIFRoZSBwYXR0ZXJuIGNvbnRleHQgb2JqZWN0XG4gKiBAcGFyYW0gcGVxIC0gVGhlIGBwZXFgIGFycmF5IGZvciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgKGBjdHgucGVxLmdldChjaClgKVxuICogQHBhcmFtIGIgLSBUaGUgYmxvY2sgbGV2ZWxcbiAqIEBwYXJhbSBoSW4gLSBIb3Jpem9udGFsIGlucHV0IGRlbHRhIOKIiCB7MSwwLC0xfVxuICogQHJldHVybiBIb3Jpem9udGFsIG91dHB1dCBkZWx0YSDiiIggezEsMCwtMX1cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUJsb2NrKGN0eCwgcGVxLCBiLCBoSW4pIHtcbiAgICB2YXIgcFYgPSBjdHguUFtiXTtcbiAgICB2YXIgbVYgPSBjdHguTVtiXTtcbiAgICB2YXIgaEluSXNOZWdhdGl2ZSA9IGhJbiA+Pj4gMzE7IC8vIDEgaWYgaEluIDwgMCBvciAwIG90aGVyd2lzZS5cbiAgICB2YXIgZXEgPSBwZXFbYl0gfCBoSW5Jc05lZ2F0aXZlO1xuICAgIC8vIFN0ZXAgMTogQ29tcHV0ZSBob3Jpem9udGFsIGRlbHRhcy5cbiAgICB2YXIgeFYgPSBlcSB8IG1WO1xuICAgIHZhciB4SCA9ICgoKGVxICYgcFYpICsgcFYpIF4gcFYpIHwgZXE7XG4gICAgdmFyIHBIID0gbVYgfCB+KHhIIHwgcFYpO1xuICAgIHZhciBtSCA9IHBWICYgeEg7XG4gICAgLy8gU3RlcCAyOiBVcGRhdGUgc2NvcmUgKHZhbHVlIG9mIGxhc3Qgcm93IG9mIHRoaXMgYmxvY2spLlxuICAgIHZhciBoT3V0ID0gb25lSWZOb3RaZXJvKHBIICYgY3R4Lmxhc3RSb3dNYXNrW2JdKSAtXG4gICAgICAgIG9uZUlmTm90WmVybyhtSCAmIGN0eC5sYXN0Um93TWFza1tiXSk7XG4gICAgLy8gU3RlcCAzOiBVcGRhdGUgdmVydGljYWwgZGVsdGFzIGZvciB1c2Ugd2hlbiBwcm9jZXNzaW5nIG5leHQgY2hhci5cbiAgICBwSCA8PD0gMTtcbiAgICBtSCA8PD0gMTtcbiAgICBtSCB8PSBoSW5Jc05lZ2F0aXZlO1xuICAgIHBIIHw9IG9uZUlmTm90WmVybyhoSW4pIC0gaEluSXNOZWdhdGl2ZTsgLy8gc2V0IHBIWzBdIGlmIGhJbiA+IDBcbiAgICBwViA9IG1IIHwgfih4ViB8IHBIKTtcbiAgICBtViA9IHBIICYgeFY7XG4gICAgY3R4LlBbYl0gPSBwVjtcbiAgICBjdHguTVtiXSA9IG1WO1xuICAgIHJldHVybiBoT3V0O1xufVxuLyoqXG4gKiBGaW5kIHRoZSBlbmRzIGFuZCBlcnJvciBjb3VudHMgZm9yIG1hdGNoZXMgb2YgYHBhdHRlcm5gIGluIGB0ZXh0YC5cbiAqXG4gKiBPbmx5IHRoZSBtYXRjaGVzIHdpdGggdGhlIGxvd2VzdCBlcnJvciBjb3VudCBhcmUgcmVwb3J0ZWQuIE90aGVyIG1hdGNoZXNcbiAqIHdpdGggZXJyb3IgY291bnRzIDw9IG1heEVycm9ycyBhcmUgZGlzY2FyZGVkLlxuICpcbiAqIFRoaXMgaXMgdGhlIGJsb2NrLWJhc2VkIHNlYXJjaCBhbGdvcml0aG0gZnJvbSBGaWcuIDkgb24gcC40MTAgb2YgWzFdLlxuICovXG5mdW5jdGlvbiBmaW5kTWF0Y2hFbmRzKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIENsYW1wIGVycm9yIGNvdW50IHNvIHdlIGNhbiByZWx5IG9uIHRoZSBgbWF4RXJyb3JzYCBhbmQgYHBhdHRlcm4ubGVuZ3RoYFxuICAgIC8vIHJvd3MgYmVpbmcgaW4gdGhlIHNhbWUgYmxvY2sgYmVsb3cuXG4gICAgbWF4RXJyb3JzID0gTWF0aC5taW4obWF4RXJyb3JzLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgICAvLyBXb3JkIHNpemUuXG4gICAgdmFyIHcgPSAzMjtcbiAgICAvLyBJbmRleCBvZiBtYXhpbXVtIGJsb2NrIGxldmVsLlxuICAgIHZhciBiTWF4ID0gTWF0aC5jZWlsKHBhdHRlcm4ubGVuZ3RoIC8gdykgLSAxO1xuICAgIC8vIENvbnRleHQgdXNlZCBhY3Jvc3MgYmxvY2sgY2FsY3VsYXRpb25zLlxuICAgIHZhciBjdHggPSB7XG4gICAgICAgIFA6IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIE06IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSksXG4gICAgICAgIGxhc3RSb3dNYXNrOiBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpXG4gICAgfTtcbiAgICBjdHgubGFzdFJvd01hc2suZmlsbCgxIDw8IDMxKTtcbiAgICBjdHgubGFzdFJvd01hc2tbYk1heF0gPSAxIDw8IChwYXR0ZXJuLmxlbmd0aCAtIDEpICUgdztcbiAgICAvLyBEdW1teSBcInBlcVwiIGFycmF5IGZvciBjaGFycyBpbiB0aGUgdGV4dCB3aGljaCBkbyBub3Qgb2NjdXIgaW4gdGhlIHBhdHRlcm4uXG4gICAgdmFyIGVtcHR5UGVxID0gbmV3IFVpbnQzMkFycmF5KGJNYXggKyAxKTtcbiAgICAvLyBNYXAgb2YgVVRGLTE2IGNoYXJhY3RlciBjb2RlIHRvIGJpdCB2ZWN0b3IgaW5kaWNhdGluZyBwb3NpdGlvbnMgaW4gdGhlXG4gICAgLy8gcGF0dGVybiB0aGF0IGVxdWFsIHRoYXQgY2hhcmFjdGVyLlxuICAgIHZhciBwZXEgPSBuZXcgTWFwKCk7XG4gICAgLy8gVmVyc2lvbiBvZiBgcGVxYCB0aGF0IG9ubHkgc3RvcmVzIG1hcHBpbmdzIGZvciBzbWFsbCBjaGFyYWN0ZXJzLiBUaGlzXG4gICAgLy8gYWxsb3dzIGZhc3RlciBsb29rdXBzIHdoZW4gaXRlcmF0aW5nIHRocm91Z2ggdGhlIHRleHQgYmVjYXVzZSBhIHNpbXBsZVxuICAgIC8vIGFycmF5IGxvb2t1cCBjYW4gYmUgZG9uZSBpbnN0ZWFkIG9mIGEgaGFzaCB0YWJsZSBsb29rdXAuXG4gICAgdmFyIGFzY2lpUGVxID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgICBhc2NpaVBlcS5wdXNoKGVtcHR5UGVxKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlIGBjdHgucGVxYCAtIGEgbWFwIG9mIGNoYXJhY3RlciB2YWx1ZXMgdG8gYml0bWFza3MgaW5kaWNhdGluZ1xuICAgIC8vIHBvc2l0aW9ucyBvZiB0aGF0IGNoYXJhY3RlciB3aXRoaW4gdGhlIHBhdHRlcm4sIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHNcbiAgICAvLyBhIHBvc2l0aW9uIGluIHRoZSBwYXR0ZXJuLlxuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgcGF0dGVybi5sZW5ndGg7IGMgKz0gMSkge1xuICAgICAgICB2YXIgdmFsID0gcGF0dGVybi5jaGFyQ29kZUF0KGMpO1xuICAgICAgICBpZiAocGVxLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgY2hhciBpbiBwYXR0ZXJuLlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoYXJQZXEgPSBuZXcgVWludDMyQXJyYXkoYk1heCArIDEpO1xuICAgICAgICBwZXEuc2V0KHZhbCwgY2hhclBlcSk7XG4gICAgICAgIGlmICh2YWwgPCBhc2NpaVBlcS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFzY2lpUGVxW3ZhbF0gPSBjaGFyUGVxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGIgPSAwOyBiIDw9IGJNYXg7IGIgKz0gMSkge1xuICAgICAgICAgICAgY2hhclBlcVtiXSA9IDA7XG4gICAgICAgICAgICAvLyBTZXQgYWxsIHRoZSBiaXRzIHdoZXJlIHRoZSBwYXR0ZXJuIG1hdGNoZXMgdGhlIGN1cnJlbnQgY2hhciAoY2gpLlxuICAgICAgICAgICAgLy8gRm9yIGluZGV4ZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIGFsd2F5cyBzZXQgdGhlIGJpdCBhcyBpZiB0aGVcbiAgICAgICAgICAgIC8vIHBhdHRlcm4gY29udGFpbmVkIGEgd2lsZGNhcmQgY2hhciBpbiB0aGF0IHBvc2l0aW9uLlxuICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCB3OyByICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gYiAqIHcgKyByO1xuICAgICAgICAgICAgICAgIGlmIChpZHggPj0gcGF0dGVybi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IHBhdHRlcm4uY2hhckNvZGVBdChpZHgpID09PSB2YWw7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJQZXFbYl0gfD0gMSA8PCByO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJbmRleCBvZiBsYXN0LWFjdGl2ZSBibG9jayBsZXZlbCBpbiB0aGUgY29sdW1uLlxuICAgIHZhciB5ID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKG1heEVycm9ycyAvIHcpIC0gMSk7XG4gICAgLy8gSW5pdGlhbGl6ZSBtYXhpbXVtIGVycm9yIGNvdW50IGF0IGJvdHRvbSBvZiBlYWNoIGJsb2NrLlxuICAgIHZhciBzY29yZSA9IG5ldyBVaW50MzJBcnJheShiTWF4ICsgMSk7XG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIHNjb3JlW2JdID0gKGIgKyAxKSAqIHc7XG4gICAgfVxuICAgIHNjb3JlW2JNYXhdID0gcGF0dGVybi5sZW5ndGg7XG4gICAgLy8gSW5pdGlhbGl6ZSB2ZXJ0aWNhbCBkZWx0YXMgZm9yIGVhY2ggYmxvY2suXG4gICAgZm9yICh2YXIgYiA9IDA7IGIgPD0geTsgYiArPSAxKSB7XG4gICAgICAgIGN0eC5QW2JdID0gfjA7XG4gICAgICAgIGN0eC5NW2JdID0gMDtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBlYWNoIGNoYXIgb2YgdGhlIHRleHQsIGNvbXB1dGluZyB0aGUgZXJyb3IgY291bnQgZm9yIGB3YCBjaGFycyBvZlxuICAgIC8vIHRoZSBwYXR0ZXJuIGF0IGEgdGltZS5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRleHQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBiaXRtYXNrIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb25zIG9mIHRoZSBjdXJyZW50IGNoYXIgZnJvbVxuICAgICAgICAvLyB0aGUgdGV4dCB3aXRoaW4gdGhlIHBhdHRlcm4uXG4gICAgICAgIHZhciBjaGFyQ29kZSA9IHRleHQuY2hhckNvZGVBdChqKTtcbiAgICAgICAgdmFyIGNoYXJQZXEgPSB2b2lkIDA7XG4gICAgICAgIGlmIChjaGFyQ29kZSA8IGFzY2lpUGVxLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gRmFzdCBhcnJheSBsb29rdXAuXG4gICAgICAgICAgICBjaGFyUGVxID0gYXNjaWlQZXFbY2hhckNvZGVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU2xvd2VyIGhhc2ggdGFibGUgbG9va3VwLlxuICAgICAgICAgICAgY2hhclBlcSA9IHBlcS5nZXQoY2hhckNvZGUpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyUGVxID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgY2hhclBlcSA9IGVtcHR5UGVxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3VudCBmb3IgYmxvY2tzIHRoYXQgd2UgZGVmaW5pdGVseSBoYXZlIHRvIHByb2Nlc3MgZm9yXG4gICAgICAgIC8vIHRoaXMgY29sdW1uLlxuICAgICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgICBmb3IgKHZhciBiID0gMDsgYiA8PSB5OyBiICs9IDEpIHtcbiAgICAgICAgICAgIGNhcnJ5ID0gYWR2YW5jZUJsb2NrKGN0eCwgY2hhclBlcSwgYiwgY2FycnkpO1xuICAgICAgICAgICAgc2NvcmVbYl0gKz0gY2Fycnk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgYWxzbyBuZWVkIHRvIGNvbXB1dGUgYW4gYWRkaXRpb25hbCBibG9jaywgb3IgaWYgd2UgY2FuIHJlZHVjZVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGJsb2NrcyBwcm9jZXNzZWQgZm9yIHRoZSBuZXh0IGNvbHVtbi5cbiAgICAgICAgaWYgKHNjb3JlW3ldIC0gY2FycnkgPD0gbWF4RXJyb3JzICYmXG4gICAgICAgICAgICB5IDwgYk1heCAmJlxuICAgICAgICAgICAgKGNoYXJQZXFbeSArIDFdICYgMSB8fCBjYXJyeSA8IDApKSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGlzIHVuZGVyIHRocmVzaG9sZCwgaW5jcmVhc2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhpcyBjb2x1bW4gJiBuZXh0IGJ5IDEuXG4gICAgICAgICAgICB5ICs9IDE7XG4gICAgICAgICAgICBjdHguUFt5XSA9IH4wO1xuICAgICAgICAgICAgY3R4Lk1beV0gPSAwO1xuICAgICAgICAgICAgdmFyIG1heEJsb2NrU2NvcmUgPSB5ID09PSBiTWF4ID8gcGF0dGVybi5sZW5ndGggJSB3IDogdztcbiAgICAgICAgICAgIHNjb3JlW3ldID1cbiAgICAgICAgICAgICAgICBzY29yZVt5IC0gMV0gK1xuICAgICAgICAgICAgICAgICAgICBtYXhCbG9ja1Njb3JlIC1cbiAgICAgICAgICAgICAgICAgICAgY2FycnkgK1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlQmxvY2soY3R4LCBjaGFyUGVxLCB5LCBjYXJyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBFcnJvciBjb3VudCBmb3IgYm90dG9tIGJsb2NrIGV4Y2VlZHMgdGhyZXNob2xkLCByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAgICAgICAgLy8gYmxvY2tzIHByb2Nlc3NlZCBmb3IgdGhlIG5leHQgY29sdW1uLlxuICAgICAgICAgICAgd2hpbGUgKHkgPiAwICYmIHNjb3JlW3ldID49IG1heEVycm9ycyArIHcpIHtcbiAgICAgICAgICAgICAgICB5IC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZXJyb3IgY291bnQgaXMgdW5kZXIgdGhyZXNob2xkLCByZXBvcnQgYSBtYXRjaC5cbiAgICAgICAgaWYgKHkgPT09IGJNYXggJiYgc2NvcmVbeV0gPD0gbWF4RXJyb3JzKSB7XG4gICAgICAgICAgICBpZiAoc2NvcmVbeV0gPCBtYXhFcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIGFueSBlYXJsaWVyLCB3b3JzZSBtYXRjaGVzLlxuICAgICAgICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKDAsIG1hdGNoZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICAgICAgICAgIGVuZDogaiArIDEsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBzY29yZVt5XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBCZWNhdXNlIGBzZWFyY2hgIG9ubHkgcmVwb3J0cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBsb3dlc3QgZXJyb3IgY291bnQsXG4gICAgICAgICAgICAvLyB3ZSBjYW4gXCJyYXRjaGV0IGRvd25cIiB0aGUgbWF4IGVycm9yIHRocmVzaG9sZCB3aGVuZXZlciBhIG1hdGNoIGlzXG4gICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbmQgdGhlcmVieSBzYXZlIGEgc21hbGwgYW1vdW50IG9mIHdvcmsgZm9yIHRoZSByZW1haW5kZXJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB0ZXh0LlxuICAgICAgICAgICAgbWF4RXJyb3JzID0gc2NvcmVbeV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59XG4vKipcbiAqIFNlYXJjaCBmb3IgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogUmV0dXJucyB0aGUgc3RhcnQsIGFuZCBlbmQgcG9zaXRpb25zIGFuZCBlcnJvciBjb3VudHMgZm9yIGVhY2ggbG93ZXN0LWNvc3RcbiAqIG1hdGNoLiBPbmx5IHRoZSBcImJlc3RcIiBtYXRjaGVzIGFyZSByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gc2VhcmNoKHRleHQsIHBhdHRlcm4sIG1heEVycm9ycykge1xuICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoRW5kcyh0ZXh0LCBwYXR0ZXJuLCBtYXhFcnJvcnMpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hTdGFydHModGV4dCwgcGF0dGVybiwgbWF0Y2hlcyk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzZWFyY2g7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3089\n')},8501:function(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__){"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/approx-string-match/dist/index.js\nvar dist = __webpack_require__(3089);\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/match-quote.js\n\n/**\n * @typedef {import(\'approx-string-match\').Match} StringMatch\n */\n\n/**\n * @typedef Match\n * @prop {number} start - Start offset of match in text\n * @prop {number} end - End offset of match in text\n * @prop {number} score -\n * Score for the match between 0 and 1.0, where 1.0 indicates a perfect match\n * for the quote and context.\n */\n\n/**\n * Find the best approximate matches for `str` in `text` allowing up to `maxErrors` errors.\n *\n * @param {string} text\n * @param {string} str\n * @param {number} maxErrors\n * @return {StringMatch[]}\n */\n\nfunction search(text, str, maxErrors) {\n // Do a fast search for exact matches. The `approx-string-match` library\n // doesn\'t currently incorporate this optimization itself.\n var matchPos = 0;\n var exactMatches = [];\n\n while (matchPos !== -1) {\n matchPos = text.indexOf(str, matchPos);\n\n if (matchPos !== -1) {\n exactMatches.push({\n start: matchPos,\n end: matchPos + str.length,\n errors: 0\n });\n matchPos += 1;\n }\n }\n\n if (exactMatches.length > 0) {\n return exactMatches;\n } // If there are no exact matches, do a more expensive search for matches\n // with errors.\n\n\n return (0,dist/* default */.Z)(text, str, maxErrors);\n}\n/**\n * Compute a score between 0 and 1.0 for the similarity between `text` and `str`.\n *\n * @param {string} text\n * @param {string} str\n */\n\n\nfunction textMatchScore(text, str) {\n /* istanbul ignore next - `scoreMatch` will never pass an empty string */\n if (str.length === 0 || text.length === 0) {\n return 0.0;\n }\n\n var matches = search(text, str, str.length); // prettier-ignore\n\n return 1 - matches[0].errors / str.length;\n}\n/**\n * Find the best approximate match for `quote` in `text`.\n *\n * Returns `null` if no match exceeding the minimum quality threshold was found.\n *\n * @param {string} text - Document text to search\n * @param {string} quote - String to find within `text`\n * @param {Object} context -\n * Context in which the quote originally appeared. This is used to choose the\n * best match.\n * @param {string} [context.prefix] - Expected text before the quote\n * @param {string} [context.suffix] - Expected text after the quote\n * @param {number} [context.hint] - Expected offset of match within text\n * @return {Match|null}\n */\n\n\nfunction matchQuote(text, quote) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (quote.length === 0) {\n return null;\n } // Choose the maximum number of errors to allow for the initial search.\n // This choice involves a tradeoff between:\n //\n // - Recall (proportion of "good" matches found)\n // - Precision (proportion of matches found which are "good")\n // - Cost of the initial search and of processing the candidate matches [1]\n //\n // [1] Specifically, the expected-time complexity of the initial search is\n // `O((maxErrors / 32) * text.length)`. See `approx-string-match` docs.\n\n\n var maxErrors = Math.min(256, quote.length / 2); // Find closest matches for `quote` in `text` based on edit distance.\n\n var matches = search(text, quote, maxErrors);\n\n if (matches.length === 0) {\n return null;\n }\n /**\n * Compute a score between 0 and 1.0 for a match candidate.\n *\n * @param {StringMatch} match\n */\n\n\n var scoreMatch = function scoreMatch(match) {\n var quoteWeight = 50; // Similarity of matched text to quote.\n\n var prefixWeight = 20; // Similarity of text before matched text to `context.prefix`.\n\n var suffixWeight = 20; // Similarity of text after matched text to `context.suffix`.\n\n var posWeight = 2; // Proximity to expected location. Used as a tie-breaker.\n\n var quoteScore = 1 - match.errors / quote.length;\n var prefixScore = context.prefix ? textMatchScore(text.slice(Math.max(0, match.start - context.prefix.length), match.start), context.prefix) : 1.0;\n var suffixScore = context.suffix ? textMatchScore(text.slice(match.end, match.end + context.suffix.length), context.suffix) : 1.0;\n var posScore = 1.0;\n\n if (typeof context.hint === \'number\') {\n var offset = Math.abs(match.start - context.hint);\n posScore = 1.0 - offset / text.length;\n }\n\n var rawScore = quoteWeight * quoteScore + prefixWeight * prefixScore + suffixWeight * suffixScore + posWeight * posScore;\n var maxScore = quoteWeight + prefixWeight + suffixWeight + posWeight;\n var normalizedScore = rawScore / maxScore;\n return normalizedScore;\n }; // Rank matches based on similarity of actual and expected surrounding text\n // and actual/expected offset in the document text.\n\n\n var scoredMatches = matches.map(function (m) {\n return {\n start: m.start,\n end: m.end,\n score: scoreMatch(m)\n };\n }); // Choose match with highest score.\n\n scoredMatches.sort(function (a, b) {\n return b.score - a.score;\n });\n return scoredMatches[0];\n}\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/text-range.js\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Return the combined length of text nodes contained in `node`.\n *\n * @param {Node} node\n */\nfunction nodeTextLength(node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.TEXT_NODE:\n // nb. `textContent` excludes text in comments and processing instructions\n // when called on a parent element, so we don\'t need to subtract that here.\n return (\n /** @type {string} */\n node.textContent.length\n );\n\n default:\n return 0;\n }\n}\n/**\n * Return the total length of the text of all previous siblings of `node`.\n *\n * @param {Node} node\n */\n\n\nfunction previousSiblingsTextLength(node) {\n var sibling = node.previousSibling;\n var length = 0;\n\n while (sibling) {\n length += nodeTextLength(sibling);\n sibling = sibling.previousSibling;\n }\n\n return length;\n}\n/**\n * Resolve one or more character offsets within an element to (text node, position)\n * pairs.\n *\n * @param {Element} element\n * @param {number[]} offsets - Offsets, which must be sorted in ascending order\n * @return {{ node: Text, offset: number }[]}\n */\n\n\nfunction resolveOffsets(element) {\n for (var _len = arguments.length, offsets = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n offsets[_key - 1] = arguments[_key];\n }\n\n var nextOffset = offsets.shift();\n var nodeIter =\n /** @type {Document} */\n element.ownerDocument.createNodeIterator(element, NodeFilter.SHOW_TEXT);\n var results = [];\n var currentNode = nodeIter.nextNode();\n var textNode;\n var length = 0; // Find the text node containing the `nextOffset`th character from the start\n // of `element`.\n\n while (nextOffset !== undefined && currentNode) {\n textNode =\n /** @type {Text} */\n currentNode;\n\n if (length + textNode.data.length > nextOffset) {\n results.push({\n node: textNode,\n offset: nextOffset - length\n });\n nextOffset = offsets.shift();\n } else {\n currentNode = nodeIter.nextNode();\n length += textNode.data.length;\n }\n } // Boundary case.\n\n\n while (nextOffset !== undefined && textNode && length === nextOffset) {\n results.push({\n node: textNode,\n offset: textNode.data.length\n });\n nextOffset = offsets.shift();\n }\n\n if (nextOffset !== undefined) {\n throw new RangeError(\'Offset exceeds text length\');\n }\n\n return results;\n}\n\nvar RESOLVE_FORWARDS = 1;\nvar RESOLVE_BACKWARDS = 2;\n/**\n * Represents an offset within the text content of an element.\n *\n * This position can be resolved to a specific descendant node in the current\n * DOM subtree of the element using the `resolve` method.\n */\n\nvar text_range_TextPosition = /*#__PURE__*/function () {\n /**\n * Construct a `TextPosition` that refers to the text position `offset` within\n * the text content of `element`.\n *\n * @param {Element} element\n * @param {number} offset\n */\n function TextPosition(element, offset) {\n _classCallCheck(this, TextPosition);\n\n if (offset < 0) {\n throw new Error(\'Offset is invalid\');\n }\n /** Element that `offset` is relative to. */\n\n\n this.element = element;\n /** Character offset from the start of the element\'s `textContent`. */\n\n this.offset = offset;\n }\n /**\n * Return a copy of this position with offset relative to a given ancestor\n * element.\n *\n * @param {Element} parent - Ancestor of `this.element`\n * @return {TextPosition}\n */\n\n\n _createClass(TextPosition, [{\n key: "relativeTo",\n value: function relativeTo(parent) {\n if (!parent.contains(this.element)) {\n throw new Error(\'Parent is not an ancestor of current element\');\n }\n\n var el = this.element;\n var offset = this.offset;\n\n while (el !== parent) {\n offset += previousSiblingsTextLength(el);\n el =\n /** @type {Element} */\n el.parentElement;\n }\n\n return new TextPosition(el, offset);\n }\n /**\n * Resolve the position to a specific text node and offset within that node.\n *\n * Throws if `this.offset` exceeds the length of the element\'s text. In the\n * case where the element has no text and `this.offset` is 0, the `direction`\n * option determines what happens.\n *\n * Offsets at the boundary between two nodes are resolved to the start of the\n * node that begins at the boundary.\n *\n * @param {Object} [options]\n * @param {RESOLVE_FORWARDS|RESOLVE_BACKWARDS} [options.direction] -\n * Specifies in which direction to search for the nearest text node if\n * `this.offset` is `0` and `this.element` has no text. If not specified\n * an error is thrown.\n * @return {{ node: Text, offset: number }}\n * @throws {RangeError}\n */\n\n }, {\n key: "resolve",\n value: function resolve() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n try {\n return resolveOffsets(this.element, this.offset)[0];\n } catch (err) {\n if (this.offset === 0 && options.direction !== undefined) {\n var tw = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);\n tw.currentNode = this.element;\n var forwards = options.direction === RESOLVE_FORWARDS;\n var text =\n /** @type {Text|null} */\n forwards ? tw.nextNode() : tw.previousNode();\n\n if (!text) {\n throw err;\n }\n\n return {\n node: text,\n offset: forwards ? 0 : text.data.length\n };\n } else {\n throw err;\n }\n }\n }\n /**\n * Construct a `TextPosition` that refers to the `offset`th character within\n * `node`.\n *\n * @param {Node} node\n * @param {number} offset\n * @return {TextPosition}\n */\n\n }], [{\n key: "fromCharOffset",\n value: function fromCharOffset(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n return TextPosition.fromPoint(node, offset);\n\n case Node.ELEMENT_NODE:\n return new TextPosition(\n /** @type {Element} */\n node, offset);\n\n default:\n throw new Error(\'Node is not an element or text node\');\n }\n }\n /**\n * Construct a `TextPosition` representing the range start or end point (node, offset).\n *\n * @param {Node} node - Text or Element node\n * @param {number} offset - Offset within the node.\n * @return {TextPosition}\n */\n\n }, {\n key: "fromPoint",\n value: function fromPoint(node, offset) {\n switch (node.nodeType) {\n case Node.TEXT_NODE:\n {\n if (offset < 0 || offset >\n /** @type {Text} */\n node.data.length) {\n throw new Error(\'Text node offset is out of range\');\n }\n\n if (!node.parentElement) {\n throw new Error(\'Text node has no parent\');\n } // Get the offset from the start of the parent element.\n\n\n var textOffset = previousSiblingsTextLength(node) + offset;\n return new TextPosition(node.parentElement, textOffset);\n }\n\n case Node.ELEMENT_NODE:\n {\n if (offset < 0 || offset > node.childNodes.length) {\n throw new Error(\'Child node offset is out of range\');\n } // Get the text length before the `offset`th child of element.\n\n\n var _textOffset = 0;\n\n for (var i = 0; i < offset; i++) {\n _textOffset += nodeTextLength(node.childNodes[i]);\n }\n\n return new TextPosition(\n /** @type {Element} */\n node, _textOffset);\n }\n\n default:\n throw new Error(\'Point is not in an element or text node\');\n }\n }\n }]);\n\n return TextPosition;\n}();\n/**\n * Represents a region of a document as a (start, end) pair of `TextPosition` points.\n *\n * Representing a range in this way allows for changes in the DOM content of the\n * range which don\'t affect its text content, without affecting the text content\n * of the range itself.\n */\n\nvar text_range_TextRange = /*#__PURE__*/function () {\n /**\n * Construct an immutable `TextRange` from a `start` and `end` point.\n *\n * @param {TextPosition} start\n * @param {TextPosition} end\n */\n function TextRange(start, end) {\n _classCallCheck(this, TextRange);\n\n this.start = start;\n this.end = end;\n }\n /**\n * Return a copy of this range with start and end positions relative to a\n * given ancestor. See `TextPosition.relativeTo`.\n *\n * @param {Element} element\n */\n\n\n _createClass(TextRange, [{\n key: "relativeTo",\n value: function relativeTo(element) {\n return new TextRange(this.start.relativeTo(element), this.end.relativeTo(element));\n }\n /**\n * Resolve the `TextRange` to a DOM range.\n *\n * The resulting DOM Range will always start and end in a `Text` node.\n * Hence `TextRange.fromRange(range).toRange()` can be used to "shrink" a\n * range to the text it contains.\n *\n * May throw if the `start` or `end` positions cannot be resolved to a range.\n *\n * @return {Range}\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var start;\n var end;\n\n if (this.start.element === this.end.element && this.start.offset <= this.end.offset) {\n // Fast path for start and end points in same element.\n var _resolveOffsets = resolveOffsets(this.start.element, this.start.offset, this.end.offset);\n\n var _resolveOffsets2 = _slicedToArray(_resolveOffsets, 2);\n\n start = _resolveOffsets2[0];\n end = _resolveOffsets2[1];\n } else {\n start = this.start.resolve({\n direction: RESOLVE_FORWARDS\n });\n end = this.end.resolve({\n direction: RESOLVE_BACKWARDS\n });\n }\n\n var range = new Range();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range;\n }\n /**\n * Convert an existing DOM `Range` to a `TextRange`\n *\n * @param {Range} range\n * @return {TextRange}\n */\n\n }], [{\n key: "fromRange",\n value: function fromRange(range) {\n var start = text_range_TextPosition.fromPoint(range.startContainer, range.startOffset);\n var end = text_range_TextPosition.fromPoint(range.endContainer, range.endOffset);\n return new TextRange(start, end);\n }\n /**\n * Return a `TextRange` from the `start`th to `end`th characters in `root`.\n *\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n\n }, {\n key: "fromOffsets",\n value: function fromOffsets(root, start, end) {\n return new TextRange(new text_range_TextPosition(root, start), new text_range_TextPosition(root, end));\n }\n }]);\n\n return TextRange;\n}();\n;// CONCATENATED MODULE: ./src/vendor/hypothesis/anchoring/types.js\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction types_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction types_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction types_createClass(Constructor, protoProps, staticProps) { if (protoProps) types_defineProperties(Constructor.prototype, protoProps); if (staticProps) types_defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This module exports a set of classes for converting between DOM `Range`\n * objects and different types of selectors. It is mostly a thin wrapper around a\n * set of anchoring libraries. It serves two main purposes:\n *\n * 1. Providing a consistent interface across different types of anchors.\n * 2. Insulating the rest of the code from API changes in the underlying anchoring\n * libraries.\n */\n\n\n\n/**\n * @typedef {import(\'../../types/api\').RangeSelector} RangeSelector\n * @typedef {import(\'../../types/api\').TextPositionSelector} TextPositionSelector\n * @typedef {import(\'../../types/api\').TextQuoteSelector} TextQuoteSelector\n */\n\n/**\n * Converts between `RangeSelector` selectors and `Range` objects.\n */\n\nvar RangeAnchor = /*#__PURE__*/(/* unused pure expression or super */ null && (function () {\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n function RangeAnchor(root, range) {\n types_classCallCheck(this, RangeAnchor);\n\n this.root = root;\n this.range = range;\n }\n /**\n * @param {Node} root - A root element from which to anchor.\n * @param {Range} range - A range describing the anchor.\n */\n\n\n types_createClass(RangeAnchor, [{\n key: "toRange",\n value: function toRange() {\n return this.range;\n }\n /**\n * @return {RangeSelector}\n */\n\n }, {\n key: "toSelector",\n value: function toSelector() {\n // "Shrink" the range so that it tightly wraps its text. This ensures more\n // predictable output for a given text selection.\n var normalizedRange = TextRange.fromRange(this.range).toRange();\n var textRange = TextRange.fromRange(normalizedRange);\n var startContainer = xpathFromNode(textRange.start.element, this.root);\n var endContainer = xpathFromNode(textRange.end.element, this.root);\n return {\n type: \'RangeSelector\',\n startContainer: startContainer,\n startOffset: textRange.start.offset,\n endContainer: endContainer,\n endOffset: textRange.end.offset\n };\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n return new RangeAnchor(root, range);\n }\n /**\n * Create an anchor from a serialized `RangeSelector` selector.\n *\n * @param {Element} root - A root element from which to anchor.\n * @param {RangeSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var startContainer = nodeFromXPath(selector.startContainer, root);\n\n if (!startContainer) {\n throw new Error(\'Failed to resolve startContainer XPath\');\n }\n\n var endContainer = nodeFromXPath(selector.endContainer, root);\n\n if (!endContainer) {\n throw new Error(\'Failed to resolve endContainer XPath\');\n }\n\n var startPos = TextPosition.fromCharOffset(startContainer, selector.startOffset);\n var endPos = TextPosition.fromCharOffset(endContainer, selector.endOffset);\n var range = new TextRange(startPos, endPos).toRange();\n return new RangeAnchor(root, range);\n }\n }]);\n\n return RangeAnchor;\n}()));\n/**\n * Converts between `TextPositionSelector` selectors and `Range` objects.\n */\n\nvar TextPositionAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root\n * @param {number} start\n * @param {number} end\n */\n function TextPositionAnchor(root, start, end) {\n types_classCallCheck(this, TextPositionAnchor);\n\n this.root = root;\n this.start = start;\n this.end = end;\n }\n /**\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextPositionAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextPositionSelector}\n */\n function toSelector() {\n return {\n type: \'TextPositionSelector\',\n start: this.start,\n end: this.end\n };\n }\n }, {\n key: "toRange",\n value: function toRange() {\n return text_range_TextRange.fromOffsets(this.root, this.start, this.end).toRange();\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n return new TextPositionAnchor(root, textRange.start.offset, textRange.end.offset);\n }\n /**\n * @param {Element} root\n * @param {TextPositionSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n return new TextPositionAnchor(root, selector.start, selector.end);\n }\n }]);\n\n return TextPositionAnchor;\n}();\n/**\n * @typedef QuoteMatchOptions\n * @prop {number} [hint] - Expected position of match in text. See `matchQuote`.\n */\n\n/**\n * Converts between `TextQuoteSelector` selectors and `Range` objects.\n */\n\nvar TextQuoteAnchor = /*#__PURE__*/function () {\n /**\n * @param {Element} root - A root element from which to anchor.\n * @param {string} exact\n * @param {Object} context\n * @param {string} [context.prefix]\n * @param {string} [context.suffix]\n */\n function TextQuoteAnchor(root, exact) {\n var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n types_classCallCheck(this, TextQuoteAnchor);\n\n this.root = root;\n this.exact = exact;\n this.context = context;\n }\n /**\n * Create a `TextQuoteAnchor` from a range.\n *\n * Will throw if `range` does not contain any text nodes.\n *\n * @param {Element} root\n * @param {Range} range\n */\n\n\n types_createClass(TextQuoteAnchor, [{\n key: "toSelector",\n value:\n /**\n * @return {TextQuoteSelector}\n */\n function toSelector() {\n return {\n type: \'TextQuoteSelector\',\n exact: this.exact,\n prefix: this.context.prefix,\n suffix: this.context.suffix\n };\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toRange",\n value: function toRange() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return this.toPositionAnchor(options).toRange();\n }\n /**\n * @param {QuoteMatchOptions} [options]\n */\n\n }, {\n key: "toPositionAnchor",\n value: function toPositionAnchor() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var text =\n /** @type {string} */\n this.root.textContent;\n var match = matchQuote(text, this.exact, _objectSpread(_objectSpread({}, this.context), {}, {\n hint: options.hint\n }));\n\n if (!match) {\n throw new Error(\'Quote not found\');\n }\n\n return new TextPositionAnchor(this.root, match.start, match.end);\n }\n }], [{\n key: "fromRange",\n value: function fromRange(root, range) {\n var text =\n /** @type {string} */\n root.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(root);\n var start = textRange.start.offset;\n var end = textRange.end.offset; // Number of characters around the quote to capture as context. We currently\n // always use a fixed amount, but it would be better if this code was aware\n // of logical boundaries in the document (paragraph, article etc.) to avoid\n // capturing text unrelated to the quote.\n //\n // In regular prose the ideal content would often be the surrounding sentence.\n // This is a natural unit of meaning which enables displaying quotes in\n // context even when the document is not available. We could use `Intl.Segmenter`\n // for this when available.\n\n var contextLen = 32;\n return new TextQuoteAnchor(root, text.slice(start, end), {\n prefix: text.slice(Math.max(0, start - contextLen), start),\n suffix: text.slice(end, Math.min(text.length, end + contextLen))\n });\n }\n /**\n * @param {Element} root\n * @param {TextQuoteSelector} selector\n */\n\n }, {\n key: "fromSelector",\n value: function fromSelector(root, selector) {\n var prefix = selector.prefix,\n suffix = selector.suffix;\n return new TextQuoteAnchor(root, selector.exact, {\n prefix: prefix,\n suffix: suffix\n });\n }\n }]);\n\n return TextQuoteAnchor;\n}();\n;// CONCATENATED MODULE: ./src/utils.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = utils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction utils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return utils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return utils_arrayLikeToArray(o, minLen); }\n\nfunction utils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n // Catch JS errors to log them in the app.\n\nwindow.addEventListener("error", function (event) {\n Android.logError(event.message, event.filename, event.lineno);\n}, false);\nwindow.addEventListener("load", function () {\n var observer = new ResizeObserver(function () {\n onViewportWidthChanged();\n snapCurrentOffset();\n });\n observer.observe(document.body);\n}, false);\n/**\n * Having an odd number of columns when displaying two columns per screen causes snapping and page\n * turning issues. To fix this, we insert a blank virtual column at the end of the resource.\n */\n\nfunction appendVirtualColumnIfNeeded() {\n var id = "readium-virtual-page";\n var virtualCol = document.getElementById(id);\n\n if (isScrollModeEnabled() || getColumnCountPerScreen() != 2) {\n if (virtualCol) {\n virtualCol.remove();\n }\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var colCount = documentWidth / pageWidth;\n var hasOddColCount = Math.round(colCount * 2) / 2 % 1 > 0.1;\n\n if (hasOddColCount) {\n if (virtualCol) {\n virtualCol.remove();\n } else {\n virtualCol = document.createElement("div");\n virtualCol.setAttribute("id", id);\n virtualCol.style.breakBefore = "column";\n virtualCol.innerHTML = "​"; // zero-width space\n\n document.body.appendChild(virtualCol);\n }\n }\n }\n}\n\nvar pageWidth = 1;\n\nfunction onViewportWidthChanged() {\n // We can\'t rely on window.innerWidth for the pageWidth on Android, because if the\n // device pixel ratio is not an integer, we get rounding issues offsetting the pages.\n //\n // See https://github.com/readium/readium-css/issues/97\n // and https://github.com/readium/r2-navigator-kotlin/issues/146\n var width = Android.getViewportWidth();\n pageWidth = width / window.devicePixelRatio;\n setProperty("--RS__viewportWidth", "calc(" + width + "px / " + window.devicePixelRatio + ")");\n appendVirtualColumnIfNeeded();\n}\n\nfunction getColumnCountPerScreen() {\n return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n}\nfunction isScrollModeEnabled() {\n var style = document.documentElement.style;\n return style.getPropertyValue("--USER__view").trim() == "readium-scroll-on" || // FIXME: Will need to be removed in Readium 3.0, --USER__scroll was incorrect.\n style.getPropertyValue("--USER__scroll").trim() == "readium-scroll-on";\n}\nfunction isRTL() {\n return document.body.dir.toLowerCase() == "rtl";\n} // Scroll to the given TagId in document and snap.\n\nfunction scrollToId(id) {\n var element = document.getElementById(id);\n\n if (!element) {\n return false;\n }\n\n return scrollToRect(element.getBoundingClientRect());\n} // Position must be in the range [0 - 1], 0-100%.\n\nfunction scrollToPosition(position) {\n // Android.log("scrollToPosition " + position);\n if (position < 0 || position > 1) {\n throw "scrollToPosition() must be given a position from 0.0 to 1.0";\n }\n\n var offset;\n\n if (isScrollModeEnabled()) {\n offset = document.scrollingElement.scrollHeight * position;\n document.scrollingElement.scrollTop = offset; // window.scrollTo(0, offset);\n } else {\n var documentWidth = document.scrollingElement.scrollWidth;\n var factor = isRTL() ? -1 : 1;\n offset = documentWidth * position * factor;\n document.scrollingElement.scrollLeft = snapOffset(offset);\n }\n} // Scrolls to the first occurrence of the given text snippet.\n//\n// The expected text argument is a Locator Text object, as defined here:\n// https://readium.org/architecture/models/locators/\n\nfunction scrollToText(text) {\n var range = rangeFromLocator({\n text: text\n });\n\n if (!range) {\n return false;\n }\n\n scrollToRange(range);\n return true;\n}\n\nfunction scrollToRange(range) {\n return scrollToRect(range.getBoundingClientRect());\n}\n\nfunction scrollToRect(rect) {\n if (isScrollModeEnabled()) {\n document.scrollingElement.scrollTop = rect.top + window.scrollY - window.innerHeight / 2;\n } else {\n document.scrollingElement.scrollLeft = snapOffset(rect.left + window.scrollX);\n }\n\n return true;\n}\n\nfunction scrollToStart() {\n // Android.log("scrollToStart");\n if (!isScrollModeEnabled()) {\n document.scrollingElement.scrollLeft = 0;\n } else {\n document.scrollingElement.scrollTop = 0;\n window.scrollTo(0, 0);\n }\n}\nfunction scrollToEnd() {\n // Android.log("scrollToEnd");\n if (!isScrollModeEnabled()) {\n var factor = isRTL() ? -1 : 1;\n document.scrollingElement.scrollLeft = snapOffset(document.scrollingElement.scrollWidth * factor);\n } else {\n document.scrollingElement.scrollTop = document.body.scrollHeight;\n window.scrollTo(0, document.body.scrollHeight);\n }\n} // Returns false if the page is already at the left-most scroll offset.\n\nfunction scrollLeft() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX - pageWidth;\n var minOffset = isRTL() ? -(documentWidth - pageWidth) : 0;\n return scrollToOffset(Math.max(offset, minOffset));\n} // Returns false if the page is already at the right-most scroll offset.\n\nfunction scrollRight() {\n var documentWidth = document.scrollingElement.scrollWidth;\n var offset = window.scrollX + pageWidth;\n var maxOffset = isRTL() ? 0 : documentWidth - pageWidth;\n return scrollToOffset(Math.min(offset, maxOffset));\n} // Scrolls to the given left offset.\n// Returns false if the page scroll position is already close enough to the given offset.\n\nfunction scrollToOffset(offset) {\n // Android.log("scrollToOffset " + offset);\n if (isScrollModeEnabled()) {\n throw "Called scrollToOffset() with scroll mode enabled. This can only be used in paginated mode.";\n }\n\n var currentOffset = window.scrollX;\n document.scrollingElement.scrollLeft = snapOffset(offset); // In some case the scrollX cannot reach the position respecting to innerWidth\n\n var diff = Math.abs(currentOffset - offset) / pageWidth;\n return diff > 0.01;\n} // Snap the offset to the screen width (page width).\n\n\nfunction snapOffset(offset) {\n var value = offset + (isRTL() ? -1 : 1);\n return value - value % pageWidth;\n} // Snaps the current offset to the page width.\n\n\nfunction snapCurrentOffset() {\n // Android.log("snapCurrentOffset");\n if (isScrollModeEnabled()) {\n return;\n }\n\n var currentOffset = window.scrollX; // Adds half a page to make sure we don\'t snap to the previous page.\n\n var factor = isRTL() ? -1 : 1;\n var delta = factor * (pageWidth / 2);\n document.scrollingElement.scrollLeft = snapOffset(currentOffset + delta);\n}\nfunction rangeFromLocator(locator) {\n try {\n var locations = locator.locations;\n var text = locator.text;\n\n if (text && text.highlight) {\n var root;\n\n if (locations && locations.cssSelector) {\n root = document.querySelector(locations.cssSelector);\n }\n\n if (!root) {\n root = document.body;\n }\n\n var anchor = new TextQuoteAnchor(root, text.highlight, {\n prefix: text.before,\n suffix: text.after\n });\n return anchor.toRange();\n }\n\n if (locations) {\n var element = null;\n\n if (!element && locations.cssSelector) {\n element = document.querySelector(locations.cssSelector);\n }\n\n if (!element && locations.fragments) {\n var _iterator = _createForOfIteratorHelper(locations.fragments),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var htmlId = _step.value;\n element = document.getElementById(htmlId);\n\n if (element) {\n break;\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n if (element) {\n var range = document.createRange();\n range.setStartBefore(element);\n range.setEndAfter(element);\n return range;\n }\n }\n } catch (e) {\n logError(e);\n }\n\n return null;\n} /// User Settings.\n\nfunction setCSSProperties(properties) {\n for (var name in properties) {\n setProperty(name, properties[name]);\n }\n} // For setting user setting.\n\nfunction setProperty(key, value) {\n if (value === null || value === "") {\n removeProperty(key);\n } else {\n var root = document.documentElement; // The `!important` annotation is added with `setProperty()` because if it\'s part of the\n // `value`, it will be ignored by the Web View.\n\n root.style.setProperty(key, value, "important");\n }\n} // For removing user setting.\n\nfunction removeProperty(key) {\n var root = document.documentElement;\n root.style.removeProperty(key);\n} /// Toolkit\n\nfunction log() {\n var message = Array.prototype.slice.call(arguments).join(" ");\n Android.log(message);\n}\nfunction logError(message) {\n Android.logError(message, "", 0);\n}\n;// CONCATENATED MODULE: ./src/rect.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction rect_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = rect_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction rect_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return rect_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return rect_arrayLikeToArray(o, minLen); }\n\nfunction rect_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nvar debug = false;\n/**\n * Converts a DOMRect into a JSON object understandable by the native side.\n */\n\nfunction toNativeRect(rect) {\n var pixelRatio = window.devicePixelRatio;\n var width = rect.width * pixelRatio;\n var height = rect.height * pixelRatio;\n var left = rect.left * pixelRatio;\n var top = rect.top * pixelRatio;\n var right = left + width;\n var bottom = top + height;\n return {\n width: width,\n height: height,\n left: left,\n top: top,\n right: right,\n bottom: bottom\n };\n}\nfunction getClientRectsNoOverlap(range, doNotMergeHorizontallyAlignedRects) {\n var clientRects = range.getClientRects();\n var tolerance = 1;\n var originalRects = [];\n\n var _iterator = rect_createForOfIteratorHelper(clientRects),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var rangeClientRect = _step.value;\n originalRects.push({\n bottom: rangeClientRect.bottom,\n height: rangeClientRect.height,\n left: rangeClientRect.left,\n right: rangeClientRect.right,\n top: rangeClientRect.top,\n width: rangeClientRect.width\n });\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n var mergedRects = mergeTouchingRects(originalRects, tolerance, doNotMergeHorizontallyAlignedRects);\n var noContainedRects = removeContainedRects(mergedRects, tolerance);\n var newRects = replaceOverlapingRects(noContainedRects);\n var minArea = 2 * 2;\n\n for (var j = newRects.length - 1; j >= 0; j--) {\n var rect = newRects[j];\n var bigEnough = rect.width * rect.height > minArea;\n\n if (!bigEnough) {\n if (newRects.length > 1) {\n rect_log("CLIENT RECT: remove small");\n newRects.splice(j, 1);\n } else {\n rect_log("CLIENT RECT: remove small, but keep otherwise empty!");\n break;\n }\n }\n }\n\n rect_log("CLIENT RECT: reduced ".concat(originalRects.length, " --\x3e ").concat(newRects.length));\n return newRects;\n}\n\nfunction mergeTouchingRects(rects, tolerance, doNotMergeHorizontallyAlignedRects) {\n for (var i = 0; i < rects.length; i++) {\n var _loop = function _loop(j) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("mergeTouchingRects rect1 === rect2 ??!");\n return "continue";\n }\n\n var rectsLineUpVertically = almostEqual(rect1.top, rect2.top, tolerance) && almostEqual(rect1.bottom, rect2.bottom, tolerance);\n var rectsLineUpHorizontally = almostEqual(rect1.left, rect2.left, tolerance) && almostEqual(rect1.right, rect2.right, tolerance);\n var horizontalAllowed = !doNotMergeHorizontallyAlignedRects;\n var aligned = rectsLineUpHorizontally && horizontalAllowed || rectsLineUpVertically && !rectsLineUpHorizontally;\n var canMerge = aligned && rectsTouchOrOverlap(rect1, rect2, tolerance);\n\n if (canMerge) {\n rect_log("CLIENT RECT: merging two into one, VERTICAL: ".concat(rectsLineUpVertically, " HORIZONTAL: ").concat(rectsLineUpHorizontally, " (").concat(doNotMergeHorizontallyAlignedRects, ")"));\n var newRects = rects.filter(function (rect) {\n return rect !== rect1 && rect !== rect2;\n });\n var replacementClientRect = getBoundingRect(rect1, rect2);\n newRects.push(replacementClientRect);\n return {\n v: mergeTouchingRects(newRects, tolerance, doNotMergeHorizontallyAlignedRects)\n };\n }\n };\n\n for (var j = i + 1; j < rects.length; j++) {\n var _ret = _loop(j);\n\n if (_ret === "continue") continue;\n if (_typeof(_ret) === "object") return _ret.v;\n }\n }\n\n return rects;\n}\n\nfunction getBoundingRect(rect1, rect2) {\n var left = Math.min(rect1.left, rect2.left);\n var right = Math.max(rect1.right, rect2.right);\n var top = Math.min(rect1.top, rect2.top);\n var bottom = Math.max(rect1.bottom, rect2.bottom);\n return {\n bottom: bottom,\n height: bottom - top,\n left: left,\n right: right,\n top: top,\n width: right - left\n };\n}\n\nfunction removeContainedRects(rects, tolerance) {\n var rectsToKeep = new Set(rects);\n\n var _iterator2 = rect_createForOfIteratorHelper(rects),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var rect = _step2.value;\n var bigEnough = rect.width > 1 && rect.height > 1;\n\n if (!bigEnough) {\n rect_log("CLIENT RECT: remove tiny");\n rectsToKeep.delete(rect);\n continue;\n }\n\n var _iterator3 = rect_createForOfIteratorHelper(rects),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var possiblyContainingRect = _step3.value;\n\n if (rect === possiblyContainingRect) {\n continue;\n }\n\n if (!rectsToKeep.has(possiblyContainingRect)) {\n continue;\n }\n\n if (rectContains(possiblyContainingRect, rect, tolerance)) {\n rect_log("CLIENT RECT: remove contained");\n rectsToKeep.delete(rect);\n break;\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n return Array.from(rectsToKeep);\n}\n\nfunction rectContains(rect1, rect2, tolerance) {\n return rectContainsPoint(rect1, rect2.left, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.top, tolerance) && rectContainsPoint(rect1, rect2.left, rect2.bottom, tolerance) && rectContainsPoint(rect1, rect2.right, rect2.bottom, tolerance);\n}\n\nfunction rectContainsPoint(rect, x, y, tolerance) {\n return (rect.left < x || almostEqual(rect.left, x, tolerance)) && (rect.right > x || almostEqual(rect.right, x, tolerance)) && (rect.top < y || almostEqual(rect.top, y, tolerance)) && (rect.bottom > y || almostEqual(rect.bottom, y, tolerance));\n}\n\nfunction replaceOverlapingRects(rects) {\n for (var i = 0; i < rects.length; i++) {\n for (var j = i + 1; j < rects.length; j++) {\n var rect1 = rects[i];\n var rect2 = rects[j];\n\n if (rect1 === rect2) {\n rect_log("replaceOverlapingRects rect1 === rect2 ??!");\n continue;\n }\n\n if (rectsTouchOrOverlap(rect1, rect2, -1)) {\n var _ret2 = function () {\n var toAdd = [];\n var toRemove = void 0;\n var subtractRects1 = rectSubtract(rect1, rect2);\n\n if (subtractRects1.length === 1) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n var subtractRects2 = rectSubtract(rect2, rect1);\n\n if (subtractRects1.length < subtractRects2.length) {\n toAdd = subtractRects1;\n toRemove = rect1;\n } else {\n toAdd = subtractRects2;\n toRemove = rect2;\n }\n }\n\n rect_log("CLIENT RECT: overlap, cut one rect into ".concat(toAdd.length));\n var newRects = rects.filter(function (rect) {\n return rect !== toRemove;\n });\n Array.prototype.push.apply(newRects, toAdd);\n return {\n v: replaceOverlapingRects(newRects)\n };\n }();\n\n if (_typeof(_ret2) === "object") return _ret2.v;\n }\n }\n }\n\n return rects;\n}\n\nfunction rectSubtract(rect1, rect2) {\n var rectIntersected = rectIntersect(rect2, rect1);\n\n if (rectIntersected.height === 0 || rectIntersected.width === 0) {\n return [rect1];\n }\n\n var rects = [];\n {\n var rectA = {\n bottom: rect1.bottom,\n height: 0,\n left: rect1.left,\n right: rectIntersected.left,\n top: rect1.top,\n width: 0\n };\n rectA.width = rectA.right - rectA.left;\n rectA.height = rectA.bottom - rectA.top;\n\n if (rectA.height !== 0 && rectA.width !== 0) {\n rects.push(rectA);\n }\n }\n {\n var rectB = {\n bottom: rectIntersected.top,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rect1.top,\n width: 0\n };\n rectB.width = rectB.right - rectB.left;\n rectB.height = rectB.bottom - rectB.top;\n\n if (rectB.height !== 0 && rectB.width !== 0) {\n rects.push(rectB);\n }\n }\n {\n var rectC = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.left,\n right: rectIntersected.right,\n top: rectIntersected.bottom,\n width: 0\n };\n rectC.width = rectC.right - rectC.left;\n rectC.height = rectC.bottom - rectC.top;\n\n if (rectC.height !== 0 && rectC.width !== 0) {\n rects.push(rectC);\n }\n }\n {\n var rectD = {\n bottom: rect1.bottom,\n height: 0,\n left: rectIntersected.right,\n right: rect1.right,\n top: rect1.top,\n width: 0\n };\n rectD.width = rectD.right - rectD.left;\n rectD.height = rectD.bottom - rectD.top;\n\n if (rectD.height !== 0 && rectD.width !== 0) {\n rects.push(rectD);\n }\n }\n return rects;\n}\n\nfunction rectIntersect(rect1, rect2) {\n var maxLeft = Math.max(rect1.left, rect2.left);\n var minRight = Math.min(rect1.right, rect2.right);\n var maxTop = Math.max(rect1.top, rect2.top);\n var minBottom = Math.min(rect1.bottom, rect2.bottom);\n return {\n bottom: minBottom,\n height: Math.max(0, minBottom - maxTop),\n left: maxLeft,\n right: minRight,\n top: maxTop,\n width: Math.max(0, minRight - maxLeft)\n };\n}\n\nfunction rectsTouchOrOverlap(rect1, rect2, tolerance) {\n return (rect1.left < rect2.right || tolerance >= 0 && almostEqual(rect1.left, rect2.right, tolerance)) && (rect2.left < rect1.right || tolerance >= 0 && almostEqual(rect2.left, rect1.right, tolerance)) && (rect1.top < rect2.bottom || tolerance >= 0 && almostEqual(rect1.top, rect2.bottom, tolerance)) && (rect2.top < rect1.bottom || tolerance >= 0 && almostEqual(rect2.top, rect1.bottom, tolerance));\n}\n\nfunction almostEqual(a, b, tolerance) {\n return Math.abs(a - b) <= tolerance;\n}\n\nfunction rect_log() {\n if (debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/decorator.js\nfunction decorator_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = decorator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction decorator_slicedToArray(arr, i) { return decorator_arrayWithHoles(arr) || decorator_iterableToArrayLimit(arr, i) || decorator_unsupportedIterableToArray(arr, i) || decorator_nonIterableRest(); }\n\nfunction decorator_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\n\nfunction decorator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return decorator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return decorator_arrayLikeToArray(o, minLen); }\n\nfunction decorator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction decorator_iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction decorator_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\nvar styles = new Map();\nvar groups = new Map();\nvar lastGroupId = 0;\n/**\n * Registers a list of additional supported Decoration Templates.\n *\n * Each template object is indexed by the style ID.\n */\n\nfunction registerTemplates(newStyles) {\n var stylesheet = "";\n\n for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = decorator_slicedToArray(_Object$entries[_i], 2),\n id = _Object$entries$_i[0],\n style = _Object$entries$_i[1];\n\n styles.set(id, style);\n\n if (style.stylesheet) {\n stylesheet += style.stylesheet + "\\n";\n }\n }\n\n if (stylesheet) {\n var styleElement = document.createElement("style");\n styleElement.innerHTML = stylesheet;\n document.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n}\n/**\n * Returns an instance of DecorationGroup for the given group name.\n */\n\nfunction getDecorations(groupName) {\n var group = groups.get(groupName);\n\n if (!group) {\n var id = "r2-decoration-" + lastGroupId++;\n group = DecorationGroup(id, groupName);\n groups.set(groupName, group);\n }\n\n return group;\n}\n/**\n * Handles click events on a Decoration.\n * Returns whether a decoration matched this event.\n */\n\nfunction handleDecorationClickEvent(event, clickEvent) {\n if (groups.size === 0) {\n return false;\n }\n\n function findTarget() {\n var _iterator = decorator_createForOfIteratorHelper(groups),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = decorator_slicedToArray(_step.value, 2),\n group = _step$value[0],\n groupContent = _step$value[1];\n\n var _iterator2 = decorator_createForOfIteratorHelper(groupContent.items.reverse()),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var item = _step2.value;\n\n if (!item.clickableElements) {\n continue;\n }\n\n var _iterator3 = decorator_createForOfIteratorHelper(item.clickableElements),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var element = _step3.value;\n var rect = element.getBoundingClientRect().toJSON();\n\n if (rectContainsPoint(rect, event.clientX, event.clientY, 1)) {\n return {\n group: group,\n item: item,\n element: element,\n rect: rect\n };\n }\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var target = findTarget();\n\n if (!target) {\n return false;\n }\n\n return Android.onDecorationActivated(JSON.stringify({\n id: target.item.decoration.id,\n group: target.group,\n rect: toNativeRect(target.item.range.getBoundingClientRect()),\n click: clickEvent\n }));\n}\n/**\n * Creates a DecorationGroup object from a unique HTML ID and its name.\n */\n\nfunction DecorationGroup(groupId, groupName) {\n var items = [];\n var lastItemId = 0;\n var container = null;\n /**\n * Adds a new decoration to the group.\n */\n\n function add(decoration) {\n var id = groupId + "-" + lastItemId++;\n var range = rangeFromLocator(decoration.locator);\n\n if (!range) {\n log("Can\'t locate DOM range for decoration", decoration);\n return;\n }\n\n var item = {\n id: id,\n decoration: decoration,\n range: range\n };\n items.push(item);\n layout(item);\n }\n /**\n * Removes the decoration with given ID from the group.\n */\n\n\n function remove(decorationId) {\n var index = items.findIndex(function (i) {\n return i.decoration.id === decorationId;\n });\n\n if (index === -1) {\n return;\n }\n\n var item = items[index];\n items.splice(index, 1);\n item.clickableElements = null;\n\n if (item.container) {\n item.container.remove();\n item.container = null;\n }\n }\n /**\n * Notifies that the given decoration was modified and needs to be updated.\n */\n\n\n function update(decoration) {\n remove(decoration.id);\n add(decoration);\n }\n /**\n * Removes all decorations from this group.\n */\n\n\n function clear() {\n clearContainer();\n items.length = 0;\n }\n /**\n * Recreates the decoration elements.\n *\n * To be called after reflowing the resource, for example.\n */\n\n\n function requestLayout() {\n clearContainer();\n items.forEach(function (item) {\n return layout(item);\n });\n }\n /**\n * Layouts a single Decoration item.\n */\n\n\n function layout(item) {\n var groupContainer = requireContainer();\n var style = styles.get(item.decoration.style);\n\n if (!style) {\n logError("Unknown decoration style: ".concat(item.decoration.style));\n return;\n }\n\n var itemContainer = document.createElement("div");\n itemContainer.setAttribute("id", item.id);\n itemContainer.setAttribute("data-style", item.decoration.style);\n itemContainer.style.setProperty("pointer-events", "none");\n var viewportWidth = window.innerWidth;\n var columnCount = parseInt(getComputedStyle(document.documentElement).getPropertyValue("column-count"));\n var pageWidth = viewportWidth / (columnCount || 1);\n var scrollingElement = document.scrollingElement;\n var xOffset = scrollingElement.scrollLeft;\n var yOffset = scrollingElement.scrollTop;\n\n function positionElement(element, rect, boundingRect) {\n element.style.position = "absolute";\n\n if (style.width === "wrap") {\n element.style.width = "".concat(rect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(rect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "viewport") {\n element.style.width = "".concat(viewportWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n var left = Math.floor(rect.left / viewportWidth) * viewportWidth;\n element.style.left = "".concat(left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "bounds") {\n element.style.width = "".concat(boundingRect.width, "px");\n element.style.height = "".concat(rect.height, "px");\n element.style.left = "".concat(boundingRect.left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n } else if (style.width === "page") {\n element.style.width = "".concat(pageWidth, "px");\n element.style.height = "".concat(rect.height, "px");\n\n var _left = Math.floor(rect.left / pageWidth) * pageWidth;\n\n element.style.left = "".concat(_left + xOffset, "px");\n element.style.top = "".concat(rect.top + yOffset, "px");\n }\n }\n\n var boundingRect = item.range.getBoundingClientRect();\n var elementTemplate;\n\n try {\n var template = document.createElement("template");\n template.innerHTML = item.decoration.element.trim();\n elementTemplate = template.content.firstElementChild;\n } catch (error) {\n logError("Invalid decoration element \\"".concat(item.decoration.element, "\\": ").concat(error.message));\n return;\n }\n\n if (style.layout === "boxes") {\n var doNotMergeHorizontallyAlignedRects = true;\n var clientRects = getClientRectsNoOverlap(item.range, doNotMergeHorizontallyAlignedRects);\n clientRects = clientRects.sort(function (r1, r2) {\n if (r1.top < r2.top) {\n return -1;\n } else if (r1.top > r2.top) {\n return 1;\n } else {\n return 0;\n }\n });\n\n var _iterator4 = decorator_createForOfIteratorHelper(clientRects),\n _step4;\n\n try {\n for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {\n var clientRect = _step4.value;\n var line = elementTemplate.cloneNode(true);\n line.style.setProperty("pointer-events", "none");\n positionElement(line, clientRect, boundingRect);\n itemContainer.append(line);\n }\n } catch (err) {\n _iterator4.e(err);\n } finally {\n _iterator4.f();\n }\n } else if (style.layout === "bounds") {\n var bounds = elementTemplate.cloneNode(true);\n bounds.style.setProperty("pointer-events", "none");\n positionElement(bounds, boundingRect, boundingRect);\n itemContainer.append(bounds);\n }\n\n groupContainer.append(itemContainer);\n item.container = itemContainer;\n item.clickableElements = Array.from(itemContainer.querySelectorAll("[data-activable=\'1\']"));\n\n if (item.clickableElements.length === 0) {\n item.clickableElements = Array.from(itemContainer.children);\n }\n }\n /**\n * Returns the group container element, after making sure it exists.\n */\n\n\n function requireContainer() {\n if (!container) {\n container = document.createElement("div");\n container.setAttribute("id", groupId);\n container.setAttribute("data-group", groupName);\n container.style.setProperty("pointer-events", "none");\n document.body.append(container);\n }\n\n return container;\n }\n /**\n * Removes the group container.\n */\n\n\n function clearContainer() {\n if (container) {\n container.remove();\n container = null;\n }\n }\n\n return {\n add: add,\n remove: remove,\n update: update,\n clear: clear,\n items: items,\n requestLayout: requestLayout\n };\n}\nwindow.addEventListener("load", function () {\n // Will relayout all the decorations when the document body is resized.\n var body = document.body;\n var lastSize = {\n width: 0,\n height: 0\n };\n var observer = new ResizeObserver(function () {\n if (lastSize.width === body.clientWidth && lastSize.height === body.clientHeight) {\n return;\n }\n\n lastSize = {\n width: body.clientWidth,\n height: body.clientHeight\n };\n groups.forEach(function (group) {\n group.requestLayout();\n });\n });\n observer.observe(body);\n}, false);\n// EXTERNAL MODULE: ./node_modules/css-selector-generator/build/index.js\nvar build = __webpack_require__(4766);\n;// CONCATENATED MODULE: ./src/dom.js\n//\n// Copyright 2022 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n // See. https://github.com/JayPanoz/architecture/tree/touch-handling/misc/touch-handling\n\nfunction nearestInteractiveElement(element) {\n if (element == null) {\n return null;\n }\n\n var interactiveTags = ["a", "audio", "button", "canvas", "details", "input", "label", "option", "select", "submit", "textarea", "video"];\n\n if (interactiveTags.indexOf(element.nodeName.toLowerCase()) != -1) {\n return element.outerHTML;\n } // Checks whether the element is editable by the user.\n\n\n if (element.hasAttribute("contenteditable") && element.getAttribute("contenteditable").toLowerCase() != "false") {\n return element.outerHTML;\n } // Checks parents recursively because the touch might be for example on an inside a .\n\n\n if (element.parentElement) {\n return nearestInteractiveElement(element.parentElement);\n }\n\n return null;\n}\nfunction findFirstVisibleLocator() {\n var element = findElement(document.body);\n return {\n href: "#",\n type: "application/xhtml+xml",\n locations: {\n cssSelector: (0,build.getCssSelector)(element)\n },\n text: {\n highlight: element.textContent\n }\n };\n}\n\nfunction findElement(rootElement) {\n for (var i = 0; i < rootElement.children.length; i++) {\n var child = rootElement.children[i];\n\n if (!shouldIgnoreElement(child) && isElementVisible(child)) {\n return findElement(child);\n }\n }\n\n return rootElement;\n}\n\nfunction isElementVisible(element) {\n if (readium.isFixedLayout) return true;\n\n if (element === document.body || element === document.documentElement) {\n return true;\n }\n\n if (!document || !document.documentElement || !document.body) {\n return false;\n }\n\n var rect = element.getBoundingClientRect();\n\n if (isScrollModeEnabled()) {\n return rect.bottom > 0 && rect.top < window.innerHeight;\n } else {\n return rect.right > 0 && rect.left < window.innerWidth;\n }\n}\n\nfunction shouldIgnoreElement(element) {\n var elStyle = getComputedStyle(element);\n\n if (elStyle) {\n var display = elStyle.getPropertyValue("display");\n\n if (display != "block") {\n return true;\n } // Cannot be relied upon, because web browser engine reports invisible when out of view in\n // scrolled columns!\n // const visibility = elStyle.getPropertyValue("visibility");\n // if (visibility === "hidden") {\n // return false;\n // }\n\n\n var opacity = elStyle.getPropertyValue("opacity");\n\n if (opacity === "0") {\n return true;\n }\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./src/gestures.js\n/*\n * Copyright 2021 Readium Foundation. All rights reserved.\n * Use of this source code is governed by the BSD-style license\n * available in the top-level LICENSE file of the project.\n */\n\n\nwindow.addEventListener("DOMContentLoaded", function () {\n document.addEventListener("click", onClick, false);\n bindDragGesture(document);\n});\n\nfunction onClick(event) {\n if (!window.getSelection().isCollapsed) {\n // There\'s an on-going selection, the tap will dismiss it so we don\'t forward it.\n return;\n }\n\n var pixelRatio = window.devicePixelRatio;\n var clickEvent = {\n defaultPrevented: event.defaultPrevented,\n x: event.clientX * pixelRatio,\n y: event.clientY * pixelRatio,\n targetElement: event.target.outerHTML,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n\n if (handleDecorationClickEvent(event, clickEvent)) {\n return;\n } // Send the tap data over the JS bridge even if it\'s been handled within the web view, so that\n // it can be preserved and used by the toolkit if needed.\n\n\n var shouldPreventDefault = Android.onTap(JSON.stringify(clickEvent));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n}\n\nfunction bindDragGesture(element) {\n // passive: false is necessary to be able to prevent the default behavior.\n element.addEventListener("touchstart", onStart, {\n passive: false\n });\n element.addEventListener("touchend", onEnd, {\n passive: false\n });\n element.addEventListener("touchmove", onMove, {\n passive: false\n });\n var state = undefined;\n var isStartingDrag = false;\n var pixelRatio = window.devicePixelRatio;\n\n function onStart(event) {\n isStartingDrag = true;\n var startX = event.touches[0].clientX * pixelRatio;\n var startY = event.touches[0].clientY * pixelRatio;\n state = {\n defaultPrevented: event.defaultPrevented,\n startX: startX,\n startY: startY,\n currentX: startX,\n currentY: startY,\n offsetX: 0,\n offsetY: 0,\n interactiveElement: nearestInteractiveElement(event.target)\n };\n }\n\n function onMove(event) {\n if (!state) return;\n state.currentX = event.touches[0].clientX * pixelRatio;\n state.currentY = event.touches[0].clientY * pixelRatio;\n state.offsetX = state.currentX - state.startX;\n state.offsetY = state.currentY - state.startY;\n var shouldPreventDefault = false; // Wait for a movement of at least 6 pixels before reporting a drag.\n\n if (isStartingDrag) {\n if (Math.abs(state.offsetX) >= 6 || Math.abs(state.offsetY) >= 6) {\n isStartingDrag = false;\n shouldPreventDefault = Android.onDragStart(JSON.stringify(state));\n }\n } else {\n shouldPreventDefault = Android.onDragMove(JSON.stringify(state));\n }\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n }\n\n function onEnd(event) {\n if (!state) return;\n var shouldPreventDefault = Android.onDragEnd(JSON.stringify(state));\n\n if (shouldPreventDefault) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n state = undefined;\n }\n}\n;// CONCATENATED MODULE: ./src/keyboard.js\n//\n// Copyright 2023 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\nwindow.addEventListener("keydown", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "down");\n});\nwindow.addEventListener("keyup", function (event) {\n if (shouldIgnoreEvent(event)) {\n return;\n }\n\n preventDefault(event);\n sendPressKeyMessage(event, "up");\n});\n\nfunction shouldIgnoreEvent(event) {\n return event.defaultPrevented || nearestInteractiveElement(document.activeElement) != null;\n} // We prevent the default behavior for keyboard events, otherwise the web view\n// might scroll.\n\n\nfunction preventDefault(event) {\n event.stopPropagation();\n event.preventDefault();\n}\n\nfunction sendPressKeyMessage(event, type) {\n if (event.repeat) return;\n var keyEvent = {\n type: type,\n code: event.code,\n characters: String.fromCharCode(event.keyCode),\n alt: event.altKey,\n control: event.ctrlKey,\n shift: event.shiftKey,\n meta: event.metaKey\n };\n Android.onKey(JSON.stringify(keyEvent));\n}\n// EXTERNAL MODULE: ./node_modules/string.prototype.matchall/index.js\nvar string_prototype_matchall = __webpack_require__(4956);\nvar string_prototype_matchall_default = /*#__PURE__*/__webpack_require__.n(string_prototype_matchall);\n;// CONCATENATED MODULE: ./src/selection.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n\n\n // Polyfill for Android API 26\n\n\nstring_prototype_matchall_default().shim();\nvar selection_debug = true; // Notify native code that the selection changes.\n\nwindow.addEventListener("load", function () {\n var isSelecting = false;\n document.addEventListener("selectionchange", function () {\n var collapsed = window.getSelection().isCollapsed;\n\n if (collapsed && isSelecting) {\n isSelecting = false;\n Android.onSelectionEnd(); // Snaps the current column in case the user shifted the scroll by dragging the text selection.\n\n snapCurrentOffset();\n } else if (!collapsed && !isSelecting) {\n isSelecting = true;\n Android.onSelectionStart();\n }\n });\n}, false);\nfunction getCurrentSelection() {\n var text = getCurrentSelectionText();\n\n if (!text) {\n return null;\n }\n\n var rect = getSelectionRect();\n return {\n text: text,\n rect: rect\n };\n}\n\nfunction getSelectionRect() {\n try {\n var sel = window.getSelection();\n\n if (!sel) {\n return;\n }\n\n var range = sel.getRangeAt(0);\n return toNativeRect(range.getBoundingClientRect());\n } catch (e) {\n logError(e);\n return null;\n }\n}\n\nfunction getCurrentSelectionText() {\n var selection = window.getSelection();\n\n if (!selection) {\n return undefined;\n }\n\n if (selection.isCollapsed) {\n return undefined;\n }\n\n var highlight = selection.toString();\n var cleanHighlight = highlight.trim().replace(/\\n/g, " ").replace(/\\s\\s+/g, " ");\n\n if (cleanHighlight.length === 0) {\n return undefined;\n }\n\n if (!selection.anchorNode || !selection.focusNode) {\n return undefined;\n }\n\n var range = selection.rangeCount === 1 ? selection.getRangeAt(0) : createOrderedRange(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);\n\n if (!range || range.collapsed) {\n selection_log("$$$$$$$$$$$$$$$$$ CANNOT GET NON-COLLAPSED SELECTION RANGE?!");\n return undefined;\n }\n\n var text = document.body.textContent;\n var textRange = text_range_TextRange.fromRange(range).relativeTo(document.body);\n var start = textRange.start.offset;\n var end = textRange.end.offset;\n var snippetLength = 200; // Compute the text before the highlight, ignoring the first "word", which might be cut.\n\n var before = text.slice(Math.max(0, start - snippetLength), start);\n var firstWordStart = before.search(/(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])/g);\n\n if (firstWordStart !== -1) {\n before = before.slice(firstWordStart + 1);\n } // Compute the text after the highlight, ignoring the last "word", which might be cut.\n\n\n var after = text.slice(end, Math.min(text.length, end + snippetLength));\n var lastWordEnd = Array.from(after.matchAll(/(?:[A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088E\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5D\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7CA\\uA7D0\\uA7D1\\uA7D3\\uA7D5-\\uA7D9\\uA7F2-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDD70-\\uDD7A\\uDD7C-\\uDD8A\\uDD8C-\\uDD92\\uDD94\\uDD95\\uDD97-\\uDDA1\\uDDA3-\\uDDB1\\uDDB3-\\uDDB9\\uDDBB\\uDDBC\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67\\uDF80-\\uDF85\\uDF87-\\uDFB0\\uDFB2-\\uDFBA]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDE80-\\uDEA9\\uDEB0\\uDEB1\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45\\uDF70-\\uDF81\\uDFB0-\\uDFC4\\uDFE0-\\uDFF6]|\\uD804[\\uDC03-\\uDC37\\uDC71\\uDC72\\uDC75\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD47\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC5F-\\uDC61\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDEB8\\uDF00-\\uDF1A\\uDF40-\\uDF46]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF-\\uDD06\\uDD09\\uDD0C-\\uDD13\\uDD15\\uDD16\\uDD18-\\uDD2F\\uDD3F\\uDD41\\uDDA0-\\uDDA7\\uDDAA-\\uDDD0\\uDDE1\\uDDE3\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE89\\uDE9D\\uDEB0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2\\uDFB0]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|\\uD80B[\\uDF90-\\uDFF0]|[\\uD80C\\uD81C-\\uD820\\uD822\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879\\uD880-\\uD883][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE70-\\uDEBE\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF4A\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1\\uDFE3]|\\uD821[\\uDC00-\\uDFF7]|\\uD823[\\uDC00-\\uDCD5\\uDD00-\\uDD08]|\\uD82B[\\uDFF0-\\uDFF3\\uDFF5-\\uDFFB\\uDFFD\\uDFFE]|\\uD82C[\\uDC00-\\uDD22\\uDD50-\\uDD52\\uDD64-\\uDD67\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD837[\\uDF00-\\uDF1E]|\\uD838[\\uDD00-\\uDD2C\\uDD37-\\uDD3D\\uDD4E\\uDE90-\\uDEAD\\uDEC0-\\uDEEB]|\\uD839[\\uDFE0-\\uDFE6\\uDFE8-\\uDFEB\\uDFED\\uDFEE\\uDFF0-\\uDFFE]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43\\uDD4B]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF38\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uD884[\\uDC00-\\uDF4A])(?:[\\0-@\\[-`\\{-\\xA9\\xAB-\\xB4\\xB6-\\xB9\\xBB-\\xBF\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u036F\\u0375\\u0378\\u0379\\u037E\\u0380-\\u0385\\u0387\\u038B\\u038D\\u03A2\\u03F6\\u0482-\\u0489\\u0530\\u0557\\u0558\\u055A-\\u055F\\u0589-\\u05CF\\u05EB-\\u05EE\\u05F3-\\u061F\\u064B-\\u066D\\u0670\\u06D4\\u06D6-\\u06E4\\u06E7-\\u06ED\\u06F0-\\u06F9\\u06FD\\u06FE\\u0700-\\u070F\\u0711\\u0730-\\u074C\\u07A6-\\u07B0\\u07B2-\\u07C9\\u07EB-\\u07F3\\u07F6-\\u07F9\\u07FB-\\u07FF\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u083F\\u0859-\\u085F\\u086B-\\u086F\\u0888\\u088F-\\u089F\\u08CA-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962-\\u0970\\u0981-\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA-\\u09BC\\u09BE-\\u09CD\\u09CF-\\u09DB\\u09DE\\u09E2-\\u09EF\\u09F2-\\u09FB\\u09FD-\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A-\\u0A58\\u0A5D\\u0A5F-\\u0A71\\u0A75-\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA-\\u0ABC\\u0ABE-\\u0ACF\\u0AD1-\\u0ADF\\u0AE2-\\u0AF8\\u0AFA-\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A-\\u0B3C\\u0B3E-\\u0B5B\\u0B5E\\u0B62-\\u0B70\\u0B72-\\u0B82\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BCF\\u0BD1-\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C3A-\\u0C3C\\u0C3E-\\u0C57\\u0C5B\\u0C5C\\u0C5E\\u0C5F\\u0C62-\\u0C7F\\u0C81-\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA-\\u0CBC\\u0CBE-\\u0CDC\\u0CDF\\u0CE2-\\u0CF0\\u0CF3-\\u0D03\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D3E-\\u0D4D\\u0D4F-\\u0D53\\u0D57-\\u0D5E\\u0D62-\\u0D79\\u0D80-\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0E00\\u0E31\\u0E34-\\u0E3F\\u0E47-\\u0E80\\u0E83\\u0E85\\u0E8B\\u0EA4\\u0EA6\\u0EB1\\u0EB4-\\u0EBC\\u0EBE\\u0EBF\\u0EC5\\u0EC7-\\u0EDB\\u0EE0-\\u0EFF\\u0F01-\\u0F3F\\u0F48\\u0F6D-\\u0F87\\u0F8D-\\u0FFF\\u102B-\\u103E\\u1040-\\u104F\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F-\\u109F\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u10FB\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B-\\u137F\\u1390-\\u139F\\u13F6\\u13F7\\u13FE-\\u1400\\u166D\\u166E\\u1680\\u169B-\\u169F\\u16EB-\\u16F0\\u16F9-\\u16FF\\u1712-\\u171E\\u1732-\\u173F\\u1752-\\u175F\\u176D\\u1771-\\u177F\\u17B4-\\u17D6\\u17D8-\\u17DB\\u17DD-\\u181F\\u1879-\\u187F\\u1885\\u1886\\u18A9\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191F-\\u194F\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19FF\\u1A17-\\u1A1F\\u1A55-\\u1AA6\\u1AA8-\\u1B04\\u1B34-\\u1B44\\u1B4D-\\u1B82\\u1BA1-\\u1BAD\\u1BB0-\\u1BB9\\u1BE6-\\u1BFF\\u1C24-\\u1C4C\\u1C50-\\u1C59\\u1C7E\\u1C7F\\u1C89-\\u1C8F\\u1CBB\\u1CBC\\u1CC0-\\u1CE8\\u1CED\\u1CF4\\u1CF7-\\u1CF9\\u1CFB-\\u1CFF\\u1DC0-\\u1DFF\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FBD\\u1FBF-\\u1FC1\\u1FC5\\u1FCD-\\u1FCF\\u1FD4\\u1FD5\\u1FDC-\\u1FDF\\u1FED-\\u1FF1\\u1FF5\\u1FFD-\\u2070\\u2072-\\u207E\\u2080-\\u208F\\u209D-\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F-\\u2182\\u2185-\\u2BFF\\u2CE5-\\u2CEA\\u2CEF-\\u2CF1\\u2CF4-\\u2CFF\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D70-\\u2D7F\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF-\\u2E2E\\u2E30-\\u3004\\u3007-\\u3030\\u3036-\\u303A\\u303D-\\u3040\\u3097-\\u309C\\u30A0\\u30FB\\u3100-\\u3104\\u3130\\u318F-\\u319F\\u31C0-\\u31EF\\u3200-\\u33FF\\u4DC0-\\u4DFF\\uA48D-\\uA4CF\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA620-\\uA629\\uA62C-\\uA63F\\uA66F-\\uA67E\\uA69E\\uA69F\\uA6E6-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA7CB-\\uA7CF\\uA7D2\\uA7D4\\uA7DA-\\uA7F1\\uA802\\uA806\\uA80B\\uA823-\\uA83F\\uA874-\\uA881\\uA8B4-\\uA8F1\\uA8F8-\\uA8FA\\uA8FC\\uA8FF-\\uA909\\uA926-\\uA92F\\uA947-\\uA95F\\uA97D-\\uA983\\uA9B3-\\uA9CE\\uA9D0-\\uA9DF\\uA9E5\\uA9F0-\\uA9F9\\uA9FF\\uAA29-\\uAA3F\\uAA43\\uAA4C-\\uAA5F\\uAA77-\\uAA79\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAC3-\\uAADA\\uAADE\\uAADF\\uAAEB-\\uAAF1\\uAAF5-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F\\uAB5B\\uAB6A-\\uAB6F\\uABE3-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uD7FF\\uE000-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB1E\\uFB29\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBB2-\\uFBD2\\uFD3E-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFC-\\uFE6F\\uFE75\\uFEFD-\\uFF20\\uFF3B-\\uFF40\\uFF5B-\\uFF65\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFFF]|\\uD800[\\uDC0C\\uDC27\\uDC3B\\uDC3E\\uDC4E\\uDC4F\\uDC5E-\\uDC7F\\uDCFB-\\uDE7F\\uDE9D-\\uDE9F\\uDED1-\\uDEFF\\uDF20-\\uDF2C\\uDF41\\uDF4A-\\uDF4F\\uDF76-\\uDF7F\\uDF9E\\uDF9F\\uDFC4-\\uDFC7\\uDFD0-\\uDFFF]|\\uD801[\\uDC9E-\\uDCAF\\uDCD4-\\uDCD7\\uDCFC-\\uDCFF\\uDD28-\\uDD2F\\uDD64-\\uDD6F\\uDD7B\\uDD8B\\uDD93\\uDD96\\uDDA2\\uDDB2\\uDDBA\\uDDBD-\\uDDFF\\uDF37-\\uDF3F\\uDF56-\\uDF5F\\uDF68-\\uDF7F\\uDF86\\uDFB1\\uDFBB-\\uDFFF]|\\uD802[\\uDC06\\uDC07\\uDC09\\uDC36\\uDC39-\\uDC3B\\uDC3D\\uDC3E\\uDC56-\\uDC5F\\uDC77-\\uDC7F\\uDC9F-\\uDCDF\\uDCF3\\uDCF6-\\uDCFF\\uDD16-\\uDD1F\\uDD3A-\\uDD7F\\uDDB8-\\uDDBD\\uDDC0-\\uDDFF\\uDE01-\\uDE0F\\uDE14\\uDE18\\uDE36-\\uDE5F\\uDE7D-\\uDE7F\\uDE9D-\\uDEBF\\uDEC8\\uDEE5-\\uDEFF\\uDF36-\\uDF3F\\uDF56-\\uDF5F\\uDF73-\\uDF7F\\uDF92-\\uDFFF]|\\uD803[\\uDC49-\\uDC7F\\uDCB3-\\uDCBF\\uDCF3-\\uDCFF\\uDD24-\\uDE7F\\uDEAA-\\uDEAF\\uDEB2-\\uDEFF\\uDF1D-\\uDF26\\uDF28-\\uDF2F\\uDF46-\\uDF6F\\uDF82-\\uDFAF\\uDFC5-\\uDFDF\\uDFF7-\\uDFFF]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC70\\uDC73\\uDC74\\uDC76-\\uDC82\\uDCB0-\\uDCCF\\uDCE9-\\uDD02\\uDD27-\\uDD43\\uDD45\\uDD46\\uDD48-\\uDD4F\\uDD73-\\uDD75\\uDD77-\\uDD82\\uDDB3-\\uDDC0\\uDDC5-\\uDDD9\\uDDDB\\uDDDD-\\uDDFF\\uDE12\\uDE2C-\\uDE7F\\uDE87\\uDE89\\uDE8E\\uDE9E\\uDEA9-\\uDEAF\\uDEDF-\\uDF04\\uDF0D\\uDF0E\\uDF11\\uDF12\\uDF29\\uDF31\\uDF34\\uDF3A-\\uDF3C\\uDF3E-\\uDF4F\\uDF51-\\uDF5C\\uDF62-\\uDFFF]|\\uD805[\\uDC35-\\uDC46\\uDC4B-\\uDC5E\\uDC62-\\uDC7F\\uDCB0-\\uDCC3\\uDCC6\\uDCC8-\\uDD7F\\uDDAF-\\uDDD7\\uDDDC-\\uDDFF\\uDE30-\\uDE43\\uDE45-\\uDE7F\\uDEAB-\\uDEB7\\uDEB9-\\uDEFF\\uDF1B-\\uDF3F\\uDF47-\\uDFFF]|\\uD806[\\uDC2C-\\uDC9F\\uDCE0-\\uDCFE\\uDD07\\uDD08\\uDD0A\\uDD0B\\uDD14\\uDD17\\uDD30-\\uDD3E\\uDD40\\uDD42-\\uDD9F\\uDDA8\\uDDA9\\uDDD1-\\uDDE0\\uDDE2\\uDDE4-\\uDDFF\\uDE01-\\uDE0A\\uDE33-\\uDE39\\uDE3B-\\uDE4F\\uDE51-\\uDE5B\\uDE8A-\\uDE9C\\uDE9E-\\uDEAF\\uDEF9-\\uDFFF]|\\uD807[\\uDC09\\uDC2F-\\uDC3F\\uDC41-\\uDC71\\uDC90-\\uDCFF\\uDD07\\uDD0A\\uDD31-\\uDD45\\uDD47-\\uDD5F\\uDD66\\uDD69\\uDD8A-\\uDD97\\uDD99-\\uDEDF\\uDEF3-\\uDFAF\\uDFB1-\\uDFFF]|\\uD808[\\uDF9A-\\uDFFF]|\\uD809[\\uDC00-\\uDC7F\\uDD44-\\uDFFF]|[\\uD80A\\uD80E-\\uD810\\uD812-\\uD819\\uD824-\\uD82A\\uD82D\\uD82E\\uD830-\\uD834\\uD836\\uD83C-\\uD83F\\uD87B-\\uD87D\\uD87F\\uD885-\\uDBFF][\\uDC00-\\uDFFF]|\\uD80B[\\uDC00-\\uDF8F\\uDFF1-\\uDFFF]|\\uD80D[\\uDC2F-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|\\uD81A[\\uDE39-\\uDE3F\\uDE5F-\\uDE6F\\uDEBF-\\uDECF\\uDEEE-\\uDEFF\\uDF30-\\uDF3F\\uDF44-\\uDF62\\uDF78-\\uDF7C\\uDF90-\\uDFFF]|\\uD81B[\\uDC00-\\uDE3F\\uDE80-\\uDEFF\\uDF4B-\\uDF4F\\uDF51-\\uDF92\\uDFA0-\\uDFDF\\uDFE2\\uDFE4-\\uDFFF]|\\uD821[\\uDFF8-\\uDFFF]|\\uD823[\\uDCD6-\\uDCFF\\uDD09-\\uDFFF]|\\uD82B[\\uDC00-\\uDFEF\\uDFF4\\uDFFC\\uDFFF]|\\uD82C[\\uDD23-\\uDD4F\\uDD53-\\uDD63\\uDD68-\\uDD6F\\uDEFC-\\uDFFF]|\\uD82F[\\uDC6B-\\uDC6F\\uDC7D-\\uDC7F\\uDC89-\\uDC8F\\uDC9A-\\uDFFF]|\\uD835[\\uDC55\\uDC9D\\uDCA0\\uDCA1\\uDCA3\\uDCA4\\uDCA7\\uDCA8\\uDCAD\\uDCBA\\uDCBC\\uDCC4\\uDD06\\uDD0B\\uDD0C\\uDD15\\uDD1D\\uDD3A\\uDD3F\\uDD45\\uDD47-\\uDD49\\uDD51\\uDEA6\\uDEA7\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3\\uDFCC-\\uDFFF]|\\uD837[\\uDC00-\\uDEFF\\uDF1F-\\uDFFF]|\\uD838[\\uDC00-\\uDCFF\\uDD2D-\\uDD36\\uDD3E-\\uDD4D\\uDD4F-\\uDE8F\\uDEAE-\\uDEBF\\uDEEC-\\uDFFF]|\\uD839[\\uDC00-\\uDFDF\\uDFE7\\uDFEC\\uDFEF\\uDFFF]|\\uD83A[\\uDCC5-\\uDCFF\\uDD44-\\uDD4A\\uDD4C-\\uDFFF]|\\uD83B[\\uDC00-\\uDDFF\\uDE04\\uDE20\\uDE23\\uDE25\\uDE26\\uDE28\\uDE33\\uDE38\\uDE3A\\uDE3C-\\uDE41\\uDE43-\\uDE46\\uDE48\\uDE4A\\uDE4C\\uDE50\\uDE53\\uDE55\\uDE56\\uDE58\\uDE5A\\uDE5C\\uDE5E\\uDE60\\uDE63\\uDE65\\uDE66\\uDE6B\\uDE73\\uDE78\\uDE7D\\uDE7F\\uDE8A\\uDE9C-\\uDEA0\\uDEA4\\uDEAA\\uDEBC-\\uDFFF]|\\uD869[\\uDEE0-\\uDEFF]|\\uD86D[\\uDF39-\\uDF3F]|\\uD86E[\\uDC1E\\uDC1F]|\\uD873[\\uDEA2-\\uDEAF]|\\uD87A[\\uDFE1-\\uDFFF]|\\uD87E[\\uDE1E-\\uDFFF]|\\uD884[\\uDF4B-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g)).pop();\n\n if (lastWordEnd !== undefined && lastWordEnd.index > 1) {\n after = after.slice(0, lastWordEnd.index + 1);\n }\n\n return {\n highlight: highlight,\n before: before,\n after: after\n };\n}\n\nfunction createOrderedRange(startNode, startOffset, endNode, endOffset) {\n var range = new Range();\n range.setStart(startNode, startOffset);\n range.setEnd(endNode, endOffset);\n\n if (!range.collapsed) {\n return range;\n }\n\n selection_log(">>> createOrderedRange COLLAPSED ... RANGE REVERSE?");\n var rangeReverse = new Range();\n rangeReverse.setStart(endNode, endOffset);\n rangeReverse.setEnd(startNode, startOffset);\n\n if (!rangeReverse.collapsed) {\n selection_log(">>> createOrderedRange RANGE REVERSE OK.");\n return range;\n }\n\n selection_log(">>> createOrderedRange RANGE REVERSE ALSO COLLAPSED?!");\n return undefined;\n}\n\nfunction convertRangeInfo(document, rangeInfo) {\n var startElement = document.querySelector(rangeInfo.startContainerElementCssSelector);\n\n if (!startElement) {\n selection_log("^^^ convertRangeInfo NO START ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var startContainer = startElement;\n\n if (rangeInfo.startContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.startContainerChildTextNodeIndex >= startElement.childNodes.length?!");\n return undefined;\n }\n\n startContainer = startElement.childNodes[rangeInfo.startContainerChildTextNodeIndex];\n\n if (startContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo startContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n var endElement = document.querySelector(rangeInfo.endContainerElementCssSelector);\n\n if (!endElement) {\n selection_log("^^^ convertRangeInfo NO END ELEMENT CSS SELECTOR?!");\n return undefined;\n }\n\n var endContainer = endElement;\n\n if (rangeInfo.endContainerChildTextNodeIndex >= 0) {\n if (rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length) {\n selection_log("^^^ convertRangeInfo rangeInfo.endContainerChildTextNodeIndex >= endElement.childNodes.length?!");\n return undefined;\n }\n\n endContainer = endElement.childNodes[rangeInfo.endContainerChildTextNodeIndex];\n\n if (endContainer.nodeType !== Node.TEXT_NODE) {\n selection_log("^^^ convertRangeInfo endContainer.nodeType !== Node.TEXT_NODE?!");\n return undefined;\n }\n }\n\n return createOrderedRange(startContainer, rangeInfo.startOffset, endContainer, rangeInfo.endOffset);\n}\nfunction location2RangeInfo(location) {\n var locations = location.locations;\n var domRange = locations.domRange;\n var start = domRange.start;\n var end = domRange.end;\n return {\n endContainerChildTextNodeIndex: end.textNodeIndex,\n endContainerElementCssSelector: end.cssSelector,\n endOffset: end.offset,\n startContainerChildTextNodeIndex: start.textNodeIndex,\n startContainerElementCssSelector: start.cssSelector,\n startOffset: start.offset\n };\n}\n\nfunction selection_log() {\n if (selection_debug) {\n log.apply(null, arguments);\n }\n}\n;// CONCATENATED MODULE: ./src/index.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Base script used by both reflowable and fixed layout resources.\n\n\n\n\n\n // Public API used by the navigator.\n\nwindow.readium = {\n // utils\n scrollToId: scrollToId,\n scrollToPosition: scrollToPosition,\n scrollToText: scrollToText,\n scrollLeft: scrollLeft,\n scrollRight: scrollRight,\n scrollToStart: scrollToStart,\n scrollToEnd: scrollToEnd,\n setCSSProperties: setCSSProperties,\n setProperty: setProperty,\n removeProperty: removeProperty,\n // selection\n getCurrentSelection: getCurrentSelection,\n // decoration\n registerDecorationTemplates: registerTemplates,\n getDecorations: getDecorations,\n // DOM\n findFirstVisibleLocator: findFirstVisibleLocator\n};\n;// CONCATENATED MODULE: ./src/index-reflowable.js\n//\n// Copyright 2021 Readium Foundation. All rights reserved.\n// Use of this source code is governed by the BSD-style license\n// available in the top-level LICENSE file of the project.\n//\n// Script used for reflowable resources.\n\nwindow.readium.isReflowable = true;\ndocument.addEventListener("DOMContentLoaded", function () {\n // Setups the `viewport` meta tag to disable zooming.\n var meta = document.createElement("meta");\n meta.setAttribute("name", "viewport");\n meta.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no");\n document.head.appendChild(meta);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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RTtBQVdmeUQsRUFBQUEsY0FBYyxFQUFFQSxjQVhEO0FBYWY7QUFDQXdOLEVBQUFBLG1CQUFtQixFQUFFQSxtQkFkTjtBQWdCZjtBQUNBa0MsRUFBQUEsMkJBQTJCLEVBQUVoTCxpQkFqQmQ7QUFrQmZRLEVBQUFBLGNBQWMsRUFBRUEsY0FsQkQ7QUFvQmY7QUFDQXVFLEVBQUFBLHVCQUF1QixFQUFFQSx1QkFBdUJBO0FBckJqQyxDQUFqQixDOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBdlAsTUFBTSxDQUFDOFAsT0FBUCxDQUFlMkYsWUFBZixHQUE4QixJQUE5QjtBQUVBaFksUUFBUSxDQUFDd0MsZ0JBQVQsQ0FBMEIsa0JBQTFCLEVBQThDLFlBQVk7QUFDeEQ7QUFDQSxNQUFJNFMsSUFBSSxHQUFHcFYsUUFBUSxDQUFDbUUsYUFBVCxDQUF1QixNQUF2QixDQUFYO0FBQ0FpUixFQUFBQSxJQUFJLENBQUNoUixZQUFMLENBQWtCLE1BQWxCLEVBQTBCLFVBQTFCO0FBQ0FnUixFQUFBQSxJQUFJLENBQUNoUixZQUFMLENBQ0UsU0FERixFQUVFLDhGQUZGO0FBSUFwRSxFQUFBQSxRQUFRLENBQUNpWSxJQUFULENBQWN6VCxXQUFkLENBQTBCNFEsSUFBMUI7QUFDRCxDQVREIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvbWF0Y2gtcXVvdGUuanM/ZGQ2YSIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90ZXh0LXJhbmdlLmpzP2ZkZWUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy92ZW5kb3IvaHlwb3RoZXNpcy9hbmNob3JpbmcvdHlwZXMuanM/NDAwNCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL3V0aWxzLmpzPzAyNWUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9yZWN0LmpzPzRkNWEiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9kZWNvcmF0b3IuanM/MWIwNCIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2RvbS5qcz9jYmYwIiwid2VicGFjazovL3JlYWRpdW0tanMvLi9zcmMvZ2VzdHVyZXMuanM/MTRjMiIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2tleWJvYXJkLmpzPzE4ZTMiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9zZWxlY3Rpb24uanM/NTlhYyIsIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vc3JjL2luZGV4LmpzP2I2MzUiLCJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL3NyYy9pbmRleC1yZWZsb3dhYmxlLmpzPzM5MjUiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFwcHJveFNlYXJjaCBmcm9tICdhcHByb3gtc3RyaW5nLW1hdGNoJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHByb3gtc3RyaW5nLW1hdGNoJykuTWF0Y2h9IFN0cmluZ01hdGNoXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBNYXRjaFxuICogQHByb3Age251bWJlcn0gc3RhcnQgLSBTdGFydCBvZmZzZXQgb2YgbWF0Y2ggaW4gdGV4dFxuICogQHByb3Age251bWJlcn0gZW5kIC0gRW5kIG9mZnNldCBvZiBtYXRjaCBpbiB0ZXh0XG4gKiBAcHJvcCB7bnVtYmVyfSBzY29yZSAtXG4gKiAgIFNjb3JlIGZvciB0aGUgbWF0Y2ggYmV0d2VlbiAwIGFuZCAxLjAsIHdoZXJlIDEuMCBpbmRpY2F0ZXMgYSBwZXJmZWN0IG1hdGNoXG4gKiAgIGZvciB0aGUgcXVvdGUgYW5kIGNvbnRleHQuXG4gKi9cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoZXMgZm9yIGBzdHJgIGluIGB0ZXh0YCBhbGxvd2luZyB1cCB0byBgbWF4RXJyb3JzYCBlcnJvcnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhFcnJvcnNcbiAqIEByZXR1cm4ge1N0cmluZ01hdGNoW119XG4gKi9cbmZ1bmN0aW9uIHNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycykge1xuICAvLyBEbyBhIGZhc3Qgc2VhcmNoIGZvciBleGFjdCBtYXRjaGVzLiBUaGUgYGFwcHJveC1zdHJpbmctbWF0Y2hgIGxpYnJhcnlcbiAgLy8gZG9lc24ndCBjdXJyZW50bHkgaW5jb3Jwb3JhdGUgdGhpcyBvcHRpbWl6YXRpb24gaXRzZWxmLlxuICBsZXQgbWF0Y2hQb3MgPSAwO1xuICBsZXQgZXhhY3RNYXRjaGVzID0gW107XG4gIHdoaWxlIChtYXRjaFBvcyAhPT0gLTEpIHtcbiAgICBtYXRjaFBvcyA9IHRleHQuaW5kZXhPZihzdHIsIG1hdGNoUG9zKTtcbiAgICBpZiAobWF0Y2hQb3MgIT09IC0xKSB7XG4gICAgICBleGFjdE1hdGNoZXMucHVzaCh7XG4gICAgICAgIHN0YXJ0OiBtYXRjaFBvcyxcbiAgICAgICAgZW5kOiBtYXRjaFBvcyArIHN0ci5sZW5ndGgsXG4gICAgICAgIGVycm9yczogMCxcbiAgICAgIH0pO1xuICAgICAgbWF0Y2hQb3MgKz0gMTtcbiAgICB9XG4gIH1cbiAgaWYgKGV4YWN0TWF0Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGV4YWN0TWF0Y2hlcztcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBubyBleGFjdCBtYXRjaGVzLCBkbyBhIG1vcmUgZXhwZW5zaXZlIHNlYXJjaCBmb3IgbWF0Y2hlc1xuICAvLyB3aXRoIGVycm9ycy5cbiAgcmV0dXJuIGFwcHJveFNlYXJjaCh0ZXh0LCBzdHIsIG1heEVycm9ycyk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSBhIHNjb3JlIGJldHdlZW4gMCBhbmQgMS4wIGZvciB0aGUgc2ltaWxhcml0eSBiZXR3ZWVuIGB0ZXh0YCBhbmQgYHN0cmAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqL1xuZnVuY3Rpb24gdGV4dE1hdGNoU2NvcmUodGV4dCwgc3RyKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0IC0gYHNjb3JlTWF0Y2hgIHdpbGwgbmV2ZXIgcGFzcyBhbiBlbXB0eSBzdHJpbmcgKi9cbiAgaWYgKHN0ci5sZW5ndGggPT09IDAgfHwgdGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gMC4wO1xuICB9XG4gIGNvbnN0IG1hdGNoZXMgPSBzZWFyY2godGV4dCwgc3RyLCBzdHIubGVuZ3RoKTtcblxuICAvLyBwcmV0dGllci1pZ25vcmVcbiAgcmV0dXJuIDEgLSAobWF0Y2hlc1swXS5lcnJvcnMgLyBzdHIubGVuZ3RoKTtcbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBiZXN0IGFwcHJveGltYXRlIG1hdGNoIGZvciBgcXVvdGVgIGluIGB0ZXh0YC5cbiAqXG4gKiBSZXR1cm5zIGBudWxsYCBpZiBubyBtYXRjaCBleGNlZWRpbmcgdGhlIG1pbmltdW0gcXVhbGl0eSB0aHJlc2hvbGQgd2FzIGZvdW5kLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gRG9jdW1lbnQgdGV4dCB0byBzZWFyY2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBxdW90ZSAtIFN0cmluZyB0byBmaW5kIHdpdGhpbiBgdGV4dGBcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC1cbiAqICAgQ29udGV4dCBpbiB3aGljaCB0aGUgcXVvdGUgb3JpZ2luYWxseSBhcHBlYXJlZC4gVGhpcyBpcyB1c2VkIHRvIGNob29zZSB0aGVcbiAqICAgYmVzdCBtYXRjaC5cbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnByZWZpeF0gLSBFeHBlY3RlZCB0ZXh0IGJlZm9yZSB0aGUgcXVvdGVcbiAqICAgQHBhcmFtIHtzdHJpbmd9IFtjb250ZXh0LnN1ZmZpeF0gLSBFeHBlY3RlZCB0ZXh0IGFmdGVyIHRoZSBxdW90ZVxuICogICBAcGFyYW0ge251bWJlcn0gW2NvbnRleHQuaGludF0gLSBFeHBlY3RlZCBvZmZzZXQgb2YgbWF0Y2ggd2l0aGluIHRleHRcbiAqIEByZXR1cm4ge01hdGNofG51bGx9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaFF1b3RlKHRleHQsIHF1b3RlLCBjb250ZXh0ID0ge30pIHtcbiAgaWYgKHF1b3RlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQ2hvb3NlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBlcnJvcnMgdG8gYWxsb3cgZm9yIHRoZSBpbml0aWFsIHNlYXJjaC5cbiAgLy8gVGhpcyBjaG9pY2UgaW52b2x2ZXMgYSB0cmFkZW9mZiBiZXR3ZWVuOlxuICAvL1xuICAvLyAgLSBSZWNhbGwgKHByb3BvcnRpb24gb2YgXCJnb29kXCIgbWF0Y2hlcyBmb3VuZClcbiAgLy8gIC0gUHJlY2lzaW9uIChwcm9wb3J0aW9uIG9mIG1hdGNoZXMgZm91bmQgd2hpY2ggYXJlIFwiZ29vZFwiKVxuICAvLyAgLSBDb3N0IG9mIHRoZSBpbml0aWFsIHNlYXJjaCBhbmQgb2YgcHJvY2Vzc2luZyB0aGUgY2FuZGlkYXRlIG1hdGNoZXMgWzFdXG4gIC8vXG4gIC8vIFsxXSBTcGVjaWZpY2FsbHksIHRoZSBleHBlY3RlZC10aW1lIGNvbXBsZXhpdHkgb2YgdGhlIGluaXRpYWwgc2VhcmNoIGlzXG4gIC8vICAgICBgTygobWF4RXJyb3JzIC8gMzIpICogdGV4dC5sZW5ndGgpYC4gU2VlIGBhcHByb3gtc3RyaW5nLW1hdGNoYCBkb2NzLlxuICBjb25zdCBtYXhFcnJvcnMgPSBNYXRoLm1pbigyNTYsIHF1b3RlLmxlbmd0aCAvIDIpO1xuXG4gIC8vIEZpbmQgY2xvc2VzdCBtYXRjaGVzIGZvciBgcXVvdGVgIGluIGB0ZXh0YCBiYXNlZCBvbiBlZGl0IGRpc3RhbmNlLlxuICBjb25zdCBtYXRjaGVzID0gc2VhcmNoKHRleHQsIHF1b3RlLCBtYXhFcnJvcnMpO1xuXG4gIGlmIChtYXRjaGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEuMCBmb3IgYSBtYXRjaCBjYW5kaWRhdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nTWF0Y2h9IG1hdGNoXG4gICAqL1xuICBjb25zdCBzY29yZU1hdGNoID0gbWF0Y2ggPT4ge1xuICAgIGNvbnN0IHF1b3RlV2VpZ2h0ID0gNTA7IC8vIFNpbWlsYXJpdHkgb2YgbWF0Y2hlZCB0ZXh0IHRvIHF1b3RlLlxuICAgIGNvbnN0IHByZWZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYmVmb3JlIG1hdGNoZWQgdGV4dCB0byBgY29udGV4dC5wcmVmaXhgLlxuICAgIGNvbnN0IHN1ZmZpeFdlaWdodCA9IDIwOyAvLyBTaW1pbGFyaXR5IG9mIHRleHQgYWZ0ZXIgbWF0Y2hlZCB0ZXh0IHRvIGBjb250ZXh0LnN1ZmZpeGAuXG4gICAgY29uc3QgcG9zV2VpZ2h0ID0gMjsgLy8gUHJveGltaXR5IHRvIGV4cGVjdGVkIGxvY2F0aW9uLiBVc2VkIGFzIGEgdGllLWJyZWFrZXIuXG5cbiAgICBjb25zdCBxdW90ZVNjb3JlID0gMSAtIG1hdGNoLmVycm9ycyAvIHF1b3RlLmxlbmd0aDtcblxuICAgIGNvbnN0IHByZWZpeFNjb3JlID0gY29udGV4dC5wcmVmaXhcbiAgICAgID8gdGV4dE1hdGNoU2NvcmUoXG4gICAgICAgICAgdGV4dC5zbGljZShNYXRoLm1heCgwLCBtYXRjaC5zdGFydCAtIGNvbnRleHQucHJlZml4Lmxlbmd0aCksIG1hdGNoLnN0YXJ0KSxcbiAgICAgICAgICBjb250ZXh0LnByZWZpeFxuICAgICAgICApXG4gICAgICA6IDEuMDtcbiAgICBjb25zdCBzdWZmaXhTY29yZSA9IGNvbnRleHQuc3VmZml4XG4gICAgICA/IHRleHRNYXRjaFNjb3JlKFxuICAgICAgICAgIHRleHQuc2xpY2UobWF0Y2guZW5kLCBtYXRjaC5lbmQgKyBjb250ZXh0LnN1ZmZpeC5sZW5ndGgpLFxuICAgICAgICAgIGNvbnRleHQuc3VmZml4XG4gICAgICAgIClcbiAgICAgIDogMS4wO1xuXG4gICAgbGV0IHBvc1Njb3JlID0gMS4wO1xuICAgIGlmICh0eXBlb2YgY29udGV4dC5oaW50ID09PSAnbnVtYmVyJykge1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5hYnMobWF0Y2guc3RhcnQgLSBjb250ZXh0LmhpbnQpO1xuICAgICAgcG9zU2NvcmUgPSAxLjAgLSBvZmZzZXQgLyB0ZXh0Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBjb25zdCByYXdTY29yZSA9XG4gICAgICBxdW90ZVdlaWdodCAqIHF1b3RlU2NvcmUgK1xuICAgICAgcHJlZml4V2VpZ2h0ICogcHJlZml4U2NvcmUgK1xuICAgICAgc3VmZml4V2VpZ2h0ICogc3VmZml4U2NvcmUgK1xuICAgICAgcG9zV2VpZ2h0ICogcG9zU2NvcmU7XG4gICAgY29uc3QgbWF4U2NvcmUgPSBxdW90ZVdlaWdodCArIHByZWZpeFdlaWdodCArIHN1ZmZpeFdlaWdodCArIHBvc1dlaWdodDtcbiAgICBjb25zdCBub3JtYWxpemVkU2NvcmUgPSByYXdTY29yZSAvIG1heFNjb3JlO1xuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRTY29yZTtcbiAgfTtcblxuICAvLyBSYW5rIG1hdGNoZXMgYmFzZWQgb24gc2ltaWxhcml0eSBvZiBhY3R1YWwgYW5kIGV4cGVjdGVkIHN1cnJvdW5kaW5nIHRleHRcbiAgLy8gYW5kIGFjdHVhbC9leHBlY3RlZCBvZmZzZXQgaW4gdGhlIGRvY3VtZW50IHRleHQuXG4gIGNvbnN0IHNjb3JlZE1hdGNoZXMgPSBtYXRjaGVzLm1hcChtID0+ICh7XG4gICAgc3RhcnQ6IG0uc3RhcnQsXG4gICAgZW5kOiBtLmVuZCxcbiAgICBzY29yZTogc2NvcmVNYXRjaChtKSxcbiAgfSkpO1xuXG4gIC8vIENob29zZSBtYXRjaCB3aXRoIGhpZ2hlc3Qgc2NvcmUuXG4gIHNjb3JlZE1hdGNoZXMuc29ydCgoYSwgYikgPT4gYi5zY29yZSAtIGEuc2NvcmUpO1xuICByZXR1cm4gc2NvcmVkTWF0Y2hlc1swXTtcbn1cbiIsIi8qKlxuICogUmV0dXJuIHRoZSBjb21iaW5lZCBsZW5ndGggb2YgdGV4dCBub2RlcyBjb250YWluZWQgaW4gYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICovXG5mdW5jdGlvbiBub2RlVGV4dExlbmd0aChub2RlKSB7XG4gIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgIC8vIG5iLiBgdGV4dENvbnRlbnRgIGV4Y2x1ZGVzIHRleHQgaW4gY29tbWVudHMgYW5kIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zXG4gICAgICAvLyB3aGVuIGNhbGxlZCBvbiBhIHBhcmVudCBlbGVtZW50LCBzbyB3ZSBkb24ndCBuZWVkIHRvIHN1YnRyYWN0IHRoYXQgaGVyZS5cblxuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobm9kZS50ZXh0Q29udGVudCkubGVuZ3RoO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gMDtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgdG90YWwgbGVuZ3RoIG9mIHRoZSB0ZXh0IG9mIGFsbCBwcmV2aW91cyBzaWJsaW5ncyBvZiBgbm9kZWAuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKi9cbmZ1bmN0aW9uIHByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoKG5vZGUpIHtcbiAgbGV0IHNpYmxpbmcgPSBub2RlLnByZXZpb3VzU2libGluZztcbiAgbGV0IGxlbmd0aCA9IDA7XG4gIHdoaWxlIChzaWJsaW5nKSB7XG4gICAgbGVuZ3RoICs9IG5vZGVUZXh0TGVuZ3RoKHNpYmxpbmcpO1xuICAgIHNpYmxpbmcgPSBzaWJsaW5nLnByZXZpb3VzU2libGluZztcbiAgfVxuICByZXR1cm4gbGVuZ3RoO1xufVxuXG4vKipcbiAqIFJlc29sdmUgb25lIG9yIG1vcmUgY2hhcmFjdGVyIG9mZnNldHMgd2l0aGluIGFuIGVsZW1lbnQgdG8gKHRleHQgbm9kZSwgcG9zaXRpb24pXG4gKiBwYWlycy5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyW119IG9mZnNldHMgLSBPZmZzZXRzLCB3aGljaCBtdXN0IGJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXJcbiAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfVtdfVxuICovXG5mdW5jdGlvbiByZXNvbHZlT2Zmc2V0cyhlbGVtZW50LCAuLi5vZmZzZXRzKSB7XG4gIGxldCBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICBjb25zdCBub2RlSXRlciA9IC8qKiBAdHlwZSB7RG9jdW1lbnR9ICovIChcbiAgICBlbGVtZW50Lm93bmVyRG9jdW1lbnRcbiAgKS5jcmVhdGVOb2RlSXRlcmF0b3IoZWxlbWVudCwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuICBjb25zdCByZXN1bHRzID0gW107XG5cbiAgbGV0IGN1cnJlbnROb2RlID0gbm9kZUl0ZXIubmV4dE5vZGUoKTtcbiAgbGV0IHRleHROb2RlO1xuICBsZXQgbGVuZ3RoID0gMDtcblxuICAvLyBGaW5kIHRoZSB0ZXh0IG5vZGUgY29udGFpbmluZyB0aGUgYG5leHRPZmZzZXRgdGggY2hhcmFjdGVyIGZyb20gdGhlIHN0YXJ0XG4gIC8vIG9mIGBlbGVtZW50YC5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50Tm9kZSkge1xuICAgIHRleHROb2RlID0gLyoqIEB0eXBlIHtUZXh0fSAqLyAoY3VycmVudE5vZGUpO1xuICAgIGlmIChsZW5ndGggKyB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCA+IG5leHRPZmZzZXQpIHtcbiAgICAgIHJlc3VsdHMucHVzaCh7IG5vZGU6IHRleHROb2RlLCBvZmZzZXQ6IG5leHRPZmZzZXQgLSBsZW5ndGggfSk7XG4gICAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IG5vZGVJdGVyLm5leHROb2RlKCk7XG4gICAgICBsZW5ndGggKz0gdGV4dE5vZGUuZGF0YS5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgLy8gQm91bmRhcnkgY2FzZS5cbiAgd2hpbGUgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCAmJiB0ZXh0Tm9kZSAmJiBsZW5ndGggPT09IG5leHRPZmZzZXQpIHtcbiAgICByZXN1bHRzLnB1c2goeyBub2RlOiB0ZXh0Tm9kZSwgb2Zmc2V0OiB0ZXh0Tm9kZS5kYXRhLmxlbmd0aCB9KTtcbiAgICBuZXh0T2Zmc2V0ID0gb2Zmc2V0cy5zaGlmdCgpO1xuICB9XG5cbiAgaWYgKG5leHRPZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPZmZzZXQgZXhjZWVkcyB0ZXh0IGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmV4cG9ydCBsZXQgUkVTT0xWRV9GT1JXQVJEUyA9IDE7XG5leHBvcnQgbGV0IFJFU09MVkVfQkFDS1dBUkRTID0gMjtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIG9mZnNldCB3aXRoaW4gdGhlIHRleHQgY29udGVudCBvZiBhbiBlbGVtZW50LlxuICpcbiAqIFRoaXMgcG9zaXRpb24gY2FuIGJlIHJlc29sdmVkIHRvIGEgc3BlY2lmaWMgZGVzY2VuZGFudCBub2RlIGluIHRoZSBjdXJyZW50XG4gKiBET00gc3VidHJlZSBvZiB0aGUgZWxlbWVudCB1c2luZyB0aGUgYHJlc29sdmVgIG1ldGhvZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbiB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgdGV4dCBwb3NpdGlvbiBgb2Zmc2V0YCB3aXRoaW5cbiAgICogdGhlIHRleHQgY29udGVudCBvZiBgZWxlbWVudGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvZmZzZXQpIHtcbiAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPZmZzZXQgaXMgaW52YWxpZCcpO1xuICAgIH1cblxuICAgIC8qKiBFbGVtZW50IHRoYXQgYG9mZnNldGAgaXMgcmVsYXRpdmUgdG8uICovXG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIC8qKiBDaGFyYWN0ZXIgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBlbGVtZW50J3MgYHRleHRDb250ZW50YC4gKi9cbiAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgcG9zaXRpb24gd2l0aCBvZmZzZXQgcmVsYXRpdmUgdG8gYSBnaXZlbiBhbmNlc3RvclxuICAgKiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHBhcmVudCAtIEFuY2VzdG9yIG9mIGB0aGlzLmVsZW1lbnRgXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHJlbGF0aXZlVG8ocGFyZW50KSB7XG4gICAgaWYgKCFwYXJlbnQuY29udGFpbnModGhpcy5lbGVtZW50KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJlbnQgaXMgbm90IGFuIGFuY2VzdG9yIG9mIGN1cnJlbnQgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIGxldCBlbCA9IHRoaXMuZWxlbWVudDtcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgd2hpbGUgKGVsICE9PSBwYXJlbnQpIHtcbiAgICAgIG9mZnNldCArPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChlbCk7XG4gICAgICBlbCA9IC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKGVsLnBhcmVudEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKGVsLCBvZmZzZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIHBvc2l0aW9uIHRvIGEgc3BlY2lmaWMgdGV4dCBub2RlIGFuZCBvZmZzZXQgd2l0aGluIHRoYXQgbm9kZS5cbiAgICpcbiAgICogVGhyb3dzIGlmIGB0aGlzLm9mZnNldGAgZXhjZWVkcyB0aGUgbGVuZ3RoIG9mIHRoZSBlbGVtZW50J3MgdGV4dC4gSW4gdGhlXG4gICAqIGNhc2Ugd2hlcmUgdGhlIGVsZW1lbnQgaGFzIG5vIHRleHQgYW5kIGB0aGlzLm9mZnNldGAgaXMgMCwgdGhlIGBkaXJlY3Rpb25gXG4gICAqIG9wdGlvbiBkZXRlcm1pbmVzIHdoYXQgaGFwcGVucy5cbiAgICpcbiAgICogT2Zmc2V0cyBhdCB0aGUgYm91bmRhcnkgYmV0d2VlbiB0d28gbm9kZXMgYXJlIHJlc29sdmVkIHRvIHRoZSBzdGFydCBvZiB0aGVcbiAgICogbm9kZSB0aGF0IGJlZ2lucyBhdCB0aGUgYm91bmRhcnkuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBAcGFyYW0ge1JFU09MVkVfRk9SV0FSRFN8UkVTT0xWRV9CQUNLV0FSRFN9IFtvcHRpb25zLmRpcmVjdGlvbl0gLVxuICAgKiAgICAgU3BlY2lmaWVzIGluIHdoaWNoIGRpcmVjdGlvbiB0byBzZWFyY2ggZm9yIHRoZSBuZWFyZXN0IHRleHQgbm9kZSBpZlxuICAgKiAgICAgYHRoaXMub2Zmc2V0YCBpcyBgMGAgYW5kIGB0aGlzLmVsZW1lbnRgIGhhcyBubyB0ZXh0LiBJZiBub3Qgc3BlY2lmaWVkXG4gICAqICAgICBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAqIEByZXR1cm4ge3sgbm9kZTogVGV4dCwgb2Zmc2V0OiBudW1iZXIgfX1cbiAgICogQHRocm93cyB7UmFuZ2VFcnJvcn1cbiAgICovXG4gIHJlc29sdmUob3B0aW9ucyA9IHt9KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiByZXNvbHZlT2Zmc2V0cyh0aGlzLmVsZW1lbnQsIHRoaXMub2Zmc2V0KVswXTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmICh0aGlzLm9mZnNldCA9PT0gMCAmJiBvcHRpb25zLmRpcmVjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHR3ID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVFxuICAgICAgICApO1xuICAgICAgICB0dy5jdXJyZW50Tm9kZSA9IHRoaXMuZWxlbWVudDtcbiAgICAgICAgY29uc3QgZm9yd2FyZHMgPSBvcHRpb25zLmRpcmVjdGlvbiA9PT0gUkVTT0xWRV9GT1JXQVJEUztcbiAgICAgICAgY29uc3QgdGV4dCA9IC8qKiBAdHlwZSB7VGV4dHxudWxsfSAqLyAoXG4gICAgICAgICAgZm9yd2FyZHMgPyB0dy5uZXh0Tm9kZSgpIDogdHcucHJldmlvdXNOb2RlKClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHRleHQsIG9mZnNldDogZm9yd2FyZHMgPyAwIDogdGV4dC5kYXRhLmxlbmd0aCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCB0aGF0IHJlZmVycyB0byB0aGUgYG9mZnNldGB0aCBjaGFyYWN0ZXIgd2l0aGluXG4gICAqIGBub2RlYC5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7VGV4dFBvc2l0aW9ufVxuICAgKi9cbiAgc3RhdGljIGZyb21DaGFyT2Zmc2V0KG5vZGUsIG9mZnNldCkge1xuICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERTpcbiAgICAgICAgcmV0dXJuIFRleHRQb3NpdGlvbi5mcm9tUG9pbnQobm9kZSwgb2Zmc2V0KTtcbiAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6XG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCBvZmZzZXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb2RlIGlzIG5vdCBhbiBlbGVtZW50IG9yIHRleHQgbm9kZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBgVGV4dFBvc2l0aW9uYCByZXByZXNlbnRpbmcgdGhlIHJhbmdlIHN0YXJ0IG9yIGVuZCBwb2ludCAobm9kZSwgb2Zmc2V0KS5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBub2RlIC0gVGV4dCBvciBFbGVtZW50IG5vZGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCAtIE9mZnNldCB3aXRoaW4gdGhlIG5vZGUuXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tUG9pbnQobm9kZSwgb2Zmc2V0KSB7XG4gICAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7XG4gICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOiB7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IC8qKiBAdHlwZSB7VGV4dH0gKi8gKG5vZGUpLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IG5vZGUgb2Zmc2V0IGlzIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFub2RlLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RleHQgbm9kZSBoYXMgbm8gcGFyZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcGFyZW50IGVsZW1lbnQuXG4gICAgICAgIGNvbnN0IHRleHRPZmZzZXQgPSBwcmV2aW91c1NpYmxpbmdzVGV4dExlbmd0aChub2RlKSArIG9mZnNldDtcblxuICAgICAgICByZXR1cm4gbmV3IFRleHRQb3NpdGlvbihub2RlLnBhcmVudEVsZW1lbnQsIHRleHRPZmZzZXQpO1xuICAgICAgfVxuICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERToge1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBub2RlIG9mZnNldCBpcyBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgdGV4dCBsZW5ndGggYmVmb3JlIHRoZSBgb2Zmc2V0YHRoIGNoaWxkIG9mIGVsZW1lbnQuXG4gICAgICAgIGxldCB0ZXh0T2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvZmZzZXQ7IGkrKykge1xuICAgICAgICAgIHRleHRPZmZzZXQgKz0gbm9kZVRleHRMZW5ndGgobm9kZS5jaGlsZE5vZGVzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uKC8qKiBAdHlwZSB7RWxlbWVudH0gKi8gKG5vZGUpLCB0ZXh0T2Zmc2V0KTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUG9pbnQgaXMgbm90IGluIGFuIGVsZW1lbnQgb3IgdGV4dCBub2RlJyk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHJlZ2lvbiBvZiBhIGRvY3VtZW50IGFzIGEgKHN0YXJ0LCBlbmQpIHBhaXIgb2YgYFRleHRQb3NpdGlvbmAgcG9pbnRzLlxuICpcbiAqIFJlcHJlc2VudGluZyBhIHJhbmdlIGluIHRoaXMgd2F5IGFsbG93cyBmb3IgY2hhbmdlcyBpbiB0aGUgRE9NIGNvbnRlbnQgb2YgdGhlXG4gKiByYW5nZSB3aGljaCBkb24ndCBhZmZlY3QgaXRzIHRleHQgY29udGVudCwgd2l0aG91dCBhZmZlY3RpbmcgdGhlIHRleHQgY29udGVudFxuICogb2YgdGhlIHJhbmdlIGl0c2VsZi5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRSYW5nZSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYW4gaW1tdXRhYmxlIGBUZXh0UmFuZ2VgIGZyb20gYSBgc3RhcnRgIGFuZCBgZW5kYCBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHtUZXh0UG9zaXRpb259IHN0YXJ0XG4gICAqIEBwYXJhbSB7VGV4dFBvc2l0aW9ufSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5lbmQgPSBlbmQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGlzIHJhbmdlIHdpdGggc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgcmVsYXRpdmUgdG8gYVxuICAgKiBnaXZlbiBhbmNlc3Rvci4gU2VlIGBUZXh0UG9zaXRpb24ucmVsYXRpdmVUb2AuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKi9cbiAgcmVsYXRpdmVUbyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2UoXG4gICAgICB0aGlzLnN0YXJ0LnJlbGF0aXZlVG8oZWxlbWVudCksXG4gICAgICB0aGlzLmVuZC5yZWxhdGl2ZVRvKGVsZW1lbnQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBgVGV4dFJhbmdlYCB0byBhIERPTSByYW5nZS5cbiAgICpcbiAgICogVGhlIHJlc3VsdGluZyBET00gUmFuZ2Ugd2lsbCBhbHdheXMgc3RhcnQgYW5kIGVuZCBpbiBhIGBUZXh0YCBub2RlLlxuICAgKiBIZW5jZSBgVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkudG9SYW5nZSgpYCBjYW4gYmUgdXNlZCB0byBcInNocmlua1wiIGFcbiAgICogcmFuZ2UgdG8gdGhlIHRleHQgaXQgY29udGFpbnMuXG4gICAqXG4gICAqIE1heSB0aHJvdyBpZiB0aGUgYHN0YXJ0YCBvciBgZW5kYCBwb3NpdGlvbnMgY2Fubm90IGJlIHJlc29sdmVkIHRvIGEgcmFuZ2UuXG4gICAqXG4gICAqIEByZXR1cm4ge1JhbmdlfVxuICAgKi9cbiAgdG9SYW5nZSgpIHtcbiAgICBsZXQgc3RhcnQ7XG4gICAgbGV0IGVuZDtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhcnQuZWxlbWVudCA9PT0gdGhpcy5lbmQuZWxlbWVudCAmJlxuICAgICAgdGhpcy5zdGFydC5vZmZzZXQgPD0gdGhpcy5lbmQub2Zmc2V0XG4gICAgKSB7XG4gICAgICAvLyBGYXN0IHBhdGggZm9yIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGluIHNhbWUgZWxlbWVudC5cbiAgICAgIFtzdGFydCwgZW5kXSA9IHJlc29sdmVPZmZzZXRzKFxuICAgICAgICB0aGlzLnN0YXJ0LmVsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhcnQub2Zmc2V0LFxuICAgICAgICB0aGlzLmVuZC5vZmZzZXRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0ID0gdGhpcy5zdGFydC5yZXNvbHZlKHsgZGlyZWN0aW9uOiBSRVNPTFZFX0ZPUldBUkRTIH0pO1xuICAgICAgZW5kID0gdGhpcy5lbmQucmVzb2x2ZSh7IGRpcmVjdGlvbjogUkVTT0xWRV9CQUNLV0FSRFMgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgUmFuZ2UoKTtcbiAgICByYW5nZS5zZXRTdGFydChzdGFydC5ub2RlLCBzdGFydC5vZmZzZXQpO1xuICAgIHJhbmdlLnNldEVuZChlbmQubm9kZSwgZW5kLm9mZnNldCk7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYW4gZXhpc3RpbmcgRE9NIGBSYW5nZWAgdG8gYSBgVGV4dFJhbmdlYFxuICAgKlxuICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZVxuICAgKiBAcmV0dXJuIHtUZXh0UmFuZ2V9XG4gICAqL1xuICBzdGF0aWMgZnJvbVJhbmdlKHJhbmdlKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBUZXh0UG9zaXRpb24uZnJvbVBvaW50KFxuICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIsXG4gICAgICByYW5nZS5zdGFydE9mZnNldFxuICAgICk7XG4gICAgY29uc3QgZW5kID0gVGV4dFBvc2l0aW9uLmZyb21Qb2ludChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7XG4gICAgcmV0dXJuIG5ldyBUZXh0UmFuZ2Uoc3RhcnQsIGVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgYFRleHRSYW5nZWAgZnJvbSB0aGUgYHN0YXJ0YHRoIHRvIGBlbmRgdGggY2hhcmFjdGVycyBpbiBgcm9vdGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZFxuICAgKi9cbiAgc3RhdGljIGZyb21PZmZzZXRzKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gbmV3IFRleHRSYW5nZShcbiAgICAgIG5ldyBUZXh0UG9zaXRpb24ocm9vdCwgc3RhcnQpLFxuICAgICAgbmV3IFRleHRQb3NpdGlvbihyb290LCBlbmQpXG4gICAgKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBUaGlzIG1vZHVsZSBleHBvcnRzIGEgc2V0IG9mIGNsYXNzZXMgZm9yIGNvbnZlcnRpbmcgYmV0d2VlbiBET00gYFJhbmdlYFxuICogb2JqZWN0cyBhbmQgZGlmZmVyZW50IHR5cGVzIG9mIHNlbGVjdG9ycy4gSXQgaXMgbW9zdGx5IGEgdGhpbiB3cmFwcGVyIGFyb3VuZCBhXG4gKiBzZXQgb2YgYW5jaG9yaW5nIGxpYnJhcmllcy4gSXQgc2VydmVzIHR3byBtYWluIHB1cnBvc2VzOlxuICpcbiAqICAxLiBQcm92aWRpbmcgYSBjb25zaXN0ZW50IGludGVyZmFjZSBhY3Jvc3MgZGlmZmVyZW50IHR5cGVzIG9mIGFuY2hvcnMuXG4gKiAgMi4gSW5zdWxhdGluZyB0aGUgcmVzdCBvZiB0aGUgY29kZSBmcm9tIEFQSSBjaGFuZ2VzIGluIHRoZSB1bmRlcmx5aW5nIGFuY2hvcmluZ1xuICogICAgIGxpYnJhcmllcy5cbiAqL1xuXG5pbXBvcnQgeyBtYXRjaFF1b3RlIH0gZnJvbSAnLi9tYXRjaC1xdW90ZSc7XG5pbXBvcnQgeyBUZXh0UmFuZ2UsIFRleHRQb3NpdGlvbiB9IGZyb20gJy4vdGV4dC1yYW5nZSc7XG5pbXBvcnQgeyBub2RlRnJvbVhQYXRoLCB4cGF0aEZyb21Ob2RlIH0gZnJvbSAnLi94cGF0aCc7XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuUmFuZ2VTZWxlY3Rvcn0gUmFuZ2VTZWxlY3RvclxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vLi4vdHlwZXMvYXBpJykuVGV4dFBvc2l0aW9uU2VsZWN0b3J9IFRleHRQb3NpdGlvblNlbGVjdG9yXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi8uLi90eXBlcy9hcGknKS5UZXh0UXVvdGVTZWxlY3Rvcn0gVGV4dFF1b3RlU2VsZWN0b3JcbiAqL1xuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgUmFuZ2VBbmNob3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtOb2RlfSByb290IC0gQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgY29uc3RydWN0b3Iocm9vdCwgcmFuZ2UpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMucmFuZ2UgPSByYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge05vZGV9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gIEEgcmFuZ2UgZGVzY3JpYmluZyB0aGUgYW5jaG9yLlxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5nZShyb290LCByYW5nZSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2VBbmNob3Iocm9vdCwgcmFuZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBhbmNob3IgZnJvbSBhIHNlcmlhbGl6ZWQgYFJhbmdlU2VsZWN0b3JgIHNlbGVjdG9yLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3QgLSAgQSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0byBhbmNob3IuXG4gICAqIEBwYXJhbSB7UmFuZ2VTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIHN0YXRpYyBmcm9tU2VsZWN0b3Iocm9vdCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IG5vZGVGcm9tWFBhdGgoc2VsZWN0b3Iuc3RhcnRDb250YWluZXIsIHJvb3QpO1xuICAgIGlmICghc3RhcnRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgc3RhcnRDb250YWluZXIgWFBhdGgnKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmRDb250YWluZXIgPSBub2RlRnJvbVhQYXRoKHNlbGVjdG9yLmVuZENvbnRhaW5lciwgcm9vdCk7XG4gICAgaWYgKCFlbmRDb250YWluZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc29sdmUgZW5kQ29udGFpbmVyIFhQYXRoJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBzdGFydENvbnRhaW5lcixcbiAgICAgIHNlbGVjdG9yLnN0YXJ0T2Zmc2V0XG4gICAgKTtcbiAgICBjb25zdCBlbmRQb3MgPSBUZXh0UG9zaXRpb24uZnJvbUNoYXJPZmZzZXQoXG4gICAgICBlbmRDb250YWluZXIsXG4gICAgICBzZWxlY3Rvci5lbmRPZmZzZXRcbiAgICApO1xuXG4gICAgY29uc3QgcmFuZ2UgPSBuZXcgVGV4dFJhbmdlKHN0YXJ0UG9zLCBlbmRQb3MpLnRvUmFuZ2UoKTtcbiAgICByZXR1cm4gbmV3IFJhbmdlQW5jaG9yKHJvb3QsIHJhbmdlKTtcbiAgfVxuXG4gIHRvUmFuZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMucmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7UmFuZ2VTZWxlY3Rvcn1cbiAgICovXG4gIHRvU2VsZWN0b3IoKSB7XG4gICAgLy8gXCJTaHJpbmtcIiB0aGUgcmFuZ2Ugc28gdGhhdCBpdCB0aWdodGx5IHdyYXBzIGl0cyB0ZXh0LiBUaGlzIGVuc3VyZXMgbW9yZVxuICAgIC8vIHByZWRpY3RhYmxlIG91dHB1dCBmb3IgYSBnaXZlbiB0ZXh0IHNlbGVjdGlvbi5cbiAgICBjb25zdCBub3JtYWxpemVkUmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHRoaXMucmFuZ2UpLnRvUmFuZ2UoKTtcblxuICAgIGNvbnN0IHRleHRSYW5nZSA9IFRleHRSYW5nZS5mcm9tUmFuZ2Uobm9ybWFsaXplZFJhbmdlKTtcbiAgICBjb25zdCBzdGFydENvbnRhaW5lciA9IHhwYXRoRnJvbU5vZGUodGV4dFJhbmdlLnN0YXJ0LmVsZW1lbnQsIHRoaXMucm9vdCk7XG4gICAgY29uc3QgZW5kQ29udGFpbmVyID0geHBhdGhGcm9tTm9kZSh0ZXh0UmFuZ2UuZW5kLmVsZW1lbnQsIHRoaXMucm9vdCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1JhbmdlU2VsZWN0b3InLFxuICAgICAgc3RhcnRDb250YWluZXIsXG4gICAgICBzdGFydE9mZnNldDogdGV4dFJhbmdlLnN0YXJ0Lm9mZnNldCxcbiAgICAgIGVuZENvbnRhaW5lcixcbiAgICAgIGVuZE9mZnNldDogdGV4dFJhbmdlLmVuZC5vZmZzZXQsXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGJldHdlZW4gYFRleHRQb3NpdGlvblNlbGVjdG9yYCBzZWxlY3RvcnMgYW5kIGBSYW5nZWAgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRQb3NpdGlvbkFuY2hvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHJvb3QsIHN0YXJ0LCBlbmQpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICB0aGlzLmVuZCA9IGVuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKFxuICAgICAgcm9vdCxcbiAgICAgIHRleHRSYW5nZS5zdGFydC5vZmZzZXQsXG4gICAgICB0ZXh0UmFuZ2UuZW5kLm9mZnNldFxuICAgICk7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRQb3NpdGlvblNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIHJldHVybiBuZXcgVGV4dFBvc2l0aW9uQW5jaG9yKHJvb3QsIHNlbGVjdG9yLnN0YXJ0LCBzZWxlY3Rvci5lbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRQb3NpdGlvblNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRQb3NpdGlvblNlbGVjdG9yJyxcbiAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0LFxuICAgICAgZW5kOiB0aGlzLmVuZCxcbiAgICB9O1xuICB9XG5cbiAgdG9SYW5nZSgpIHtcbiAgICByZXR1cm4gVGV4dFJhbmdlLmZyb21PZmZzZXRzKHRoaXMucm9vdCwgdGhpcy5zdGFydCwgdGhpcy5lbmQpLnRvUmFuZ2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIFF1b3RlTWF0Y2hPcHRpb25zXG4gKiBAcHJvcCB7bnVtYmVyfSBbaGludF0gLSBFeHBlY3RlZCBwb3NpdGlvbiBvZiBtYXRjaCBpbiB0ZXh0LiBTZWUgYG1hdGNoUXVvdGVgLlxuICovXG5cbi8qKlxuICogQ29udmVydHMgYmV0d2VlbiBgVGV4dFF1b3RlU2VsZWN0b3JgIHNlbGVjdG9ycyBhbmQgYFJhbmdlYCBvYmplY3RzLlxuICovXG5leHBvcnQgY2xhc3MgVGV4dFF1b3RlQW5jaG9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdCAtIEEgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdG8gYW5jaG9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXhhY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICogICBAcGFyYW0ge3N0cmluZ30gW2NvbnRleHQucHJlZml4XVxuICAgKiAgIEBwYXJhbSB7c3RyaW5nfSBbY29udGV4dC5zdWZmaXhdXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihyb290LCBleGFjdCwgY29udGV4dCA9IHt9KSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgICB0aGlzLmV4YWN0ID0gZXhhY3Q7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBgVGV4dFF1b3RlQW5jaG9yYCBmcm9tIGEgcmFuZ2UuXG4gICAqXG4gICAqIFdpbGwgdGhyb3cgaWYgYHJhbmdlYCBkb2VzIG5vdCBjb250YWluIGFueSB0ZXh0IG5vZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2VcbiAgICovXG4gIHN0YXRpYyBmcm9tUmFuZ2Uocm9vdCwgcmFuZ2UpIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyb290LnRleHRDb250ZW50KTtcbiAgICBjb25zdCB0ZXh0UmFuZ2UgPSBUZXh0UmFuZ2UuZnJvbVJhbmdlKHJhbmdlKS5yZWxhdGl2ZVRvKHJvb3QpO1xuXG4gICAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICAgIGNvbnN0IGVuZCA9IHRleHRSYW5nZS5lbmQub2Zmc2V0O1xuXG4gICAgLy8gTnVtYmVyIG9mIGNoYXJhY3RlcnMgYXJvdW5kIHRoZSBxdW90ZSB0byBjYXB0dXJlIGFzIGNvbnRleHQuIFdlIGN1cnJlbnRseVxuICAgIC8vIGFsd2F5cyB1c2UgYSBmaXhlZCBhbW91bnQsIGJ1dCBpdCB3b3VsZCBiZSBiZXR0ZXIgaWYgdGhpcyBjb2RlIHdhcyBhd2FyZVxuICAgIC8vIG9mIGxvZ2ljYWwgYm91bmRhcmllcyBpbiB0aGUgZG9jdW1lbnQgKHBhcmFncmFwaCwgYXJ0aWNsZSBldGMuKSB0byBhdm9pZFxuICAgIC8vIGNhcHR1cmluZyB0ZXh0IHVucmVsYXRlZCB0byB0aGUgcXVvdGUuXG4gICAgLy9cbiAgICAvLyBJbiByZWd1bGFyIHByb3NlIHRoZSBpZGVhbCBjb250ZW50IHdvdWxkIG9mdGVuIGJlIHRoZSBzdXJyb3VuZGluZyBzZW50ZW5jZS5cbiAgICAvLyBUaGlzIGlzIGEgbmF0dXJhbCB1bml0IG9mIG1lYW5pbmcgd2hpY2ggZW5hYmxlcyBkaXNwbGF5aW5nIHF1b3RlcyBpblxuICAgIC8vIGNvbnRleHQgZXZlbiB3aGVuIHRoZSBkb2N1bWVudCBpcyBub3QgYXZhaWxhYmxlLiBXZSBjb3VsZCB1c2UgYEludGwuU2VnbWVudGVyYFxuICAgIC8vIGZvciB0aGlzIHdoZW4gYXZhaWxhYmxlLlxuICAgIGNvbnN0IGNvbnRleHRMZW4gPSAzMjtcblxuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHRleHQuc2xpY2Uoc3RhcnQsIGVuZCksIHtcbiAgICAgIHByZWZpeDogdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIGNvbnRleHRMZW4pLCBzdGFydCksXG4gICAgICBzdWZmaXg6IHRleHQuc2xpY2UoZW5kLCBNYXRoLm1pbih0ZXh0Lmxlbmd0aCwgZW5kICsgY29udGV4dExlbikpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdFxuICAgKiBAcGFyYW0ge1RleHRRdW90ZVNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgc3RhdGljIGZyb21TZWxlY3Rvcihyb290LCBzZWxlY3Rvcikge1xuICAgIGNvbnN0IHsgcHJlZml4LCBzdWZmaXggfSA9IHNlbGVjdG9yO1xuICAgIHJldHVybiBuZXcgVGV4dFF1b3RlQW5jaG9yKHJvb3QsIHNlbGVjdG9yLmV4YWN0LCB7IHByZWZpeCwgc3VmZml4IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1RleHRRdW90ZVNlbGVjdG9yfVxuICAgKi9cbiAgdG9TZWxlY3RvcigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1RleHRRdW90ZVNlbGVjdG9yJyxcbiAgICAgIGV4YWN0OiB0aGlzLmV4YWN0LFxuICAgICAgcHJlZml4OiB0aGlzLmNvbnRleHQucHJlZml4LFxuICAgICAgc3VmZml4OiB0aGlzLmNvbnRleHQuc3VmZml4LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtRdW90ZU1hdGNoT3B0aW9uc30gW29wdGlvbnNdXG4gICAqL1xuICB0b1JhbmdlKG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnRvUG9zaXRpb25BbmNob3Iob3B0aW9ucykudG9SYW5nZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVvdGVNYXRjaE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKi9cbiAgdG9Qb3NpdGlvbkFuY2hvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB0ZXh0ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovICh0aGlzLnJvb3QudGV4dENvbnRlbnQpO1xuICAgIGNvbnN0IG1hdGNoID0gbWF0Y2hRdW90ZSh0ZXh0LCB0aGlzLmV4YWN0LCB7XG4gICAgICAuLi50aGlzLmNvbnRleHQsXG4gICAgICBoaW50OiBvcHRpb25zLmhpbnQsXG4gICAgfSk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdRdW90ZSBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBUZXh0UG9zaXRpb25BbmNob3IodGhpcy5yb290LCBtYXRjaC5zdGFydCwgbWF0Y2guZW5kKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgVGV4dFF1b3RlQW5jaG9yIH0gZnJvbSBcIi4vdmVuZG9yL2h5cG90aGVzaXMvYW5jaG9yaW5nL3R5cGVzXCI7XG5cbi8vIENhdGNoIEpTIGVycm9ycyB0byBsb2cgdGhlbSBpbiB0aGUgYXBwLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwiZXJyb3JcIixcbiAgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgQW5kcm9pZC5sb2dFcnJvcihldmVudC5tZXNzYWdlLCBldmVudC5maWxlbmFtZSwgZXZlbnQubGluZW5vKTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgIG9uVmlld3BvcnRXaWR0aENoYW5nZWQoKTtcbiAgICAgIHNuYXBDdXJyZW50T2Zmc2V0KCk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudC5ib2R5KTtcbiAgfSxcbiAgZmFsc2Vcbik7XG5cbi8qKlxuICogSGF2aW5nIGFuIG9kZCBudW1iZXIgb2YgY29sdW1ucyB3aGVuIGRpc3BsYXlpbmcgdHdvIGNvbHVtbnMgcGVyIHNjcmVlbiBjYXVzZXMgc25hcHBpbmcgYW5kIHBhZ2VcbiAqIHR1cm5pbmcgaXNzdWVzLiBUbyBmaXggdGhpcywgd2UgaW5zZXJ0IGEgYmxhbmsgdmlydHVhbCBjb2x1bW4gYXQgdGhlIGVuZCBvZiB0aGUgcmVzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGFwcGVuZFZpcnR1YWxDb2x1bW5JZk5lZWRlZCgpIHtcbiAgY29uc3QgaWQgPSBcInJlYWRpdW0tdmlydHVhbC1wYWdlXCI7XG4gIHZhciB2aXJ0dWFsQ29sID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHx8IGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkgIT0gMikge1xuICAgIGlmICh2aXJ0dWFsQ29sKSB7XG4gICAgICB2aXJ0dWFsQ29sLnJlbW92ZSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGNvbENvdW50ID0gZG9jdW1lbnRXaWR0aCAvIHBhZ2VXaWR0aDtcbiAgICB2YXIgaGFzT2RkQ29sQ291bnQgPSAoTWF0aC5yb3VuZChjb2xDb3VudCAqIDIpIC8gMikgJSAxID4gMC4xO1xuICAgIGlmIChoYXNPZGRDb2xDb3VudCkge1xuICAgICAgaWYgKHZpcnR1YWxDb2wpIHtcbiAgICAgICAgdmlydHVhbENvbC5yZW1vdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpcnR1YWxDb2wgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICB2aXJ0dWFsQ29sLnNldEF0dHJpYnV0ZShcImlkXCIsIGlkKTtcbiAgICAgICAgdmlydHVhbENvbC5zdHlsZS5icmVha0JlZm9yZSA9IFwiY29sdW1uXCI7XG4gICAgICAgIHZpcnR1YWxDb2wuaW5uZXJIVE1MID0gXCImIzgyMDM7XCI7IC8vIHplcm8td2lkdGggc3BhY2VcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh2aXJ0dWFsQ29sKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHZhciBwYWdlV2lkdGggPSAxO1xuXG5mdW5jdGlvbiBvblZpZXdwb3J0V2lkdGhDaGFuZ2VkKCkge1xuICAvLyBXZSBjYW4ndCByZWx5IG9uIHdpbmRvdy5pbm5lcldpZHRoIGZvciB0aGUgcGFnZVdpZHRoIG9uIEFuZHJvaWQsIGJlY2F1c2UgaWYgdGhlXG4gIC8vIGRldmljZSBwaXhlbCByYXRpbyBpcyBub3QgYW4gaW50ZWdlciwgd2UgZ2V0IHJvdW5kaW5nIGlzc3VlcyBvZmZzZXR0aW5nIHRoZSBwYWdlcy5cbiAgLy9cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFkaXVtL3JlYWRpdW0tY3NzL2lzc3Vlcy85N1xuICAvLyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL3JlYWRpdW0vcjItbmF2aWdhdG9yLWtvdGxpbi9pc3N1ZXMvMTQ2XG4gIHZhciB3aWR0aCA9IEFuZHJvaWQuZ2V0Vmlld3BvcnRXaWR0aCgpO1xuICBwYWdlV2lkdGggPSB3aWR0aCAvIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBzZXRQcm9wZXJ0eShcbiAgICBcIi0tUlNfX3ZpZXdwb3J0V2lkdGhcIixcbiAgICBcImNhbGMoXCIgKyB3aWR0aCArIFwicHggLyBcIiArIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICsgXCIpXCJcbiAgKTtcblxuICBhcHBlbmRWaXJ0dWFsQ29sdW1uSWZOZWVkZWQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbHVtbkNvdW50UGVyU2NyZWVuKCkge1xuICByZXR1cm4gcGFyc2VJbnQoXG4gICAgd2luZG93XG4gICAgICAuZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpXG4gICAgICAuZ2V0UHJvcGVydHlWYWx1ZShcImNvbHVtbi1jb3VudFwiKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTY3JvbGxNb2RlRW5hYmxlZCgpIHtcbiAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGU7XG4gIHJldHVybiAoXG4gICAgc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tVVNFUl9fdmlld1wiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiIHx8XG4gICAgLy8gRklYTUU6IFdpbGwgbmVlZCB0byBiZSByZW1vdmVkIGluIFJlYWRpdW0gMy4wLCAtLVVTRVJfX3Njcm9sbCB3YXMgaW5jb3JyZWN0LlxuICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCItLVVTRVJfX3Njcm9sbFwiKS50cmltKCkgPT0gXCJyZWFkaXVtLXNjcm9sbC1vblwiXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JUTCgpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmJvZHkuZGlyLnRvTG93ZXJDYXNlKCkgPT0gXCJydGxcIjtcbn1cblxuLy8gU2Nyb2xsIHRvIHRoZSBnaXZlbiBUYWdJZCBpbiBkb2N1bWVudCBhbmQgc25hcC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb0lkKGlkKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gc2Nyb2xsVG9SZWN0KGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG4vLyBQb3NpdGlvbiBtdXN0IGJlIGluIHRoZSByYW5nZSBbMCAtIDFdLCAwLTEwMCUuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb1Bvc2l0aW9uIFwiICsgcG9zaXRpb24pO1xuICBpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID4gMSkge1xuICAgIHRocm93IFwic2Nyb2xsVG9Qb3NpdGlvbigpIG11c3QgYmUgZ2l2ZW4gYSBwb3NpdGlvbiBmcm9tIDAuMCB0byAgMS4wXCI7XG4gIH1cblxuICBsZXQgb2Zmc2V0O1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxIZWlnaHQgKiBwb3NpdGlvbjtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCA9IG9mZnNldDtcbiAgICAvLyB3aW5kb3cuc2Nyb2xsVG8oMCwgb2Zmc2V0KTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgdmFyIGZhY3RvciA9IGlzUlRMKCkgPyAtMSA6IDE7XG4gICAgb2Zmc2V0ID0gZG9jdW1lbnRXaWR0aCAqIHBvc2l0aW9uICogZmFjdG9yO1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgfVxufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBnaXZlbiB0ZXh0IHNuaXBwZXQuXG4vL1xuLy8gVGhlIGV4cGVjdGVkIHRleHQgYXJndW1lbnQgaXMgYSBMb2NhdG9yIFRleHQgb2JqZWN0LCBhcyBkZWZpbmVkIGhlcmU6XG4vLyBodHRwczovL3JlYWRpdW0ub3JnL2FyY2hpdGVjdHVyZS9tb2RlbHMvbG9jYXRvcnMvXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9UZXh0KHRleHQpIHtcbiAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcih7IHRleHQgfSk7XG4gIGlmICghcmFuZ2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc2Nyb2xsVG9SYW5nZShyYW5nZSk7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JhbmdlKHJhbmdlKSB7XG4gIHJldHVybiBzY3JvbGxUb1JlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xufVxuXG5mdW5jdGlvbiBzY3JvbGxUb1JlY3QocmVjdCkge1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPVxuICAgICAgcmVjdC50b3AgKyB3aW5kb3cuc2Nyb2xsWSAtIHdpbmRvdy5pbm5lckhlaWdodCAvIDI7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxMZWZ0ID0gc25hcE9mZnNldChcbiAgICAgIHJlY3QubGVmdCArIHdpbmRvdy5zY3JvbGxYXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9TdGFydCgpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9TdGFydFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wID0gMDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgMCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvRW5kKCkge1xuICAvLyAgICAgICAgQW5kcm9pZC5sb2coXCJzY3JvbGxUb0VuZFwiKTtcbiAgaWYgKCFpc1Njcm9sbE1vZGVFbmFibGVkKCkpIHtcbiAgICB2YXIgZmFjdG9yID0gaXNSVEwoKSA/IC0xIDogMTtcbiAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbExlZnQgPSBzbmFwT2Zmc2V0KFxuICAgICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxXaWR0aCAqIGZhY3RvclxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudC5zY3JvbGxUb3AgPSBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodDtcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQpO1xuICB9XG59XG5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2UgaXMgYWxyZWFkeSBhdCB0aGUgbGVmdC1tb3N0IHNjcm9sbCBvZmZzZXQuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsTGVmdCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggLSBwYWdlV2lkdGg7XG4gIHZhciBtaW5PZmZzZXQgPSBpc1JUTCgpID8gLShkb2N1bWVudFdpZHRoIC0gcGFnZVdpZHRoKSA6IDA7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1heChvZmZzZXQsIG1pbk9mZnNldCkpO1xufVxuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSBwYWdlIGlzIGFscmVhZHkgYXQgdGhlIHJpZ2h0LW1vc3Qgc2Nyb2xsIG9mZnNldC5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxSaWdodCgpIHtcbiAgdmFyIGRvY3VtZW50V2lkdGggPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnNjcm9sbFdpZHRoO1xuICB2YXIgb2Zmc2V0ID0gd2luZG93LnNjcm9sbFggKyBwYWdlV2lkdGg7XG4gIHZhciBtYXhPZmZzZXQgPSBpc1JUTCgpID8gMCA6IGRvY3VtZW50V2lkdGggLSBwYWdlV2lkdGg7XG4gIHJldHVybiBzY3JvbGxUb09mZnNldChNYXRoLm1pbihvZmZzZXQsIG1heE9mZnNldCkpO1xufVxuXG4vLyBTY3JvbGxzIHRvIHRoZSBnaXZlbiBsZWZ0IG9mZnNldC5cbi8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHBhZ2Ugc2Nyb2xsIHBvc2l0aW9uIGlzIGFscmVhZHkgY2xvc2UgZW5vdWdoIHRvIHRoZSBnaXZlbiBvZmZzZXQuXG5mdW5jdGlvbiBzY3JvbGxUb09mZnNldChvZmZzZXQpIHtcbiAgLy8gICAgICAgIEFuZHJvaWQubG9nKFwic2Nyb2xsVG9PZmZzZXQgXCIgKyBvZmZzZXQpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgdGhyb3cgXCJDYWxsZWQgc2Nyb2xsVG9PZmZzZXQoKSB3aXRoIHNjcm9sbCBtb2RlIGVuYWJsZWQuIFRoaXMgY2FuIG9ubHkgYmUgdXNlZCBpbiBwYWdpbmF0ZWQgbW9kZS5cIjtcbiAgfVxuXG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQob2Zmc2V0KTtcbiAgLy8gSW4gc29tZSBjYXNlIHRoZSBzY3JvbGxYIGNhbm5vdCByZWFjaCB0aGUgcG9zaXRpb24gcmVzcGVjdGluZyB0byBpbm5lcldpZHRoXG4gIHZhciBkaWZmID0gTWF0aC5hYnMoY3VycmVudE9mZnNldCAtIG9mZnNldCkgLyBwYWdlV2lkdGg7XG4gIHJldHVybiBkaWZmID4gMC4wMTtcbn1cblxuLy8gU25hcCB0aGUgb2Zmc2V0IHRvIHRoZSBzY3JlZW4gd2lkdGggKHBhZ2Ugd2lkdGgpLlxuZnVuY3Rpb24gc25hcE9mZnNldChvZmZzZXQpIHtcbiAgdmFyIHZhbHVlID0gb2Zmc2V0ICsgKGlzUlRMKCkgPyAtMSA6IDEpO1xuICByZXR1cm4gdmFsdWUgLSAodmFsdWUgJSBwYWdlV2lkdGgpO1xufVxuXG4vLyBTbmFwcyB0aGUgY3VycmVudCBvZmZzZXQgdG8gdGhlIHBhZ2Ugd2lkdGguXG5leHBvcnQgZnVuY3Rpb24gc25hcEN1cnJlbnRPZmZzZXQoKSB7XG4gIC8vICAgICAgICBBbmRyb2lkLmxvZyhcInNuYXBDdXJyZW50T2Zmc2V0XCIpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjdXJyZW50T2Zmc2V0ID0gd2luZG93LnNjcm9sbFg7XG4gIC8vIEFkZHMgaGFsZiBhIHBhZ2UgdG8gbWFrZSBzdXJlIHdlIGRvbid0IHNuYXAgdG8gdGhlIHByZXZpb3VzIHBhZ2UuXG4gIHZhciBmYWN0b3IgPSBpc1JUTCgpID8gLTEgOiAxO1xuICB2YXIgZGVsdGEgPSBmYWN0b3IgKiAocGFnZVdpZHRoIC8gMik7XG4gIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdCA9IHNuYXBPZmZzZXQoY3VycmVudE9mZnNldCArIGRlbHRhKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlRnJvbUxvY2F0b3IobG9jYXRvcikge1xuICB0cnkge1xuICAgIGxldCBsb2NhdGlvbnMgPSBsb2NhdG9yLmxvY2F0aW9ucztcbiAgICBsZXQgdGV4dCA9IGxvY2F0b3IudGV4dDtcbiAgICBpZiAodGV4dCAmJiB0ZXh0LmhpZ2hsaWdodCkge1xuICAgICAgdmFyIHJvb3Q7XG4gICAgICBpZiAobG9jYXRpb25zICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICByb290ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuICAgICAgaWYgKCFyb290KSB7XG4gICAgICAgIHJvb3QgPSBkb2N1bWVudC5ib2R5O1xuICAgICAgfVxuXG4gICAgICBsZXQgYW5jaG9yID0gbmV3IFRleHRRdW90ZUFuY2hvcihyb290LCB0ZXh0LmhpZ2hsaWdodCwge1xuICAgICAgICBwcmVmaXg6IHRleHQuYmVmb3JlLFxuICAgICAgICBzdWZmaXg6IHRleHQuYWZ0ZXIsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhbmNob3IudG9SYW5nZSgpO1xuICAgIH1cblxuICAgIGlmIChsb2NhdGlvbnMpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gbnVsbDtcblxuICAgICAgaWYgKCFlbGVtZW50ICYmIGxvY2F0aW9ucy5jc3NTZWxlY3Rvcikge1xuICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihsb2NhdGlvbnMuY3NzU2VsZWN0b3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnQgJiYgbG9jYXRpb25zLmZyYWdtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IGh0bWxJZCBvZiBsb2NhdGlvbnMuZnJhZ21lbnRzKSB7XG4gICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGh0bWxJZCk7XG4gICAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBsZXQgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEJlZm9yZShlbGVtZW50KTtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kQWZ0ZXIoZWxlbWVudCk7XG4gICAgICAgIHJldHVybiByYW5nZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dFcnJvcihlKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vLy8gVXNlciBTZXR0aW5ncy5cblxuZXhwb3J0IGZ1bmN0aW9uIHNldENTU1Byb3BlcnRpZXMocHJvcGVydGllcykge1xuICBmb3IgKGNvbnN0IG5hbWUgaW4gcHJvcGVydGllcykge1xuICAgIHNldFByb3BlcnR5KG5hbWUsIHByb3BlcnRpZXNbbmFtZV0pO1xuICB9XG59XG5cbi8vIEZvciBzZXR0aW5nIHVzZXIgc2V0dGluZy5cbmV4cG9ydCBmdW5jdGlvbiBzZXRQcm9wZXJ0eShrZXksIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikge1xuICAgIHJlbW92ZVByb3BlcnR5KGtleSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgLy8gVGhlIGAhaW1wb3J0YW50YCBhbm5vdGF0aW9uIGlzIGFkZGVkIHdpdGggYHNldFByb3BlcnR5KClgIGJlY2F1c2UgaWYgaXQncyBwYXJ0IG9mIHRoZVxuICAgIC8vIGB2YWx1ZWAsIGl0IHdpbGwgYmUgaWdub3JlZCBieSB0aGUgV2ViIFZpZXcuXG4gICAgcm9vdC5zdHlsZS5zZXRQcm9wZXJ0eShrZXksIHZhbHVlLCBcImltcG9ydGFudFwiKTtcbiAgfVxufVxuXG4vLyBGb3IgcmVtb3ZpbmcgdXNlciBzZXR0aW5nLlxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5KGtleSkge1xuICB2YXIgcm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuICByb290LnN0eWxlLnJlbW92ZVByb3BlcnR5KGtleSk7XG59XG5cbi8vLyBUb29sa2l0XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2coKSB7XG4gIHZhciBtZXNzYWdlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKFwiIFwiKTtcbiAgQW5kcm9pZC5sb2cobWVzc2FnZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dFcnJvcihtZXNzYWdlKSB7XG4gIEFuZHJvaWQubG9nRXJyb3IobWVzc2FnZSwgXCJcIiwgMCk7XG59XG4iLCIvL1xuLy8gIENvcHlyaWdodCAyMDIxIFJlYWRpdW0gRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2Vcbi8vICBhdmFpbGFibGUgaW4gdGhlIHRvcC1sZXZlbCBMSUNFTlNFIGZpbGUgb2YgdGhlIHByb2plY3QuXG4vL1xuXG5pbXBvcnQgeyBsb2cgYXMgbG9nTmF0aXZlIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuY29uc3QgZGVidWcgPSBmYWxzZTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIERPTVJlY3QgaW50byBhIEpTT04gb2JqZWN0IHVuZGVyc3RhbmRhYmxlIGJ5IHRoZSBuYXRpdmUgc2lkZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvTmF0aXZlUmVjdChyZWN0KSB7XG4gIGNvbnN0IHBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgY29uc3Qgd2lkdGggPSByZWN0LndpZHRoICogcGl4ZWxSYXRpbztcbiAgY29uc3QgaGVpZ2h0ID0gcmVjdC5oZWlnaHQgKiBwaXhlbFJhdGlvO1xuICBjb25zdCBsZWZ0ID0gcmVjdC5sZWZ0ICogcGl4ZWxSYXRpbztcbiAgY29uc3QgdG9wID0gcmVjdC50b3AgKiBwaXhlbFJhdGlvO1xuICBjb25zdCByaWdodCA9IGxlZnQgKyB3aWR0aDtcbiAgY29uc3QgYm90dG9tID0gdG9wICsgaGVpZ2h0O1xuICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0LCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20gfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsaWVudFJlY3RzTm9PdmVybGFwKFxuICByYW5nZSxcbiAgZG9Ob3RNZXJnZUhvcml6b250YWxseUFsaWduZWRSZWN0c1xuKSB7XG4gIGxldCBjbGllbnRSZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG5cbiAgY29uc3QgdG9sZXJhbmNlID0gMTtcbiAgY29uc3Qgb3JpZ2luYWxSZWN0cyA9IFtdO1xuICBmb3IgKGNvbnN0IHJhbmdlQ2xpZW50UmVjdCBvZiBjbGllbnRSZWN0cykge1xuICAgIG9yaWdpbmFsUmVjdHMucHVzaCh7XG4gICAgICBib3R0b206IHJhbmdlQ2xpZW50UmVjdC5ib3R0b20sXG4gICAgICBoZWlnaHQ6IHJhbmdlQ2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICBsZWZ0OiByYW5nZUNsaWVudFJlY3QubGVmdCxcbiAgICAgIHJpZ2h0OiByYW5nZUNsaWVudFJlY3QucmlnaHQsXG4gICAgICB0b3A6IHJhbmdlQ2xpZW50UmVjdC50b3AsXG4gICAgICB3aWR0aDogcmFuZ2VDbGllbnRSZWN0LndpZHRoLFxuICAgIH0pO1xuICB9XG4gIGNvbnN0IG1lcmdlZFJlY3RzID0gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgIG9yaWdpbmFsUmVjdHMsXG4gICAgdG9sZXJhbmNlLFxuICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgKTtcbiAgY29uc3Qgbm9Db250YWluZWRSZWN0cyA9IHJlbW92ZUNvbnRhaW5lZFJlY3RzKG1lcmdlZFJlY3RzLCB0b2xlcmFuY2UpO1xuICBjb25zdCBuZXdSZWN0cyA9IHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobm9Db250YWluZWRSZWN0cyk7XG4gIGNvbnN0IG1pbkFyZWEgPSAyICogMjtcbiAgZm9yIChsZXQgaiA9IG5ld1JlY3RzLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgY29uc3QgcmVjdCA9IG5ld1JlY3RzW2pdO1xuICAgIGNvbnN0IGJpZ0Vub3VnaCA9IHJlY3Qud2lkdGggKiByZWN0LmhlaWdodCA+IG1pbkFyZWE7XG4gICAgaWYgKCFiaWdFbm91Z2gpIHtcbiAgICAgIGlmIChuZXdSZWN0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGxcIik7XG4gICAgICAgIG5ld1JlY3RzLnNwbGljZShqLCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgc21hbGwsIGJ1dCBrZWVwIG90aGVyd2lzZSBlbXB0eSFcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBsb2coYENMSUVOVCBSRUNUOiByZWR1Y2VkICR7b3JpZ2luYWxSZWN0cy5sZW5ndGh9IC0tPiAke25ld1JlY3RzLmxlbmd0aH1gKTtcbiAgcmV0dXJuIG5ld1JlY3RzO1xufVxuXG5mdW5jdGlvbiBtZXJnZVRvdWNoaW5nUmVjdHMoXG4gIHJlY3RzLFxuICB0b2xlcmFuY2UsXG4gIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbikge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJtZXJnZVRvdWNoaW5nUmVjdHMgcmVjdDEgPT09IHJlY3QyID8/IVwiKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0c0xpbmVVcFZlcnRpY2FsbHkgPVxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS50b3AsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKTtcbiAgICAgIGNvbnN0IHJlY3RzTGluZVVwSG9yaXpvbnRhbGx5ID1cbiAgICAgICAgYWxtb3N0RXF1YWwocmVjdDEubGVmdCwgcmVjdDIubGVmdCwgdG9sZXJhbmNlKSAmJlxuICAgICAgICBhbG1vc3RFcXVhbChyZWN0MS5yaWdodCwgcmVjdDIucmlnaHQsIHRvbGVyYW5jZSk7XG4gICAgICBjb25zdCBob3Jpem9udGFsQWxsb3dlZCA9ICFkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzO1xuICAgICAgY29uc3QgYWxpZ25lZCA9XG4gICAgICAgIChyZWN0c0xpbmVVcEhvcml6b250YWxseSAmJiBob3Jpem9udGFsQWxsb3dlZCkgfHxcbiAgICAgICAgKHJlY3RzTGluZVVwVmVydGljYWxseSAmJiAhcmVjdHNMaW5lVXBIb3Jpem9udGFsbHkpO1xuICAgICAgY29uc3QgY2FuTWVyZ2UgPSBhbGlnbmVkICYmIHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCB0b2xlcmFuY2UpO1xuICAgICAgaWYgKGNhbk1lcmdlKSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICBgQ0xJRU5UIFJFQ1Q6IG1lcmdpbmcgdHdvIGludG8gb25lLCBWRVJUSUNBTDogJHtyZWN0c0xpbmVVcFZlcnRpY2FsbHl9IEhPUklaT05UQUw6ICR7cmVjdHNMaW5lVXBIb3Jpem9udGFsbHl9ICgke2RvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHN9KWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbmV3UmVjdHMgPSByZWN0cy5maWx0ZXIoKHJlY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVjdCAhPT0gcmVjdDEgJiYgcmVjdCAhPT0gcmVjdDI7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXBsYWNlbWVudENsaWVudFJlY3QgPSBnZXRCb3VuZGluZ1JlY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgbmV3UmVjdHMucHVzaChyZXBsYWNlbWVudENsaWVudFJlY3QpO1xuICAgICAgICByZXR1cm4gbWVyZ2VUb3VjaGluZ1JlY3RzKFxuICAgICAgICAgIG5ld1JlY3RzLFxuICAgICAgICAgIHRvbGVyYW5jZSxcbiAgICAgICAgICBkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRpbmdSZWN0KHJlY3QxLCByZWN0Mikge1xuICBjb25zdCBsZWZ0ID0gTWF0aC5taW4ocmVjdDEubGVmdCwgcmVjdDIubGVmdCk7XG4gIGNvbnN0IHJpZ2h0ID0gTWF0aC5tYXgocmVjdDEucmlnaHQsIHJlY3QyLnJpZ2h0KTtcbiAgY29uc3QgdG9wID0gTWF0aC5taW4ocmVjdDEudG9wLCByZWN0Mi50b3ApO1xuICBjb25zdCBib3R0b20gPSBNYXRoLm1heChyZWN0MS5ib3R0b20sIHJlY3QyLmJvdHRvbSk7XG4gIHJldHVybiB7XG4gICAgYm90dG9tLFxuICAgIGhlaWdodDogYm90dG9tIC0gdG9wLFxuICAgIGxlZnQsXG4gICAgcmlnaHQsXG4gICAgdG9wLFxuICAgIHdpZHRoOiByaWdodCAtIGxlZnQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNvbnRhaW5lZFJlY3RzKHJlY3RzLCB0b2xlcmFuY2UpIHtcbiAgY29uc3QgcmVjdHNUb0tlZXAgPSBuZXcgU2V0KHJlY3RzKTtcbiAgZm9yIChjb25zdCByZWN0IG9mIHJlY3RzKSB7XG4gICAgY29uc3QgYmlnRW5vdWdoID0gcmVjdC53aWR0aCA+IDEgJiYgcmVjdC5oZWlnaHQgPiAxO1xuICAgIGlmICghYmlnRW5vdWdoKSB7XG4gICAgICBsb2coXCJDTElFTlQgUkVDVDogcmVtb3ZlIHRpbnlcIik7XG4gICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwb3NzaWJseUNvbnRhaW5pbmdSZWN0IG9mIHJlY3RzKSB7XG4gICAgICBpZiAocmVjdCA9PT0gcG9zc2libHlDb250YWluaW5nUmVjdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjdHNUb0tlZXAuaGFzKHBvc3NpYmx5Q29udGFpbmluZ1JlY3QpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RDb250YWlucyhwb3NzaWJseUNvbnRhaW5pbmdSZWN0LCByZWN0LCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIGxvZyhcIkNMSUVOVCBSRUNUOiByZW1vdmUgY29udGFpbmVkXCIpO1xuICAgICAgICByZWN0c1RvS2VlcC5kZWxldGUocmVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gQXJyYXkuZnJvbShyZWN0c1RvS2VlcCk7XG59XG5cbmZ1bmN0aW9uIHJlY3RDb250YWlucyhyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi50b3AsIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLnRvcCwgdG9sZXJhbmNlKSAmJlxuICAgIHJlY3RDb250YWluc1BvaW50KHJlY3QxLCByZWN0Mi5sZWZ0LCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkgJiZcbiAgICByZWN0Q29udGFpbnNQb2ludChyZWN0MSwgcmVjdDIucmlnaHQsIHJlY3QyLmJvdHRvbSwgdG9sZXJhbmNlKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjdENvbnRhaW5zUG9pbnQocmVjdCwgeCwgeSwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiAoXG4gICAgKHJlY3QubGVmdCA8IHggfHwgYWxtb3N0RXF1YWwocmVjdC5sZWZ0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnJpZ2h0ID4geCB8fCBhbG1vc3RFcXVhbChyZWN0LnJpZ2h0LCB4LCB0b2xlcmFuY2UpKSAmJlxuICAgIChyZWN0LnRvcCA8IHkgfHwgYWxtb3N0RXF1YWwocmVjdC50b3AsIHksIHRvbGVyYW5jZSkpICYmXG4gICAgKHJlY3QuYm90dG9tID4geSB8fCBhbG1vc3RFcXVhbChyZWN0LmJvdHRvbSwgeSwgdG9sZXJhbmNlKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZU92ZXJsYXBpbmdSZWN0cyhyZWN0cykge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJlY3QxID0gcmVjdHNbaV07XG4gICAgICBjb25zdCByZWN0MiA9IHJlY3RzW2pdO1xuICAgICAgaWYgKHJlY3QxID09PSByZWN0Mikge1xuICAgICAgICBsb2coXCJyZXBsYWNlT3ZlcmxhcGluZ1JlY3RzIHJlY3QxID09PSByZWN0MiA/PyFcIik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3RzVG91Y2hPck92ZXJsYXAocmVjdDEsIHJlY3QyLCAtMSkpIHtcbiAgICAgICAgbGV0IHRvQWRkID0gW107XG4gICAgICAgIGxldCB0b1JlbW92ZTtcbiAgICAgICAgY29uc3Qgc3VidHJhY3RSZWN0czEgPSByZWN0U3VidHJhY3QocmVjdDEsIHJlY3QyKTtcbiAgICAgICAgaWYgKHN1YnRyYWN0UmVjdHMxLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgdG9SZW1vdmUgPSByZWN0MTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdWJ0cmFjdFJlY3RzMiA9IHJlY3RTdWJ0cmFjdChyZWN0MiwgcmVjdDEpO1xuICAgICAgICAgIGlmIChzdWJ0cmFjdFJlY3RzMS5sZW5ndGggPCBzdWJ0cmFjdFJlY3RzMi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRvQWRkID0gc3VidHJhY3RSZWN0czE7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IHJlY3QxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b0FkZCA9IHN1YnRyYWN0UmVjdHMyO1xuICAgICAgICAgICAgdG9SZW1vdmUgPSByZWN0MjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbG9nKGBDTElFTlQgUkVDVDogb3ZlcmxhcCwgY3V0IG9uZSByZWN0IGludG8gJHt0b0FkZC5sZW5ndGh9YCk7XG4gICAgICAgIGNvbnN0IG5ld1JlY3RzID0gcmVjdHMuZmlsdGVyKChyZWN0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlY3QgIT09IHRvUmVtb3ZlO1xuICAgICAgICB9KTtcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkobmV3UmVjdHMsIHRvQWRkKTtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VPdmVybGFwaW5nUmVjdHMobmV3UmVjdHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVjdHM7XG59XG5cbmZ1bmN0aW9uIHJlY3RTdWJ0cmFjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgcmVjdEludGVyc2VjdGVkID0gcmVjdEludGVyc2VjdChyZWN0MiwgcmVjdDEpO1xuICBpZiAocmVjdEludGVyc2VjdGVkLmhlaWdodCA9PT0gMCB8fCByZWN0SW50ZXJzZWN0ZWQud2lkdGggPT09IDApIHtcbiAgICByZXR1cm4gW3JlY3QxXTtcbiAgfVxuICBjb25zdCByZWN0cyA9IFtdO1xuICB7XG4gICAgY29uc3QgcmVjdEEgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3QxLmxlZnQsXG4gICAgICByaWdodDogcmVjdEludGVyc2VjdGVkLmxlZnQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEEud2lkdGggPSByZWN0QS5yaWdodCAtIHJlY3RBLmxlZnQ7XG4gICAgcmVjdEEuaGVpZ2h0ID0gcmVjdEEuYm90dG9tIC0gcmVjdEEudG9wO1xuICAgIGlmIChyZWN0QS5oZWlnaHQgIT09IDAgJiYgcmVjdEEud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEEpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEIgPSB7XG4gICAgICBib3R0b206IHJlY3RJbnRlcnNlY3RlZC50b3AsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiByZWN0SW50ZXJzZWN0ZWQubGVmdCxcbiAgICAgIHJpZ2h0OiByZWN0SW50ZXJzZWN0ZWQucmlnaHQsXG4gICAgICB0b3A6IHJlY3QxLnRvcCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEIud2lkdGggPSByZWN0Qi5yaWdodCAtIHJlY3RCLmxlZnQ7XG4gICAgcmVjdEIuaGVpZ2h0ID0gcmVjdEIuYm90dG9tIC0gcmVjdEIudG9wO1xuICAgIGlmIChyZWN0Qi5oZWlnaHQgIT09IDAgJiYgcmVjdEIud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEIpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEMgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5sZWZ0LFxuICAgICAgcmlnaHQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHRvcDogcmVjdEludGVyc2VjdGVkLmJvdHRvbSxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH07XG4gICAgcmVjdEMud2lkdGggPSByZWN0Qy5yaWdodCAtIHJlY3RDLmxlZnQ7XG4gICAgcmVjdEMuaGVpZ2h0ID0gcmVjdEMuYm90dG9tIC0gcmVjdEMudG9wO1xuICAgIGlmIChyZWN0Qy5oZWlnaHQgIT09IDAgJiYgcmVjdEMud2lkdGggIT09IDApIHtcbiAgICAgIHJlY3RzLnB1c2gocmVjdEMpO1xuICAgIH1cbiAgfVxuICB7XG4gICAgY29uc3QgcmVjdEQgPSB7XG4gICAgICBib3R0b206IHJlY3QxLmJvdHRvbSxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IHJlY3RJbnRlcnNlY3RlZC5yaWdodCxcbiAgICAgIHJpZ2h0OiByZWN0MS5yaWdodCxcbiAgICAgIHRvcDogcmVjdDEudG9wLFxuICAgICAgd2lkdGg6IDAsXG4gICAgfTtcbiAgICByZWN0RC53aWR0aCA9IHJlY3RELnJpZ2h0IC0gcmVjdEQubGVmdDtcbiAgICByZWN0RC5oZWlnaHQgPSByZWN0RC5ib3R0b20gLSByZWN0RC50b3A7XG4gICAgaWYgKHJlY3RELmhlaWdodCAhPT0gMCAmJiByZWN0RC53aWR0aCAhPT0gMCkge1xuICAgICAgcmVjdHMucHVzaChyZWN0RCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0cztcbn1cblxuZnVuY3Rpb24gcmVjdEludGVyc2VjdChyZWN0MSwgcmVjdDIpIHtcbiAgY29uc3QgbWF4TGVmdCA9IE1hdGgubWF4KHJlY3QxLmxlZnQsIHJlY3QyLmxlZnQpO1xuICBjb25zdCBtaW5SaWdodCA9IE1hdGgubWluKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCk7XG4gIGNvbnN0IG1heFRvcCA9IE1hdGgubWF4KHJlY3QxLnRvcCwgcmVjdDIudG9wKTtcbiAgY29uc3QgbWluQm90dG9tID0gTWF0aC5taW4ocmVjdDEuYm90dG9tLCByZWN0Mi5ib3R0b20pO1xuICByZXR1cm4ge1xuICAgIGJvdHRvbTogbWluQm90dG9tLFxuICAgIGhlaWdodDogTWF0aC5tYXgoMCwgbWluQm90dG9tIC0gbWF4VG9wKSxcbiAgICBsZWZ0OiBtYXhMZWZ0LFxuICAgIHJpZ2h0OiBtaW5SaWdodCxcbiAgICB0b3A6IG1heFRvcCxcbiAgICB3aWR0aDogTWF0aC5tYXgoMCwgbWluUmlnaHQgLSBtYXhMZWZ0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVjdHNUb3VjaE9yT3ZlcmxhcChyZWN0MSwgcmVjdDIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gKFxuICAgIChyZWN0MS5sZWZ0IDwgcmVjdDIucmlnaHQgfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0MS5sZWZ0LCByZWN0Mi5yaWdodCwgdG9sZXJhbmNlKSkpICYmXG4gICAgKHJlY3QyLmxlZnQgPCByZWN0MS5yaWdodCB8fFxuICAgICAgKHRvbGVyYW5jZSA+PSAwICYmIGFsbW9zdEVxdWFsKHJlY3QyLmxlZnQsIHJlY3QxLnJpZ2h0LCB0b2xlcmFuY2UpKSkgJiZcbiAgICAocmVjdDEudG9wIDwgcmVjdDIuYm90dG9tIHx8XG4gICAgICAodG9sZXJhbmNlID49IDAgJiYgYWxtb3N0RXF1YWwocmVjdDEudG9wLCByZWN0Mi5ib3R0b20sIHRvbGVyYW5jZSkpKSAmJlxuICAgIChyZWN0Mi50b3AgPCByZWN0MS5ib3R0b20gfHxcbiAgICAgICh0b2xlcmFuY2UgPj0gMCAmJiBhbG1vc3RFcXVhbChyZWN0Mi50b3AsIHJlY3QxLmJvdHRvbSwgdG9sZXJhbmNlKSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGFsbW9zdEVxdWFsKGEsIGIsIHRvbGVyYW5jZSkge1xuICByZXR1cm4gTWF0aC5hYnMoYSAtIGIpIDw9IHRvbGVyYW5jZTtcbn1cblxuZnVuY3Rpb24gbG9nKCkge1xuICBpZiAoZGVidWcpIHtcbiAgICBsb2dOYXRpdmUuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHtcbiAgZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAsXG4gIHJlY3RDb250YWluc1BvaW50LFxuICB0b05hdGl2ZVJlY3QsXG59IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IGxvZywgbG9nRXJyb3IsIHJhbmdlRnJvbUxvY2F0b3IgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5sZXQgc3R5bGVzID0gbmV3IE1hcCgpO1xubGV0IGdyb3VwcyA9IG5ldyBNYXAoKTtcbnZhciBsYXN0R3JvdXBJZCA9IDA7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgbGlzdCBvZiBhZGRpdGlvbmFsIHN1cHBvcnRlZCBEZWNvcmF0aW9uIFRlbXBsYXRlcy5cbiAqXG4gKiBFYWNoIHRlbXBsYXRlIG9iamVjdCBpcyBpbmRleGVkIGJ5IHRoZSBzdHlsZSBJRC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyVGVtcGxhdGVzKG5ld1N0eWxlcykge1xuICB2YXIgc3R5bGVzaGVldCA9IFwiXCI7XG5cbiAgZm9yIChjb25zdCBbaWQsIHN0eWxlXSBvZiBPYmplY3QuZW50cmllcyhuZXdTdHlsZXMpKSB7XG4gICAgc3R5bGVzLnNldChpZCwgc3R5bGUpO1xuICAgIGlmIChzdHlsZS5zdHlsZXNoZWV0KSB7XG4gICAgICBzdHlsZXNoZWV0ICs9IHN0eWxlLnN0eWxlc2hlZXQgKyBcIlxcblwiO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdHlsZXNoZWV0KSB7XG4gICAgbGV0IHN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICBzdHlsZUVsZW1lbnQuaW5uZXJIVE1MID0gc3R5bGVzaGVldDtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRGVjb3JhdGlvbkdyb3VwIGZvciB0aGUgZ2l2ZW4gZ3JvdXAgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlY29yYXRpb25zKGdyb3VwTmFtZSkge1xuICB2YXIgZ3JvdXAgPSBncm91cHMuZ2V0KGdyb3VwTmFtZSk7XG4gIGlmICghZ3JvdXApIHtcbiAgICBsZXQgaWQgPSBcInIyLWRlY29yYXRpb24tXCIgKyBsYXN0R3JvdXBJZCsrO1xuICAgIGdyb3VwID0gRGVjb3JhdGlvbkdyb3VwKGlkLCBncm91cE5hbWUpO1xuICAgIGdyb3Vwcy5zZXQoZ3JvdXBOYW1lLCBncm91cCk7XG4gIH1cbiAgcmV0dXJuIGdyb3VwO1xufVxuXG4vKipcbiAqIEhhbmRsZXMgY2xpY2sgZXZlbnRzIG9uIGEgRGVjb3JhdGlvbi5cbiAqIFJldHVybnMgd2hldGhlciBhIGRlY29yYXRpb24gbWF0Y2hlZCB0aGlzIGV2ZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRGVjb3JhdGlvbkNsaWNrRXZlbnQoZXZlbnQsIGNsaWNrRXZlbnQpIHtcbiAgaWYgKGdyb3Vwcy5zaXplID09PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZFRhcmdldCgpIHtcbiAgICBmb3IgKGNvbnN0IFtncm91cCwgZ3JvdXBDb250ZW50XSBvZiBncm91cHMpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBncm91cENvbnRlbnQuaXRlbXMucmV2ZXJzZSgpKSB7XG4gICAgICAgIGlmICghaXRlbS5jbGlja2FibGVFbGVtZW50cykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzKSB7XG4gICAgICAgICAgbGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvSlNPTigpO1xuICAgICAgICAgIGlmIChyZWN0Q29udGFpbnNQb2ludChyZWN0LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCAxKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgZ3JvdXAsIGl0ZW0sIGVsZW1lbnQsIHJlY3QgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgdGFyZ2V0ID0gZmluZFRhcmdldCgpO1xuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBBbmRyb2lkLm9uRGVjb3JhdGlvbkFjdGl2YXRlZChcbiAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBpZDogdGFyZ2V0Lml0ZW0uZGVjb3JhdGlvbi5pZCxcbiAgICAgIGdyb3VwOiB0YXJnZXQuZ3JvdXAsXG4gICAgICByZWN0OiB0b05hdGl2ZVJlY3QodGFyZ2V0Lml0ZW0ucmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpLFxuICAgICAgY2xpY2s6IGNsaWNrRXZlbnQsXG4gICAgfSlcbiAgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgRGVjb3JhdGlvbkdyb3VwIG9iamVjdCBmcm9tIGEgdW5pcXVlIEhUTUwgSUQgYW5kIGl0cyBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gRGVjb3JhdGlvbkdyb3VwKGdyb3VwSWQsIGdyb3VwTmFtZSkge1xuICB2YXIgaXRlbXMgPSBbXTtcbiAgdmFyIGxhc3RJdGVtSWQgPSAwO1xuICB2YXIgY29udGFpbmVyID0gbnVsbDtcblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBkZWNvcmF0aW9uIHRvIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIGFkZChkZWNvcmF0aW9uKSB7XG4gICAgbGV0IGlkID0gZ3JvdXBJZCArIFwiLVwiICsgbGFzdEl0ZW1JZCsrO1xuXG4gICAgbGV0IHJhbmdlID0gcmFuZ2VGcm9tTG9jYXRvcihkZWNvcmF0aW9uLmxvY2F0b3IpO1xuICAgIGlmICghcmFuZ2UpIHtcbiAgICAgIGxvZyhcIkNhbid0IGxvY2F0ZSBET00gcmFuZ2UgZm9yIGRlY29yYXRpb25cIiwgZGVjb3JhdGlvbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSB7IGlkLCBkZWNvcmF0aW9uLCByYW5nZSB9O1xuICAgIGl0ZW1zLnB1c2goaXRlbSk7XG4gICAgbGF5b3V0KGl0ZW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGRlY29yYXRpb24gd2l0aCBnaXZlbiBJRCBmcm9tIHRoZSBncm91cC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZShkZWNvcmF0aW9uSWQpIHtcbiAgICBsZXQgaW5kZXggPSBpdGVtcy5maW5kSW5kZXgoKGkpID0+IGkuZGVjb3JhdGlvbi5pZCA9PT0gZGVjb3JhdGlvbklkKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGl0ZW0gPSBpdGVtc1tpbmRleF07XG4gICAgaXRlbXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gbnVsbDtcbiAgICBpZiAoaXRlbS5jb250YWluZXIpIHtcbiAgICAgIGl0ZW0uY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgaXRlbS5jb250YWluZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZmllcyB0aGF0IHRoZSBnaXZlbiBkZWNvcmF0aW9uIHdhcyBtb2RpZmllZCBhbmQgbmVlZHMgdG8gYmUgdXBkYXRlZC5cbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZShkZWNvcmF0aW9uKSB7XG4gICAgcmVtb3ZlKGRlY29yYXRpb24uaWQpO1xuICAgIGFkZChkZWNvcmF0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFsbCBkZWNvcmF0aW9ucyBmcm9tIHRoaXMgZ3JvdXAuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICBjbGVhckNvbnRhaW5lcigpO1xuICAgIGl0ZW1zLmxlbmd0aCA9IDA7XG4gIH1cblxuICAvKipcbiAgICogUmVjcmVhdGVzIHRoZSBkZWNvcmF0aW9uIGVsZW1lbnRzLlxuICAgKlxuICAgKiBUbyBiZSBjYWxsZWQgYWZ0ZXIgcmVmbG93aW5nIHRoZSByZXNvdXJjZSwgZm9yIGV4YW1wbGUuXG4gICAqL1xuICBmdW5jdGlvbiByZXF1ZXN0TGF5b3V0KCkge1xuICAgIGNsZWFyQ29udGFpbmVyKCk7XG4gICAgaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4gbGF5b3V0KGl0ZW0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXlvdXRzIGEgc2luZ2xlIERlY29yYXRpb24gaXRlbS5cbiAgICovXG4gIGZ1bmN0aW9uIGxheW91dChpdGVtKSB7XG4gICAgbGV0IGdyb3VwQ29udGFpbmVyID0gcmVxdWlyZUNvbnRhaW5lcigpO1xuXG4gICAgbGV0IHN0eWxlID0gc3R5bGVzLmdldChpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGlmICghc3R5bGUpIHtcbiAgICAgIGxvZ0Vycm9yKGBVbmtub3duIGRlY29yYXRpb24gc3R5bGU6ICR7aXRlbS5kZWNvcmF0aW9uLnN0eWxlfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpdGVtQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBpdGVtQ29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIGl0ZW0uaWQpO1xuICAgIGl0ZW1Db250YWluZXIuc2V0QXR0cmlidXRlKFwiZGF0YS1zdHlsZVwiLCBpdGVtLmRlY29yYXRpb24uc3R5bGUpO1xuICAgIGl0ZW1Db250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG5cbiAgICBsZXQgdmlld3BvcnRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgIGxldCBjb2x1bW5Db3VudCA9IHBhcnNlSW50KFxuICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXG4gICAgICAgIFwiY29sdW1uLWNvdW50XCJcbiAgICAgIClcbiAgICApO1xuICAgIGxldCBwYWdlV2lkdGggPSB2aWV3cG9ydFdpZHRoIC8gKGNvbHVtbkNvdW50IHx8IDEpO1xuICAgIGxldCBzY3JvbGxpbmdFbGVtZW50ID0gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudDtcbiAgICBsZXQgeE9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICBsZXQgeU9mZnNldCA9IHNjcm9sbGluZ0VsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgZnVuY3Rpb24gcG9zaXRpb25FbGVtZW50KGVsZW1lbnQsIHJlY3QsIGJvdW5kaW5nUmVjdCkge1xuICAgICAgZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblxuICAgICAgaWYgKHN0eWxlLndpZHRoID09PSBcIndyYXBcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7cmVjdC53aWR0aH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cmVjdC5oZWlnaHR9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtyZWN0LmxlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJ2aWV3cG9ydFwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHt2aWV3cG9ydFdpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGxldCBsZWZ0ID0gTWF0aC5mbG9vcihyZWN0LmxlZnQgLyB2aWV3cG9ydFdpZHRoKSAqIHZpZXdwb3J0V2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZS53aWR0aCA9PT0gXCJib3VuZHNcIikge1xuICAgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gYCR7Ym91bmRpbmdSZWN0LndpZHRofXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtyZWN0LmhlaWdodH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2JvdW5kaW5nUmVjdC5sZWZ0ICsgeE9mZnNldH1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cmVjdC50b3AgKyB5T2Zmc2V0fXB4YDtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGUud2lkdGggPT09IFwicGFnZVwiKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtwYWdlV2lkdGh9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3JlY3QuaGVpZ2h0fXB4YDtcbiAgICAgICAgbGV0IGxlZnQgPSBNYXRoLmZsb29yKHJlY3QubGVmdCAvIHBhZ2VXaWR0aCkgKiBwYWdlV2lkdGg7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnQgKyB4T2Zmc2V0fXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtyZWN0LnRvcCArIHlPZmZzZXR9cHhgO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBib3VuZGluZ1JlY3QgPSBpdGVtLnJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgbGV0IGVsZW1lbnRUZW1wbGF0ZTtcbiAgICB0cnkge1xuICAgICAgbGV0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gaXRlbS5kZWNvcmF0aW9uLmVsZW1lbnQudHJpbSgpO1xuICAgICAgZWxlbWVudFRlbXBsYXRlID0gdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGRlY29yYXRpb24gZWxlbWVudCBcIiR7aXRlbS5kZWNvcmF0aW9uLmVsZW1lbnR9XCI6ICR7ZXJyb3IubWVzc2FnZX1gXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm94ZXNcIikge1xuICAgICAgbGV0IGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHMgPSB0cnVlO1xuICAgICAgbGV0IGNsaWVudFJlY3RzID0gZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAoXG4gICAgICAgIGl0ZW0ucmFuZ2UsXG4gICAgICAgIGRvTm90TWVyZ2VIb3Jpem9udGFsbHlBbGlnbmVkUmVjdHNcbiAgICAgICk7XG5cbiAgICAgIGNsaWVudFJlY3RzID0gY2xpZW50UmVjdHMuc29ydCgocjEsIHIyKSA9PiB7XG4gICAgICAgIGlmIChyMS50b3AgPCByMi50b3ApIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH0gZWxzZSBpZiAocjEudG9wID4gcjIudG9wKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBmb3IgKGxldCBjbGllbnRSZWN0IG9mIGNsaWVudFJlY3RzKSB7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBlbGVtZW50VGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBsaW5lLnN0eWxlLnNldFByb3BlcnR5KFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICBwb3NpdGlvbkVsZW1lbnQobGluZSwgY2xpZW50UmVjdCwgYm91bmRpbmdSZWN0KTtcbiAgICAgICAgaXRlbUNvbnRhaW5lci5hcHBlbmQobGluZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzdHlsZS5sYXlvdXQgPT09IFwiYm91bmRzXCIpIHtcbiAgICAgIGNvbnN0IGJvdW5kcyA9IGVsZW1lbnRUZW1wbGF0ZS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICBib3VuZHMuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBwb3NpdGlvbkVsZW1lbnQoYm91bmRzLCBib3VuZGluZ1JlY3QsIGJvdW5kaW5nUmVjdCk7XG5cbiAgICAgIGl0ZW1Db250YWluZXIuYXBwZW5kKGJvdW5kcyk7XG4gICAgfVxuXG4gICAgZ3JvdXBDb250YWluZXIuYXBwZW5kKGl0ZW1Db250YWluZXIpO1xuICAgIGl0ZW0uY29udGFpbmVyID0gaXRlbUNvbnRhaW5lcjtcbiAgICBpdGVtLmNsaWNrYWJsZUVsZW1lbnRzID0gQXJyYXkuZnJvbShcbiAgICAgIGl0ZW1Db250YWluZXIucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWFjdGl2YWJsZT0nMSddXCIpXG4gICAgKTtcbiAgICBpZiAoaXRlbS5jbGlja2FibGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGl0ZW0uY2xpY2thYmxlRWxlbWVudHMgPSBBcnJheS5mcm9tKGl0ZW1Db250YWluZXIuY2hpbGRyZW4pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBncm91cCBjb250YWluZXIgZWxlbWVudCwgYWZ0ZXIgbWFraW5nIHN1cmUgaXQgZXhpc3RzLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVxdWlyZUNvbnRhaW5lcigpIHtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBncm91cElkKTtcbiAgICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJkYXRhLWdyb3VwXCIsIGdyb3VwTmFtZSk7XG4gICAgICBjb250YWluZXIuc3R5bGUuc2V0UHJvcGVydHkoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChjb250YWluZXIpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdyb3VwIGNvbnRhaW5lci5cbiAgICovXG4gIGZ1bmN0aW9uIGNsZWFyQ29udGFpbmVyKCkge1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGNvbnRhaW5lciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgYWRkLCByZW1vdmUsIHVwZGF0ZSwgY2xlYXIsIGl0ZW1zLCByZXF1ZXN0TGF5b3V0IH07XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcImxvYWRcIixcbiAgZnVuY3Rpb24gKCkge1xuICAgIC8vIFdpbGwgcmVsYXlvdXQgYWxsIHRoZSBkZWNvcmF0aW9ucyB3aGVuIHRoZSBkb2N1bWVudCBib2R5IGlzIHJlc2l6ZWQuXG4gICAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgdmFyIGxhc3RTaXplID0geyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBsYXN0U2l6ZS53aWR0aCA9PT0gYm9keS5jbGllbnRXaWR0aCAmJlxuICAgICAgICBsYXN0U2l6ZS5oZWlnaHQgPT09IGJvZHkuY2xpZW50SGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbGFzdFNpemUgPSB7XG4gICAgICAgIHdpZHRoOiBib2R5LmNsaWVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGJvZHkuY2xpZW50SGVpZ2h0LFxuICAgICAgfTtcblxuICAgICAgZ3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIGdyb3VwLnJlcXVlc3RMYXlvdXQoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoYm9keSk7XG4gIH0sXG4gIGZhbHNlXG4pO1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMiBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgaXNTY3JvbGxNb2RlRW5hYmxlZCB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBnZXRDc3NTZWxlY3RvciB9IGZyb20gXCJjc3Mtc2VsZWN0b3ItZ2VuZXJhdG9yXCI7XG5cbi8vIFNlZS4gaHR0cHM6Ly9naXRodWIuY29tL0pheVBhbm96L2FyY2hpdGVjdHVyZS90cmVlL3RvdWNoLWhhbmRsaW5nL21pc2MvdG91Y2gtaGFuZGxpbmdcbmV4cG9ydCBmdW5jdGlvbiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciBpbnRlcmFjdGl2ZVRhZ3MgPSBbXG4gICAgXCJhXCIsXG4gICAgXCJhdWRpb1wiLFxuICAgIFwiYnV0dG9uXCIsXG4gICAgXCJjYW52YXNcIixcbiAgICBcImRldGFpbHNcIixcbiAgICBcImlucHV0XCIsXG4gICAgXCJsYWJlbFwiLFxuICAgIFwib3B0aW9uXCIsXG4gICAgXCJzZWxlY3RcIixcbiAgICBcInN1Ym1pdFwiLFxuICAgIFwidGV4dGFyZWFcIixcbiAgICBcInZpZGVvXCIsXG4gIF07XG4gIGlmIChpbnRlcmFjdGl2ZVRhZ3MuaW5kZXhPZihlbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpICE9IC0xKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQub3V0ZXJIVE1MO1xuICB9XG5cbiAgLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgZWRpdGFibGUgYnkgdGhlIHVzZXIuXG4gIGlmIChcbiAgICBlbGVtZW50Lmhhc0F0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKSAmJlxuICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiY29udGVudGVkaXRhYmxlXCIpLnRvTG93ZXJDYXNlKCkgIT0gXCJmYWxzZVwiXG4gICkge1xuICAgIHJldHVybiBlbGVtZW50Lm91dGVySFRNTDtcbiAgfVxuXG4gIC8vIENoZWNrcyBwYXJlbnRzIHJlY3Vyc2l2ZWx5IGJlY2F1c2UgdGhlIHRvdWNoIG1pZ2h0IGJlIGZvciBleGFtcGxlIG9uIGFuIDxlbT4gaW5zaWRlIGEgPGE+LlxuICBpZiAoZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XG4gICAgcmV0dXJuIG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQoZWxlbWVudC5wYXJlbnRFbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IoKSB7XG4gIGNvbnN0IGVsZW1lbnQgPSBmaW5kRWxlbWVudChkb2N1bWVudC5ib2R5KTtcbiAgcmV0dXJuIHtcbiAgICBocmVmOiBcIiNcIixcbiAgICB0eXBlOiBcImFwcGxpY2F0aW9uL3hodG1sK3htbFwiLFxuICAgIGxvY2F0aW9uczoge1xuICAgICAgY3NzU2VsZWN0b3I6IGdldENzc1NlbGVjdG9yKGVsZW1lbnQpLFxuICAgIH0sXG4gICAgdGV4dDoge1xuICAgICAgaGlnaGxpZ2h0OiBlbGVtZW50LnRleHRDb250ZW50LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZpbmRFbGVtZW50KHJvb3RFbGVtZW50KSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcm9vdEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGlsZCA9IHJvb3RFbGVtZW50LmNoaWxkcmVuW2ldO1xuICAgIGlmICghc2hvdWxkSWdub3JlRWxlbWVudChjaGlsZCkgJiYgaXNFbGVtZW50VmlzaWJsZShjaGlsZCkpIHtcbiAgICAgIHJldHVybiBmaW5kRWxlbWVudChjaGlsZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByb290RWxlbWVudDtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50VmlzaWJsZShlbGVtZW50KSB7XG4gIGlmIChyZWFkaXVtLmlzRml4ZWRMYXlvdXQpIHJldHVybiB0cnVlO1xuXG4gIGlmIChlbGVtZW50ID09PSBkb2N1bWVudC5ib2R5IHx8IGVsZW1lbnQgPT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmICghZG9jdW1lbnQgfHwgIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCAhZG9jdW1lbnQuYm9keSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBpZiAoaXNTY3JvbGxNb2RlRW5hYmxlZCgpKSB7XG4gICAgcmV0dXJuIHJlY3QuYm90dG9tID4gMCAmJiByZWN0LnRvcCA8IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5sZWZ0IDwgd2luZG93LmlubmVyV2lkdGg7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlRWxlbWVudChlbGVtZW50KSB7XG4gIGNvbnN0IGVsU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICBpZiAoZWxTdHlsZSkge1xuICAgIGNvbnN0IGRpc3BsYXkgPSBlbFN0eWxlLmdldFByb3BlcnR5VmFsdWUoXCJkaXNwbGF5XCIpO1xuICAgIGlmIChkaXNwbGF5ICE9IFwiYmxvY2tcIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENhbm5vdCBiZSByZWxpZWQgdXBvbiwgYmVjYXVzZSB3ZWIgYnJvd3NlciBlbmdpbmUgcmVwb3J0cyBpbnZpc2libGUgd2hlbiBvdXQgb2YgdmlldyBpblxuICAgIC8vIHNjcm9sbGVkIGNvbHVtbnMhXG4gICAgLy8gY29uc3QgdmlzaWJpbGl0eSA9IGVsU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcInZpc2liaWxpdHlcIik7XG4gICAgLy8gaWYgKHZpc2liaWxpdHkgPT09IFwiaGlkZGVuXCIpIHtcbiAgICAvLyAgICAgcmV0dXJuIGZhbHNlO1xuICAgIC8vIH1cbiAgICBjb25zdCBvcGFjaXR5ID0gZWxTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwib3BhY2l0eVwiKTtcbiAgICBpZiAob3BhY2l0eSA9PT0gXCIwXCIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSB0aGUgQlNELXN0eWxlIGxpY2Vuc2VcbiAqIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbiAqL1xuXG5pbXBvcnQgeyBoYW5kbGVEZWNvcmF0aW9uQ2xpY2tFdmVudCB9IGZyb20gXCIuL2RlY29yYXRvclwiO1xuaW1wb3J0IHsgbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudCB9IGZyb20gXCIuL2RvbVwiO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgZnVuY3Rpb24gKCkge1xuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgb25DbGljaywgZmFsc2UpO1xuICBiaW5kRHJhZ0dlc3R1cmUoZG9jdW1lbnQpO1xufSk7XG5cbmZ1bmN0aW9uIG9uQ2xpY2soZXZlbnQpIHtcbiAgaWYgKCF3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuaXNDb2xsYXBzZWQpIHtcbiAgICAvLyBUaGVyZSdzIGFuIG9uLWdvaW5nIHNlbGVjdGlvbiwgdGhlIHRhcCB3aWxsIGRpc21pc3MgaXQgc28gd2UgZG9uJ3QgZm9yd2FyZCBpdC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGl4ZWxSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBsZXQgY2xpY2tFdmVudCA9IHtcbiAgICBkZWZhdWx0UHJldmVudGVkOiBldmVudC5kZWZhdWx0UHJldmVudGVkLFxuICAgIHg6IGV2ZW50LmNsaWVudFggKiBwaXhlbFJhdGlvLFxuICAgIHk6IGV2ZW50LmNsaWVudFkgKiBwaXhlbFJhdGlvLFxuICAgIHRhcmdldEVsZW1lbnQ6IGV2ZW50LnRhcmdldC5vdXRlckhUTUwsXG4gICAgaW50ZXJhY3RpdmVFbGVtZW50OiBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGV2ZW50LnRhcmdldCksXG4gIH07XG5cbiAgaWYgKGhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50KGV2ZW50LCBjbGlja0V2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFNlbmQgdGhlIHRhcCBkYXRhIG92ZXIgdGhlIEpTIGJyaWRnZSBldmVuIGlmIGl0J3MgYmVlbiBoYW5kbGVkIHdpdGhpbiB0aGUgd2ViIHZpZXcsIHNvIHRoYXRcbiAgLy8gaXQgY2FuIGJlIHByZXNlcnZlZCBhbmQgdXNlZCBieSB0aGUgdG9vbGtpdCBpZiBuZWVkZWQuXG4gIHZhciBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25UYXAoSlNPTi5zdHJpbmdpZnkoY2xpY2tFdmVudCkpO1xuXG4gIGlmIChzaG91bGRQcmV2ZW50RGVmYXVsdCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYmluZERyYWdHZXN0dXJlKGVsZW1lbnQpIHtcbiAgLy8gcGFzc2l2ZTogZmFsc2UgaXMgbmVjZXNzYXJ5IHRvIGJlIGFibGUgdG8gcHJldmVudCB0aGUgZGVmYXVsdCBiZWhhdmlvci5cbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCBvblN0YXJ0LCB7IHBhc3NpdmU6IGZhbHNlIH0pO1xuICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBvbkVuZCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIG9uTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcblxuICB2YXIgc3RhdGUgPSB1bmRlZmluZWQ7XG4gIHZhciBpc1N0YXJ0aW5nRHJhZyA9IGZhbHNlO1xuICBjb25zdCBwaXhlbFJhdGlvID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG5cbiAgZnVuY3Rpb24gb25TdGFydChldmVudCkge1xuICAgIGlzU3RhcnRpbmdEcmFnID0gdHJ1ZTtcblxuICAgIGNvbnN0IHN0YXJ0WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAqIHBpeGVsUmF0aW87XG4gICAgY29uc3Qgc3RhcnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZICogcGl4ZWxSYXRpbztcbiAgICBzdGF0ZSA9IHtcbiAgICAgIGRlZmF1bHRQcmV2ZW50ZWQ6IGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQsXG4gICAgICBzdGFydFg6IHN0YXJ0WCxcbiAgICAgIHN0YXJ0WTogc3RhcnRZLFxuICAgICAgY3VycmVudFg6IHN0YXJ0WCxcbiAgICAgIGN1cnJlbnRZOiBzdGFydFksXG4gICAgICBvZmZzZXRYOiAwLFxuICAgICAgb2Zmc2V0WTogMCxcbiAgICAgIGludGVyYWN0aXZlRWxlbWVudDogbmVhcmVzdEludGVyYWN0aXZlRWxlbWVudChldmVudC50YXJnZXQpLFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBvbk1vdmUoZXZlbnQpIHtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG5cbiAgICBzdGF0ZS5jdXJyZW50WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAqIHBpeGVsUmF0aW87XG4gICAgc3RhdGUuY3VycmVudFkgPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgKiBwaXhlbFJhdGlvO1xuICAgIHN0YXRlLm9mZnNldFggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLnN0YXJ0WDtcbiAgICBzdGF0ZS5vZmZzZXRZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5zdGFydFk7XG5cbiAgICB2YXIgc2hvdWxkUHJldmVudERlZmF1bHQgPSBmYWxzZTtcbiAgICAvLyBXYWl0IGZvciBhIG1vdmVtZW50IG9mIGF0IGxlYXN0IDYgcGl4ZWxzIGJlZm9yZSByZXBvcnRpbmcgYSBkcmFnLlxuICAgIGlmIChpc1N0YXJ0aW5nRHJhZykge1xuICAgICAgaWYgKE1hdGguYWJzKHN0YXRlLm9mZnNldFgpID49IDYgfHwgTWF0aC5hYnMoc3RhdGUub2Zmc2V0WSkgPj0gNikge1xuICAgICAgICBpc1N0YXJ0aW5nRHJhZyA9IGZhbHNlO1xuICAgICAgICBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IEFuZHJvaWQub25EcmFnU3RhcnQoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkUHJldmVudERlZmF1bHQgPSBBbmRyb2lkLm9uRHJhZ01vdmUoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbkVuZChldmVudCkge1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcblxuICAgIGNvbnN0IHNob3VsZFByZXZlbnREZWZhdWx0ID0gQW5kcm9pZC5vbkRyYWdFbmQoSlNPTi5zdHJpbmdpZnkoc3RhdGUpKTtcbiAgICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgc3RhdGUgPSB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjMgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbmltcG9ydCB7IG5lYXJlc3RJbnRlcmFjdGl2ZUVsZW1lbnQgfSBmcm9tIFwiLi9kb21cIjtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChldmVudCkgPT4ge1xuICBpZiAoc2hvdWxkSWdub3JlRXZlbnQoZXZlbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJldmVudERlZmF1bHQoZXZlbnQpO1xuICBzZW5kUHJlc3NLZXlNZXNzYWdlKGV2ZW50LCBcImRvd25cIik7XG59KTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXl1cFwiLCAoZXZlbnQpID0+IHtcbiAgaWYgKHNob3VsZElnbm9yZUV2ZW50KGV2ZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcbiAgc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgXCJ1cFwiKTtcbn0pO1xuXG5mdW5jdGlvbiBzaG91bGRJZ25vcmVFdmVudChldmVudCkge1xuICByZXR1cm4gKFxuICAgIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHxcbiAgICBuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50KGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpICE9IG51bGxcbiAgKTtcbn1cblxuLy8gV2UgcHJldmVudCB0aGUgZGVmYXVsdCBiZWhhdmlvciBmb3Iga2V5Ym9hcmQgZXZlbnRzLCBvdGhlcndpc2UgdGhlIHdlYiB2aWV3XG4vLyBtaWdodCBzY3JvbGwuXG5mdW5jdGlvbiBwcmV2ZW50RGVmYXVsdChldmVudCkge1xuICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbn1cblxuZnVuY3Rpb24gc2VuZFByZXNzS2V5TWVzc2FnZShldmVudCwgdHlwZSkge1xuICBpZiAoZXZlbnQucmVwZWF0KSByZXR1cm47XG5cbiAgbGV0IGtleUV2ZW50ID0ge1xuICAgIHR5cGU6IHR5cGUsXG4gICAgY29kZTogZXZlbnQuY29kZSxcbiAgICBjaGFyYWN0ZXJzOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LmtleUNvZGUpLFxuICAgIGFsdDogZXZlbnQuYWx0S2V5LFxuICAgIGNvbnRyb2w6IGV2ZW50LmN0cmxLZXksXG4gICAgc2hpZnQ6IGV2ZW50LnNoaWZ0S2V5LFxuICAgIG1ldGE6IGV2ZW50Lm1ldGFLZXksXG4gIH07XG5cbiAgQW5kcm9pZC5vbktleShKU09OLnN0cmluZ2lmeShrZXlFdmVudCkpO1xufVxuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuaW1wb3J0IHsgbG9nIGFzIGxvZ05hdGl2ZSwgbG9nRXJyb3IsIHNuYXBDdXJyZW50T2Zmc2V0IH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IHRvTmF0aXZlUmVjdCB9IGZyb20gXCIuL3JlY3RcIjtcbmltcG9ydCB7IFRleHRSYW5nZSB9IGZyb20gXCIuL3ZlbmRvci9oeXBvdGhlc2lzL2FuY2hvcmluZy90ZXh0LXJhbmdlXCI7XG5cbi8vIFBvbHlmaWxsIGZvciBBbmRyb2lkIEFQSSAyNlxuaW1wb3J0IG1hdGNoQWxsIGZyb20gXCJzdHJpbmcucHJvdG90eXBlLm1hdGNoYWxsXCI7XG5tYXRjaEFsbC5zaGltKCk7XG5cbmNvbnN0IGRlYnVnID0gdHJ1ZTtcblxuLy8gTm90aWZ5IG5hdGl2ZSBjb2RlIHRoYXQgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwibG9hZFwiLFxuICBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGlzU2VsZWN0aW5nID0gZmFsc2U7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2xsYXBzZWQgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuaXNDb2xsYXBzZWQ7XG5cbiAgICAgIGlmIChjb2xsYXBzZWQgJiYgaXNTZWxlY3RpbmcpIHtcbiAgICAgICAgaXNTZWxlY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgQW5kcm9pZC5vblNlbGVjdGlvbkVuZCgpO1xuICAgICAgICAvLyBTbmFwcyB0aGUgY3VycmVudCBjb2x1bW4gaW4gY2FzZSB0aGUgdXNlciBzaGlmdGVkIHRoZSBzY3JvbGwgYnkgZHJhZ2dpbmcgdGhlIHRleHQgc2VsZWN0aW9uLlxuICAgICAgICBzbmFwQ3VycmVudE9mZnNldCgpO1xuICAgICAgfSBlbHNlIGlmICghY29sbGFwc2VkICYmICFpc1NlbGVjdGluZykge1xuICAgICAgICBpc1NlbGVjdGluZyA9IHRydWU7XG4gICAgICAgIEFuZHJvaWQub25TZWxlY3Rpb25TdGFydCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICBmYWxzZVxuKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRTZWxlY3Rpb24oKSB7XG4gIGNvbnN0IHRleHQgPSBnZXRDdXJyZW50U2VsZWN0aW9uVGV4dCgpO1xuICBpZiAoIXRleHQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCByZWN0ID0gZ2V0U2VsZWN0aW9uUmVjdCgpO1xuICByZXR1cm4geyB0ZXh0LCByZWN0IH07XG59XG5cbmZ1bmN0aW9uIGdldFNlbGVjdGlvblJlY3QoKSB7XG4gIHRyeSB7XG4gICAgbGV0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmFuZ2UgPSBzZWwuZ2V0UmFuZ2VBdCgwKTtcblxuICAgIHJldHVybiB0b05hdGl2ZVJlY3QocmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nRXJyb3IoZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudFNlbGVjdGlvblRleHQoKSB7XG4gIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGhpZ2hsaWdodCA9IHNlbGVjdGlvbi50b1N0cmluZygpO1xuICBjb25zdCBjbGVhbkhpZ2hsaWdodCA9IGhpZ2hsaWdodFxuICAgIC50cmltKClcbiAgICAucmVwbGFjZSgvXFxuL2csIFwiIFwiKVxuICAgIC5yZXBsYWNlKC9cXHNcXHMrL2csIFwiIFwiKTtcbiAgaWYgKGNsZWFuSGlnaGxpZ2h0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFzZWxlY3Rpb24uYW5jaG9yTm9kZSB8fCAhc2VsZWN0aW9uLmZvY3VzTm9kZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcmFuZ2UgPVxuICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxXG4gICAgICA/IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApXG4gICAgICA6IGNyZWF0ZU9yZGVyZWRSYW5nZShcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgICAgIHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICAgICAgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0XG4gICAgICAgICk7XG4gIGlmICghcmFuZ2UgfHwgcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgbG9nKFwiJCQkJCQkJCQkJCQkJCQkJCQgQ0FOTk9UIEdFVCBOT04tQ09MTEFQU0VEIFNFTEVDVElPTiBSQU5HRT8hXCIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCB0ZXh0ID0gZG9jdW1lbnQuYm9keS50ZXh0Q29udGVudDtcbiAgY29uc3QgdGV4dFJhbmdlID0gVGV4dFJhbmdlLmZyb21SYW5nZShyYW5nZSkucmVsYXRpdmVUbyhkb2N1bWVudC5ib2R5KTtcbiAgY29uc3Qgc3RhcnQgPSB0ZXh0UmFuZ2Uuc3RhcnQub2Zmc2V0O1xuICBjb25zdCBlbmQgPSB0ZXh0UmFuZ2UuZW5kLm9mZnNldDtcblxuICBjb25zdCBzbmlwcGV0TGVuZ3RoID0gMjAwO1xuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYmVmb3JlIHRoZSBoaWdobGlnaHQsIGlnbm9yaW5nIHRoZSBmaXJzdCBcIndvcmRcIiwgd2hpY2ggbWlnaHQgYmUgY3V0LlxuICBsZXQgYmVmb3JlID0gdGV4dC5zbGljZShNYXRoLm1heCgwLCBzdGFydCAtIHNuaXBwZXRMZW5ndGgpLCBzdGFydCk7XG4gIGxldCBmaXJzdFdvcmRTdGFydCA9IGJlZm9yZS5zZWFyY2goL1xcUHtMfVxccHtMfS9ndSk7XG4gIGlmIChmaXJzdFdvcmRTdGFydCAhPT0gLTEpIHtcbiAgICBiZWZvcmUgPSBiZWZvcmUuc2xpY2UoZmlyc3RXb3JkU3RhcnQgKyAxKTtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIHRleHQgYWZ0ZXIgdGhlIGhpZ2hsaWdodCwgaWdub3JpbmcgdGhlIGxhc3QgXCJ3b3JkXCIsIHdoaWNoIG1pZ2h0IGJlIGN1dC5cbiAgbGV0IGFmdGVyID0gdGV4dC5zbGljZShlbmQsIE1hdGgubWluKHRleHQubGVuZ3RoLCBlbmQgKyBzbmlwcGV0TGVuZ3RoKSk7XG4gIGxldCBsYXN0V29yZEVuZCA9IEFycmF5LmZyb20oYWZ0ZXIubWF0Y2hBbGwoL1xccHtMfVxcUHtMfS9ndSkpLnBvcCgpO1xuICBpZiAobGFzdFdvcmRFbmQgIT09IHVuZGVmaW5lZCAmJiBsYXN0V29yZEVuZC5pbmRleCA+IDEpIHtcbiAgICBhZnRlciA9IGFmdGVyLnNsaWNlKDAsIGxhc3RXb3JkRW5kLmluZGV4ICsgMSk7XG4gIH1cblxuICByZXR1cm4geyBoaWdobGlnaHQsIGJlZm9yZSwgYWZ0ZXIgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT3JkZXJlZFJhbmdlKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQsIGVuZE5vZGUsIGVuZE9mZnNldCkge1xuICBjb25zdCByYW5nZSA9IG5ldyBSYW5nZSgpO1xuICByYW5nZS5zZXRTdGFydChzdGFydE5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUsIGVuZE9mZnNldCk7XG4gIGlmICghcmFuZ2UuY29sbGFwc2VkKSB7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG4gIGxvZyhcIj4+PiBjcmVhdGVPcmRlcmVkUmFuZ2UgQ09MTEFQU0VEIC4uLiBSQU5HRSBSRVZFUlNFP1wiKTtcbiAgY29uc3QgcmFuZ2VSZXZlcnNlID0gbmV3IFJhbmdlKCk7XG4gIHJhbmdlUmV2ZXJzZS5zZXRTdGFydChlbmROb2RlLCBlbmRPZmZzZXQpO1xuICByYW5nZVJldmVyc2Uuc2V0RW5kKHN0YXJ0Tm9kZSwgc3RhcnRPZmZzZXQpO1xuICBpZiAoIXJhbmdlUmV2ZXJzZS5jb2xsYXBzZWQpIHtcbiAgICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgT0suXCIpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxuICBsb2coXCI+Pj4gY3JlYXRlT3JkZXJlZFJhbmdlIFJBTkdFIFJFVkVSU0UgQUxTTyBDT0xMQVBTRUQ/IVwiKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRSYW5nZUluZm8oZG9jdW1lbnQsIHJhbmdlSW5mbykge1xuICBjb25zdCBzdGFydEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIXN0YXJ0RWxlbWVudCkge1xuICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIE5PIFNUQVJUIEVMRU1FTlQgQ1NTIFNFTEVDVE9SPyFcIik7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgc3RhcnRDb250YWluZXIgPSBzdGFydEVsZW1lbnQ7XG4gIGlmIChyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXggPj0gMCkge1xuICAgIGlmIChcbiAgICAgIHJhbmdlSW5mby5zdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PVxuICAgICAgc3RhcnRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLnN0YXJ0Q29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4ID49IHN0YXJ0RWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aD8hXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBzdGFydENvbnRhaW5lciA9XG4gICAgICBzdGFydEVsZW1lbnQuY2hpbGROb2Rlc1tyYW5nZUluZm8uc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXhdO1xuICAgIGlmIChzdGFydENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIHN0YXJ0Q29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERT8hXCIpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgY29uc3QgZW5kRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckVsZW1lbnRDc3NTZWxlY3RvclxuICApO1xuICBpZiAoIWVuZEVsZW1lbnQpIHtcbiAgICBsb2coXCJeXl4gY29udmVydFJhbmdlSW5mbyBOTyBFTkQgRUxFTUVOVCBDU1MgU0VMRUNUT1I/IVwiKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBlbmRDb250YWluZXIgPSBlbmRFbGVtZW50O1xuICBpZiAocmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSAwKSB7XG4gICAgaWYgKFxuICAgICAgcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoXG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIFwiXl5eIGNvbnZlcnRSYW5nZUluZm8gcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCA+PSBlbmRFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoPyFcIlxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVuZENvbnRhaW5lciA9XG4gICAgICBlbmRFbGVtZW50LmNoaWxkTm9kZXNbcmFuZ2VJbmZvLmVuZENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleF07XG4gICAgaWYgKGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGxvZyhcIl5eXiBjb252ZXJ0UmFuZ2VJbmZvIGVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREU/IVwiKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBjcmVhdGVPcmRlcmVkUmFuZ2UoXG4gICAgc3RhcnRDb250YWluZXIsXG4gICAgcmFuZ2VJbmZvLnN0YXJ0T2Zmc2V0LFxuICAgIGVuZENvbnRhaW5lcixcbiAgICByYW5nZUluZm8uZW5kT2Zmc2V0XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2NhdGlvbjJSYW5nZUluZm8obG9jYXRpb24pIHtcbiAgY29uc3QgbG9jYXRpb25zID0gbG9jYXRpb24ubG9jYXRpb25zO1xuICBjb25zdCBkb21SYW5nZSA9IGxvY2F0aW9ucy5kb21SYW5nZTtcbiAgY29uc3Qgc3RhcnQgPSBkb21SYW5nZS5zdGFydDtcbiAgY29uc3QgZW5kID0gZG9tUmFuZ2UuZW5kO1xuXG4gIHJldHVybiB7XG4gICAgZW5kQ29udGFpbmVyQ2hpbGRUZXh0Tm9kZUluZGV4OiBlbmQudGV4dE5vZGVJbmRleCxcbiAgICBlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IGVuZC5jc3NTZWxlY3RvcixcbiAgICBlbmRPZmZzZXQ6IGVuZC5vZmZzZXQsXG4gICAgc3RhcnRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXg6IHN0YXJ0LnRleHROb2RlSW5kZXgsXG4gICAgc3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3I6IHN0YXJ0LmNzc1NlbGVjdG9yLFxuICAgIHN0YXJ0T2Zmc2V0OiBzdGFydC5vZmZzZXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgaWYgKGRlYnVnKSB7XG4gICAgbG9nTmF0aXZlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbiIsIi8vXG4vLyAgQ29weXJpZ2h0IDIwMjEgUmVhZGl1bSBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IHRoZSBCU0Qtc3R5bGUgbGljZW5zZVxuLy8gIGF2YWlsYWJsZSBpbiB0aGUgdG9wLWxldmVsIExJQ0VOU0UgZmlsZSBvZiB0aGUgcHJvamVjdC5cbi8vXG5cbi8vIEJhc2Ugc2NyaXB0IHVzZWQgYnkgYm90aCByZWZsb3dhYmxlIGFuZCBmaXhlZCBsYXlvdXQgcmVzb3VyY2VzLlxuXG5pbXBvcnQgXCIuL2dlc3R1cmVzXCI7XG5pbXBvcnQgXCIuL2tleWJvYXJkXCI7XG5pbXBvcnQge1xuICByZW1vdmVQcm9wZXJ0eSxcbiAgc2Nyb2xsTGVmdCxcbiAgc2Nyb2xsUmlnaHQsXG4gIHNjcm9sbFRvRW5kLFxuICBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1Bvc2l0aW9uLFxuICBzY3JvbGxUb1N0YXJ0LFxuICBzY3JvbGxUb1RleHQsXG4gIHNldFByb3BlcnR5LFxuICBzZXRDU1NQcm9wZXJ0aWVzLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IgfSBmcm9tIFwiLi9kb21cIjtcbmltcG9ydCB7IGdldEN1cnJlbnRTZWxlY3Rpb24gfSBmcm9tIFwiLi9zZWxlY3Rpb25cIjtcbmltcG9ydCB7IGdldERlY29yYXRpb25zLCByZWdpc3RlclRlbXBsYXRlcyB9IGZyb20gXCIuL2RlY29yYXRvclwiO1xuXG4vLyBQdWJsaWMgQVBJIHVzZWQgYnkgdGhlIG5hdmlnYXRvci5cbndpbmRvdy5yZWFkaXVtID0ge1xuICAvLyB1dGlsc1xuICBzY3JvbGxUb0lkOiBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1Bvc2l0aW9uOiBzY3JvbGxUb1Bvc2l0aW9uLFxuICBzY3JvbGxUb1RleHQ6IHNjcm9sbFRvVGV4dCxcbiAgc2Nyb2xsTGVmdDogc2Nyb2xsTGVmdCxcbiAgc2Nyb2xsUmlnaHQ6IHNjcm9sbFJpZ2h0LFxuICBzY3JvbGxUb1N0YXJ0OiBzY3JvbGxUb1N0YXJ0LFxuICBzY3JvbGxUb0VuZDogc2Nyb2xsVG9FbmQsXG4gIHNldENTU1Byb3BlcnRpZXM6IHNldENTU1Byb3BlcnRpZXMsXG4gIHNldFByb3BlcnR5OiBzZXRQcm9wZXJ0eSxcbiAgcmVtb3ZlUHJvcGVydHk6IHJlbW92ZVByb3BlcnR5LFxuXG4gIC8vIHNlbGVjdGlvblxuICBnZXRDdXJyZW50U2VsZWN0aW9uOiBnZXRDdXJyZW50U2VsZWN0aW9uLFxuXG4gIC8vIGRlY29yYXRpb25cbiAgcmVnaXN0ZXJEZWNvcmF0aW9uVGVtcGxhdGVzOiByZWdpc3RlclRlbXBsYXRlcyxcbiAgZ2V0RGVjb3JhdGlvbnM6IGdldERlY29yYXRpb25zLFxuXG4gIC8vIERPTVxuICBmaW5kRmlyc3RWaXNpYmxlTG9jYXRvcjogZmluZEZpcnN0VmlzaWJsZUxvY2F0b3IsXG59O1xuIiwiLy9cbi8vICBDb3B5cmlnaHQgMjAyMSBSZWFkaXVtIEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgdGhlIEJTRC1zdHlsZSBsaWNlbnNlXG4vLyAgYXZhaWxhYmxlIGluIHRoZSB0b3AtbGV2ZWwgTElDRU5TRSBmaWxlIG9mIHRoZSBwcm9qZWN0LlxuLy9cblxuLy8gU2NyaXB0IHVzZWQgZm9yIHJlZmxvd2FibGUgcmVzb3VyY2VzLlxuXG5pbXBvcnQgXCIuL2luZGV4XCI7XG5cbndpbmRvdy5yZWFkaXVtLmlzUmVmbG93YWJsZSA9IHRydWU7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbiAgLy8gU2V0dXBzIHRoZSBgdmlld3BvcnRgIG1ldGEgdGFnIHRvIGRpc2FibGUgem9vbWluZy5cbiAgbGV0IG1ldGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibWV0YVwiKTtcbiAgbWV0YS5zZXRBdHRyaWJ1dGUoXCJuYW1lXCIsIFwidmlld3BvcnRcIik7XG4gIG1ldGEuc2V0QXR0cmlidXRlKFxuICAgIFwiY29udGVudFwiLFxuICAgIFwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWF4aW11bS1zY2FsZT0xLjAsIHVzZXItc2NhbGFibGU9bm8sIHNocmluay10by1maXQ9bm9cIlxuICApO1xuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGEpO1xufSk7XG4iXSwibmFtZXMiOlsiYXBwcm94U2VhcmNoIiwic2VhcmNoIiwidGV4dCIsInN0ciIsIm1heEVycm9ycyIsIm1hdGNoUG9zIiwiZXhhY3RNYXRjaGVzIiwiaW5kZXhPZiIsInB1c2giLCJzdGFydCIsImVuZCIsImxlbmd0aCIsImVycm9ycyIsInRleHRNYXRjaFNjb3JlIiwibWF0Y2hlcyIsIm1hdGNoUXVvdGUiLCJxdW90ZSIsImNvbnRleHQiLCJNYXRoIiwibWluIiwic2NvcmVNYXRjaCIsIm1hdGNoIiwicXVvdGVXZWlnaHQiLCJwcmVmaXhXZWlnaHQiLCJzdWZmaXhXZWlnaHQiLCJwb3NXZWlnaHQiLCJxdW90ZVNjb3JlIiwicHJlZml4U2NvcmUiLCJwcmVmaXgiLCJzbGljZSIsIm1heCIsInN1ZmZpeFNjb3JlIiwic3VmZml4IiwicG9zU2NvcmUiLCJoaW50Iiwib2Zmc2V0IiwiYWJzIiwicmF3U2NvcmUiLCJtYXhTY29yZSIsIm5vcm1hbGl6ZWRTY29yZSIsInNjb3JlZE1hdGNoZXMiLCJtYXAiLCJtIiwic2NvcmUiLCJzb3J0IiwiYSIsImIiLCJub2RlVGV4dExlbmd0aCIsIm5vZGUiLCJub2RlVHlwZSIsIk5vZGUiLCJFTEVNRU5UX05PREUiLCJURVhUX05PREUiLCJ0ZXh0Q29udGVudCIsInByZXZpb3VzU2libGluZ3NUZXh0TGVuZ3RoIiwic2libGluZyIsInByZXZpb3VzU2libGluZyIsInJlc29sdmVPZmZzZXRzIiwiZWxlbWVudCIsIm9mZnNldHMiLCJuZXh0T2Zmc2V0Iiwic2hpZnQiLCJub2RlSXRlciIsIm93bmVyRG9jdW1lbnQiLCJjcmVhdGVOb2RlSXRlcmF0b3IiLCJOb2RlRmlsdGVyIiwiU0hPV19URVhUIiwicmVzdWx0cyIsImN1cnJlbnROb2RlIiwibmV4dE5vZGUiLCJ0ZXh0Tm9kZSIsInVuZGVmaW5lZCIsImRhdGEiLCJSYW5nZUVycm9yIiwiUkVTT0xWRV9GT1JXQVJEUyIsIlJFU09MVkVfQkFDS1dBUkRTIiwiVGV4dFBvc2l0aW9uIiwiRXJyb3IiLCJwYXJlbnQiLCJjb250YWlucyIsImVsIiwicGFyZW50RWxlbWVudCIsIm9wdGlvbnMiLCJlcnIiLCJkaXJlY3Rpb24iLCJ0dyIsImRvY3VtZW50IiwiY3JlYXRlVHJlZVdhbGtlciIsImdldFJvb3ROb2RlIiwiZm9yd2FyZHMiLCJwcmV2aW91c05vZGUiLCJmcm9tUG9pbnQiLCJ0ZXh0T2Zmc2V0IiwiY2hpbGROb2RlcyIsImkiLCJUZXh0UmFuZ2UiLCJyZWxhdGl2ZVRvIiwicmVzb2x2ZSIsInJhbmdlIiwiUmFuZ2UiLCJzZXRTdGFydCIsInNldEVuZCIsInN0YXJ0Q29udGFpbmVyIiwic3RhcnRPZmZzZXQiLCJlbmRDb250YWluZXIiLCJlbmRPZmZzZXQiLCJyb290Iiwibm9kZUZyb21YUGF0aCIsInhwYXRoRnJvbU5vZGUiLCJSYW5nZUFuY2hvciIsIm5vcm1hbGl6ZWRSYW5nZSIsImZyb21SYW5nZSIsInRvUmFuZ2UiLCJ0ZXh0UmFuZ2UiLCJ0eXBlIiwic2VsZWN0b3IiLCJzdGFydFBvcyIsImZyb21DaGFyT2Zmc2V0IiwiZW5kUG9zIiwiVGV4dFBvc2l0aW9uQW5jaG9yIiwiZnJvbU9mZnNldHMiLCJUZXh0UXVvdGVBbmNob3IiLCJleGFjdCIsInRvUG9zaXRpb25BbmNob3IiLCJjb250ZXh0TGVuIiwid2luZG93IiwiYWRkRXZlbnRMaXN0ZW5lciIsImV2ZW50IiwiQW5kcm9pZCIsImxvZ0Vycm9yIiwibWVzc2FnZSIsImZpbGVuYW1lIiwibGluZW5vIiwib2JzZXJ2ZXIiLCJSZXNpemVPYnNlcnZlciIsIm9uVmlld3BvcnRXaWR0aENoYW5nZWQiLCJzbmFwQ3VycmVudE9mZnNldCIsIm9ic2VydmUiLCJib2R5IiwiYXBwZW5kVmlydHVhbENvbHVtbklmTmVlZGVkIiwiaWQiLCJ2aXJ0dWFsQ29sIiwiZ2V0RWxlbWVudEJ5SWQiLCJpc1Njcm9sbE1vZGVFbmFibGVkIiwiZ2V0Q29sdW1uQ291bnRQZXJTY3JlZW4iLCJyZW1vdmUiLCJkb2N1bWVudFdpZHRoIiwic2Nyb2xsaW5nRWxlbWVudCIsInNjcm9sbFdpZHRoIiwiY29sQ291bnQiLCJwYWdlV2lkdGgiLCJoYXNPZGRDb2xDb3VudCIsInJvdW5kIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsInN0eWxlIiwiYnJlYWtCZWZvcmUiLCJpbm5lckhUTUwiLCJhcHBlbmRDaGlsZCIsIndpZHRoIiwiZ2V0Vmlld3BvcnRXaWR0aCIsImRldmljZVBpeGVsUmF0aW8iLCJzZXRQcm9wZXJ0eSIsInBhcnNlSW50IiwiZ2V0Q29tcHV0ZWRTdHlsZSIsImRvY3VtZW50RWxlbWVudCIsImdldFByb3BlcnR5VmFsdWUiLCJ0cmltIiwiaXNSVEwiLCJkaXIiLCJ0b0xvd2VyQ2FzZSIsInNjcm9sbFRvSWQiLCJzY3JvbGxUb1JlY3QiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJzY3JvbGxUb1Bvc2l0aW9uIiwicG9zaXRpb24iLCJzY3JvbGxIZWlnaHQiLCJzY3JvbGxUb3AiLCJmYWN0b3IiLCJzY3JvbGxMZWZ0Iiwic25hcE9mZnNldCIsInNjcm9sbFRvVGV4dCIsInJhbmdlRnJvbUxvY2F0b3IiLCJzY3JvbGxUb1JhbmdlIiwicmVjdCIsInRvcCIsInNjcm9sbFkiLCJpbm5lckhlaWdodCIsImxlZnQiLCJzY3JvbGxYIiwic2Nyb2xsVG9TdGFydCIsInNjcm9sbFRvIiwic2Nyb2xsVG9FbmQiLCJtaW5PZmZzZXQiLCJzY3JvbGxUb09mZnNldCIsInNjcm9sbFJpZ2h0IiwibWF4T2Zmc2V0IiwiY3VycmVudE9mZnNldCIsImRpZmYiLCJ2YWx1ZSIsImRlbHRhIiwibG9jYXRvciIsImxvY2F0aW9ucyIsImhpZ2hsaWdodCIsImNzc1NlbGVjdG9yIiwicXVlcnlTZWxlY3RvciIsImFuY2hvciIsImJlZm9yZSIsImFmdGVyIiwiZnJhZ21lbnRzIiwiaHRtbElkIiwiY3JlYXRlUmFuZ2UiLCJzZXRTdGFydEJlZm9yZSIsInNldEVuZEFmdGVyIiwiZSIsInNldENTU1Byb3BlcnRpZXMiLCJwcm9wZXJ0aWVzIiwibmFtZSIsImtleSIsInJlbW92ZVByb3BlcnR5IiwibG9nIiwiQXJyYXkiLCJwcm90b3R5cGUiLCJjYWxsIiwiYXJndW1lbnRzIiwiam9pbiIsImxvZ05hdGl2ZSIsImRlYnVnIiwidG9OYXRpdmVSZWN0IiwicGl4ZWxSYXRpbyIsImhlaWdodCIsInJpZ2h0IiwiYm90dG9tIiwiZ2V0Q2xpZW50UmVjdHNOb092ZXJsYXAiLCJkb05vdE1lcmdlSG9yaXpvbnRhbGx5QWxpZ25lZFJlY3RzIiwiY2xpZW50UmVjdHMiLCJnZXRDbGllbnRSZWN0cyIsInRvbGVyYW5jZSIsIm9yaWdpbmFsUmVjdHMiLCJyYW5nZUNsaWVudFJlY3QiLCJtZXJnZWRSZWN0cyIsIm1lcmdlVG91Y2hpbmdSZWN0cyIsIm5vQ29udGFpbmVkUmVjdHMiLCJyZW1vdmVDb250YWluZWRSZWN0cyIsIm5ld1JlY3RzIiwicmVwbGFjZU92ZXJsYXBpbmdSZWN0cyIsIm1pbkFyZWEiLCJqIiwiYmlnRW5vdWdoIiwic3BsaWNlIiwicmVjdHMiLCJyZWN0MSIsInJlY3QyIiwicmVjdHNMaW5lVXBWZXJ0aWNhbGx5IiwiYWxtb3N0RXF1YWwiLCJyZWN0c0xpbmVVcEhvcml6b250YWxseSIsImhvcml6b250YWxBbGxvd2VkIiwiYWxpZ25lZCIsImNhbk1lcmdlIiwicmVjdHNUb3VjaE9yT3ZlcmxhcCIsImZpbHRlciIsInJlcGxhY2VtZW50Q2xpZW50UmVjdCIsImdldEJvdW5kaW5nUmVjdCIsInJlY3RzVG9LZWVwIiwiU2V0IiwiZGVsZXRlIiwicG9zc2libHlDb250YWluaW5nUmVjdCIsImhhcyIsInJlY3RDb250YWlucyIsImZyb20iLCJyZWN0Q29udGFpbnNQb2ludCIsIngiLCJ5IiwidG9BZGQiLCJ0b1JlbW92ZSIsInN1YnRyYWN0UmVjdHMxIiwicmVjdFN1YnRyYWN0Iiwic3VidHJhY3RSZWN0czIiLCJhcHBseSIsInJlY3RJbnRlcnNlY3RlZCIsInJlY3RJbnRlcnNlY3QiLCJyZWN0QSIsInJlY3RCIiwicmVjdEMiLCJyZWN0RCIsIm1heExlZnQiLCJtaW5SaWdodCIsIm1heFRvcCIsIm1pbkJvdHRvbSIsInN0eWxlcyIsIk1hcCIsImdyb3VwcyIsImxhc3RHcm91cElkIiwicmVnaXN0ZXJUZW1wbGF0ZXMiLCJuZXdTdHlsZXMiLCJzdHlsZXNoZWV0IiwiT2JqZWN0IiwiZW50cmllcyIsInNldCIsInN0eWxlRWxlbWVudCIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwiZ2V0RGVjb3JhdGlvbnMiLCJncm91cE5hbWUiLCJncm91cCIsImdldCIsIkRlY29yYXRpb25Hcm91cCIsImhhbmRsZURlY29yYXRpb25DbGlja0V2ZW50IiwiY2xpY2tFdmVudCIsInNpemUiLCJmaW5kVGFyZ2V0IiwiZ3JvdXBDb250ZW50IiwiaXRlbXMiLCJyZXZlcnNlIiwiaXRlbSIsImNsaWNrYWJsZUVsZW1lbnRzIiwidG9KU09OIiwiY2xpZW50WCIsImNsaWVudFkiLCJ0YXJnZXQiLCJvbkRlY29yYXRpb25BY3RpdmF0ZWQiLCJKU09OIiwic3RyaW5naWZ5IiwiZGVjb3JhdGlvbiIsImNsaWNrIiwiZ3JvdXBJZCIsImxhc3RJdGVtSWQiLCJjb250YWluZXIiLCJhZGQiLCJsYXlvdXQiLCJkZWNvcmF0aW9uSWQiLCJpbmRleCIsImZpbmRJbmRleCIsInVwZGF0ZSIsImNsZWFyIiwiY2xlYXJDb250YWluZXIiLCJyZXF1ZXN0TGF5b3V0IiwiZm9yRWFjaCIsImdyb3VwQ29udGFpbmVyIiwicmVxdWlyZUNvbnRhaW5lciIsIml0ZW1Db250YWluZXIiLCJ2aWV3cG9ydFdpZHRoIiwiaW5uZXJXaWR0aCIsImNvbHVtbkNvdW50IiwieE9mZnNldCIsInlPZmZzZXQiLCJwb3NpdGlvbkVsZW1lbnQiLCJib3VuZGluZ1JlY3QiLCJmbG9vciIsImVsZW1lbnRUZW1wbGF0ZSIsInRlbXBsYXRlIiwiY29udGVudCIsImZpcnN0RWxlbWVudENoaWxkIiwiZXJyb3IiLCJyMSIsInIyIiwiY2xpZW50UmVjdCIsImxpbmUiLCJjbG9uZU5vZGUiLCJhcHBlbmQiLCJib3VuZHMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiY2hpbGRyZW4iLCJsYXN0U2l6ZSIsImNsaWVudFdpZHRoIiwiY2xpZW50SGVpZ2h0IiwiZ2V0Q3NzU2VsZWN0b3IiLCJuZWFyZXN0SW50ZXJhY3RpdmVFbGVtZW50IiwiaW50ZXJhY3RpdmVUYWdzIiwibm9kZU5hbWUiLCJvdXRlckhUTUwiLCJoYXNBdHRyaWJ1dGUiLCJnZXRBdHRyaWJ1dGUiLCJmaW5kRmlyc3RWaXNpYmxlTG9jYXRvciIsImZpbmRFbGVtZW50IiwiaHJlZiIsInJvb3RFbGVtZW50IiwiY2hpbGQiLCJzaG91bGRJZ25vcmVFbGVtZW50IiwiaXNFbGVtZW50VmlzaWJsZSIsInJlYWRpdW0iLCJpc0ZpeGVkTGF5b3V0IiwiZWxTdHlsZSIsImRpc3BsYXkiLCJvcGFjaXR5Iiwib25DbGljayIsImJpbmREcmFnR2VzdHVyZSIsImdldFNlbGVjdGlvbiIsImlzQ29sbGFwc2VkIiwiZGVmYXVsdFByZXZlbnRlZCIsInRhcmdldEVsZW1lbnQiLCJpbnRlcmFjdGl2ZUVsZW1lbnQiLCJzaG91bGRQcmV2ZW50RGVmYXVsdCIsIm9uVGFwIiwic3RvcFByb3BhZ2F0aW9uIiwicHJldmVudERlZmF1bHQiLCJvblN0YXJ0IiwicGFzc2l2ZSIsIm9uRW5kIiwib25Nb3ZlIiwic3RhdGUiLCJpc1N0YXJ0aW5nRHJhZyIsInN0YXJ0WCIsInRvdWNoZXMiLCJzdGFydFkiLCJjdXJyZW50WCIsImN1cnJlbnRZIiwib2Zmc2V0WCIsIm9mZnNldFkiLCJvbkRyYWdTdGFydCIsIm9uRHJhZ01vdmUiLCJvbkRyYWdFbmQiLCJzaG91bGRJZ25vcmVFdmVudCIsInNlbmRQcmVzc0tleU1lc3NhZ2UiLCJhY3RpdmVFbGVtZW50IiwicmVwZWF0Iiwia2V5RXZlbnQiLCJjb2RlIiwiY2hhcmFjdGVycyIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsImtleUNvZGUiLCJhbHQiLCJhbHRLZXkiLCJjb250cm9sIiwiY3RybEtleSIsInNoaWZ0S2V5IiwibWV0YSIsIm1ldGFLZXkiLCJvbktleSIsIm1hdGNoQWxsIiwic2hpbSIsImlzU2VsZWN0aW5nIiwiY29sbGFwc2VkIiwib25TZWxlY3Rpb25FbmQiLCJvblNlbGVjdGlvblN0YXJ0IiwiZ2V0Q3VycmVudFNlbGVjdGlvbiIsImdldEN1cnJlbnRTZWxlY3Rpb25UZXh0IiwiZ2V0U2VsZWN0aW9uUmVjdCIsInNlbCIsImdldFJhbmdlQXQiLCJzZWxlY3Rpb24iLCJ0b1N0cmluZyIsImNsZWFuSGlnaGxpZ2h0IiwicmVwbGFjZSIsImFuY2hvck5vZGUiLCJmb2N1c05vZGUiLCJyYW5nZUNvdW50IiwiY3JlYXRlT3JkZXJlZFJhbmdlIiwiYW5jaG9yT2Zmc2V0IiwiZm9jdXNPZmZzZXQiLCJzbmlwcGV0TGVuZ3RoIiwiZmlyc3RXb3JkU3RhcnQiLCJsYXN0V29yZEVuZCIsInBvcCIsInN0YXJ0Tm9kZSIsImVuZE5vZGUiLCJyYW5nZVJldmVyc2UiLCJjb252ZXJ0UmFuZ2VJbmZvIiwicmFuZ2VJbmZvIiwic3RhcnRFbGVtZW50Iiwic3RhcnRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IiLCJzdGFydENvbnRhaW5lckNoaWxkVGV4dE5vZGVJbmRleCIsImVuZEVsZW1lbnQiLCJlbmRDb250YWluZXJFbGVtZW50Q3NzU2VsZWN0b3IiLCJlbmRDb250YWluZXJDaGlsZFRleHROb2RlSW5kZXgiLCJsb2NhdGlvbjJSYW5nZUluZm8iLCJsb2NhdGlvbiIsImRvbVJhbmdlIiwidGV4dE5vZGVJbmRleCIsInJlZ2lzdGVyRGVjb3JhdGlvblRlbXBsYXRlcyIsImlzUmVmbG93YWJsZSIsImhlYWQiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8501\n')},1924:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar callBind = __webpack_require__(5559);\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTkyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxlQUFlLG1CQUFPLENBQUMsSUFBSTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2NhbGwtYmluZC9jYWxsQm91bmQuanM/NTQ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJy4vJyk7XG5cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kKEdldEludHJpbnNpYygnU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpYyA9IEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZyk7XG5cdGlmICh0eXBlb2YgaW50cmluc2ljID09PSAnZnVuY3Rpb24nICYmICRpbmRleE9mKG5hbWUsICcucHJvdG90eXBlLicpID4gLTEpIHtcblx0XHRyZXR1cm4gY2FsbEJpbmQoaW50cmluc2ljKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1924\n")},5559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTtBQUNsQyxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsU0FBUyxVQUFVO0FBQ3ZDLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsa0JBQWtCO0FBQzlELEVBQUU7QUFDRixDQUFDLG9CQUFvQjtBQUNyQiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY2FsbC1iaW5kL2luZGV4LmpzPzNlYjEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJyk7XG52YXIgJGNhbGwgPSBHZXRJbnRyaW5zaWMoJyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gR2V0SW50cmluc2ljKCclUmVmbGVjdC5hcHBseSUnLCB0cnVlKSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG5cbnZhciAkZ09QRCA9IEdldEludHJpbnNpYygnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJywgdHJ1ZSk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xudmFyICRtYXggPSBHZXRJbnRyaW5zaWMoJyVNYXRoLm1heCUnKTtcblxuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmQob3JpZ2luYWxGdW5jdGlvbikge1xuXHR2YXIgZnVuYyA9ICRyZWZsZWN0QXBwbHkoYmluZCwgJGNhbGwsIGFyZ3VtZW50cyk7XG5cdGlmICgkZ09QRCAmJiAkZGVmaW5lUHJvcGVydHkpIHtcblx0XHR2YXIgZGVzYyA9ICRnT1BEKGZ1bmMsICdsZW5ndGgnKTtcblx0XHRpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdC8vIG9yaWdpbmFsIGxlbmd0aCwgcGx1cyB0aGUgcmVjZWl2ZXIsIG1pbnVzIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyAoYWZ0ZXIgdGhlIHJlY2VpdmVyKVxuXHRcdFx0JGRlZmluZVByb3BlcnR5KFxuXHRcdFx0XHRmdW5jLFxuXHRcdFx0XHQnbGVuZ3RoJyxcblx0XHRcdFx0eyB2YWx1ZTogMSArICRtYXgoMCwgb3JpZ2luYWxGdW5jdGlvbi5sZW5ndGggLSAoYXJndW1lbnRzLmxlbmd0aCAtIDEpKSB9XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZnVuYztcbn07XG5cbnZhciBhcHBseUJpbmQgPSBmdW5jdGlvbiBhcHBseUJpbmQoKSB7XG5cdHJldHVybiAkcmVmbGVjdEFwcGx5KGJpbmQsICRhcHBseSwgYXJndW1lbnRzKTtcbn07XG5cbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0JGRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnYXBwbHknLCB7IHZhbHVlOiBhcHBseUJpbmQgfSk7XG59IGVsc2Uge1xuXHRtb2R1bGUuZXhwb3J0cy5hcHBseSA9IGFwcGx5QmluZDtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5559\n")},4289:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keys = __webpack_require__(2215);\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\n\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function (fn) {\n\treturn typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function () {\n\tvar obj = {};\n\ttry {\n\t\torigDefineProperty(obj, 'x', { enumerable: false, value: obj });\n\t\t// eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\t\tfor (var _ in obj) { // jscs:ignore disallowUnusedVariables\n\t\t\treturn false;\n\t\t}\n\t\treturn obj.x === obj;\n\t} catch (e) { /* this is IE 8. */\n\t\treturn false;\n\t}\n};\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function (object, name, value, predicate) {\n\tif (name in object && (!isFunction(predicate) || !predicate())) {\n\t\treturn;\n\t}\n\tif (supportsDescriptors) {\n\t\torigDefineProperty(object, name, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: value,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\tobject[name] = value;\n\t}\n};\n\nvar defineProperties = function (object, map) {\n\tvar predicates = arguments.length > 2 ? arguments[2] : {};\n\tvar props = keys(map);\n\tif (hasSymbols) {\n\t\tprops = concat.call(props, Object.getOwnPropertySymbols(map));\n\t}\n\tfor (var i = 0; i < props.length; i += 1) {\n\t\tdefineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n\t}\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\n\nmodule.exports = defineProperties;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI4OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBYTtBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRyxZQUFZO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZGVmaW5lLXByb3BlcnRpZXMvaW5kZXguanM/ZjM2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sKCdmb28nKSA9PT0gJ3N5bWJvbCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciBvcmlnRGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgdG9TdHIuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG52YXIgYXJlUHJvcGVydHlEZXNjcmlwdG9yc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIG9iaiA9IHt9O1xuXHR0cnkge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmosICd4JywgeyBlbnVtZXJhYmxlOiBmYWxzZSwgdmFsdWU6IG9iaiB9KTtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG5cdFx0Zm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iai54ID09PSBvYmo7XG5cdH0gY2F0Y2ggKGUpIHsgLyogdGhpcyBpcyBJRSA4LiAqL1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufTtcbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gb3JpZ0RlZmluZVByb3BlcnR5ICYmIGFyZVByb3BlcnR5RGVzY3JpcHRvcnNTdXBwb3J0ZWQoKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgdmFsdWUsIHByZWRpY2F0ZSkge1xuXHRpZiAobmFtZSBpbiBvYmplY3QgJiYgKCFpc0Z1bmN0aW9uKHByZWRpY2F0ZSkgfHwgIXByZWRpY2F0ZSgpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuXHRcdG9yaWdEZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0d3JpdGFibGU6IHRydWVcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRvYmplY3RbbmFtZV0gPSB2YWx1ZTtcblx0fVxufTtcblxudmFyIGRlZmluZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAob2JqZWN0LCBtYXApIHtcblx0dmFyIHByZWRpY2F0ZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXHR2YXIgcHJvcHMgPSBrZXlzKG1hcCk7XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0cHJvcHMgPSBjb25jYXQuY2FsbChwcm9wcywgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtYXApKTtcblx0fVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wc1tpXSwgbWFwW3Byb3BzW2ldXSwgcHJlZGljYXRlc1twcm9wc1tpXV0pO1xuXHR9XG59O1xuXG5kZWZpbmVQcm9wZXJ0aWVzLnN1cHBvcnRzRGVzY3JpcHRvcnMgPSAhIXN1cHBvcnRzRGVzY3JpcHRvcnM7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydGllcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4289\n")},1503:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = __webpack_require__(4149);\nvar isCallable = __webpack_require__(5320);\nvar isDate = __webpack_require__(8923);\nvar isSymbol = __webpack_require__(2636);\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n\tif (typeof O === 'undefined' || O === null) {\n\t\tthrow new TypeError('Cannot call method on ' + O);\n\t}\n\tif (typeof hint !== 'string' || (hint !== 'number' && hint !== 'string')) {\n\t\tthrow new TypeError('hint must be \"string\" or \"number\"');\n\t}\n\tvar methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\tvar method, result, i;\n\tfor (i = 0; i < methodNames.length; ++i) {\n\t\tmethod = O[methodNames[i]];\n\t\tif (isCallable(method)) {\n\t\t\tresult = method.call(O);\n\t\t\tif (isPrimitive(result)) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\tthrow new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n\tvar func = O[P];\n\tif (func !== null && typeof func !== 'undefined') {\n\t\tif (!isCallable(func)) {\n\t\t\tthrow new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n\t\t}\n\t\treturn func;\n\t}\n\treturn void 0;\n};\n\n// http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tvar hint = 'default';\n\tif (arguments.length > 1) {\n\t\tif (arguments[1] === String) {\n\t\t\thint = 'string';\n\t\t} else if (arguments[1] === Number) {\n\t\t\thint = 'number';\n\t\t}\n\t}\n\n\tvar exoticToPrim;\n\tif (hasSymbols) {\n\t\tif (Symbol.toPrimitive) {\n\t\t\texoticToPrim = GetMethod(input, Symbol.toPrimitive);\n\t\t} else if (isSymbol(input)) {\n\t\t\texoticToPrim = Symbol.prototype.valueOf;\n\t\t}\n\t}\n\tif (typeof exoticToPrim !== 'undefined') {\n\t\tvar result = exoticToPrim.call(input, hint);\n\t\tif (isPrimitive(result)) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new TypeError('unable to convert exotic object to primitive');\n\t}\n\tif (hint === 'default' && (isDate(input) || isSymbol(input))) {\n\t\thint = 'string';\n\t}\n\treturn ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUwMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1QjtBQUNqRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLGFBQWEsbUJBQU8sQ0FBQyxJQUFnQjtBQUNyQyxlQUFlLG1CQUFPLENBQUMsSUFBVzs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9lczIwMTUuanM/NTk5NyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAnc3ltYm9sJztcblxudmFyIGlzUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9oZWxwZXJzL2lzUHJpbWl0aXZlJyk7XG52YXIgaXNDYWxsYWJsZSA9IHJlcXVpcmUoJ2lzLWNhbGxhYmxlJyk7XG52YXIgaXNEYXRlID0gcmVxdWlyZSgnaXMtZGF0ZS1vYmplY3QnKTtcbnZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJ2lzLXN5bWJvbCcpO1xuXG52YXIgb3JkaW5hcnlUb1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuXHRpZiAodHlwZW9mIE8gPT09ICd1bmRlZmluZWQnIHx8IE8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBtZXRob2Qgb24gJyArIE8pO1xuXHR9XG5cdGlmICh0eXBlb2YgaGludCAhPT0gJ3N0cmluZycgfHwgKGhpbnQgIT09ICdudW1iZXInICYmIGhpbnQgIT09ICdzdHJpbmcnKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2hpbnQgbXVzdCBiZSBcInN0cmluZ1wiIG9yIFwibnVtYmVyXCInKTtcblx0fVxuXHR2YXIgbWV0aG9kTmFtZXMgPSBoaW50ID09PSAnc3RyaW5nJyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdHZhciBtZXRob2QsIHJlc3VsdCwgaTtcblx0Zm9yIChpID0gMDsgaSA8IG1ldGhvZE5hbWVzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWV0aG9kID0gT1ttZXRob2ROYW1lc1tpXV07XG5cdFx0aWYgKGlzQ2FsbGFibGUobWV0aG9kKSkge1xuXHRcdFx0cmVzdWx0ID0gbWV0aG9kLmNhbGwoTyk7XG5cdFx0XHRpZiAoaXNQcmltaXRpdmUocmVzdWx0KSkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHR0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBkZWZhdWx0IHZhbHVlJyk7XG59O1xuXG52YXIgR2V0TWV0aG9kID0gZnVuY3Rpb24gR2V0TWV0aG9kKE8sIFApIHtcblx0dmFyIGZ1bmMgPSBPW1BdO1xuXHRpZiAoZnVuYyAhPT0gbnVsbCAmJiB0eXBlb2YgZnVuYyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRpZiAoIWlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoZnVuYyArICcgcmV0dXJuZWQgZm9yIHByb3BlcnR5ICcgKyBQICsgJyBvZiBvYmplY3QgJyArIE8gKyAnIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdHJldHVybiBmdW5jO1xuXHR9XG5cdHJldHVybiB2b2lkIDA7XG59O1xuXG4vLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9wcmltaXRpdmVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcblx0aWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuXHRcdHJldHVybiBpbnB1dDtcblx0fVxuXHR2YXIgaGludCA9ICdkZWZhdWx0Jztcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0aWYgKGFyZ3VtZW50c1sxXSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRoaW50ID0gJ3N0cmluZyc7XG5cdFx0fSBlbHNlIGlmIChhcmd1bWVudHNbMV0gPT09IE51bWJlcikge1xuXHRcdFx0aGludCA9ICdudW1iZXInO1xuXHRcdH1cblx0fVxuXG5cdHZhciBleG90aWNUb1ByaW07XG5cdGlmIChoYXNTeW1ib2xzKSB7XG5cdFx0aWYgKFN5bWJvbC50b1ByaW1pdGl2ZSkge1xuXHRcdFx0ZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCBTeW1ib2wudG9QcmltaXRpdmUpO1xuXHRcdH0gZWxzZSBpZiAoaXNTeW1ib2woaW5wdXQpKSB7XG5cdFx0XHRleG90aWNUb1ByaW0gPSBTeW1ib2wucHJvdG90eXBlLnZhbHVlT2Y7XG5cdFx0fVxuXHR9XG5cdGlmICh0eXBlb2YgZXhvdGljVG9QcmltICE9PSAndW5kZWZpbmVkJykge1xuXHRcdHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG5cdFx0aWYgKGlzUHJpbWl0aXZlKHJlc3VsdCkpIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuYWJsZSB0byBjb252ZXJ0IGV4b3RpYyBvYmplY3QgdG8gcHJpbWl0aXZlJyk7XG5cdH1cblx0aWYgKGhpbnQgPT09ICdkZWZhdWx0JyAmJiAoaXNEYXRlKGlucHV0KSB8fCBpc1N5bWJvbChpbnB1dCkpKSB7XG5cdFx0aGludCA9ICdzdHJpbmcnO1xuXHR9XG5cdHJldHVybiBvcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSAnZGVmYXVsdCcgPyAnbnVtYmVyJyA6IGhpbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1503\n")},2116:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nvar isPrimitive = __webpack_require__(4149);\n\nvar isCallable = __webpack_require__(5320);\n\n// http://ecma-international.org/ecma-262/5.1/#sec-8.12.8\nvar ES5internalSlots = {\n\t'[[DefaultValue]]': function (O) {\n\t\tvar actualHint;\n\t\tif (arguments.length > 1) {\n\t\t\tactualHint = arguments[1];\n\t\t} else {\n\t\t\tactualHint = toStr.call(O) === '[object Date]' ? String : Number;\n\t\t}\n\n\t\tif (actualHint === String || actualHint === Number) {\n\t\t\tvar methods = actualHint === String ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n\t\t\tvar value, i;\n\t\t\tfor (i = 0; i < methods.length; ++i) {\n\t\t\t\tif (isCallable(O[methods[i]])) {\n\t\t\t\t\tvalue = O[methods[i]]();\n\t\t\t\t\tif (isPrimitive(value)) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TypeError('No default value');\n\t\t}\n\t\tthrow new TypeError('invalid [[DefaultValue]] hint supplied');\n\t}\n};\n\n// http://ecma-international.org/ecma-262/5.1/#sec-9.1\nmodule.exports = function ToPrimitive(input) {\n\tif (isPrimitive(input)) {\n\t\treturn input;\n\t}\n\tif (arguments.length > 1) {\n\t\treturn ES5internalSlots['[[DefaultValue]]'](input, arguments[1]);\n\t}\n\treturn ES5internalSlots['[[DefaultValue]]'](input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjExNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF1Qjs7QUFFakQsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy10by1wcmltaXRpdmUvZXM1LmpzPzJmMTciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNQcmltaXRpdmUgPSByZXF1aXJlKCcuL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyIGlzQ2FsbGFibGUgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuXG4vLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjEyLjhcbnZhciBFUzVpbnRlcm5hbFNsb3RzID0ge1xuXHQnW1tEZWZhdWx0VmFsdWVdXSc6IGZ1bmN0aW9uIChPKSB7XG5cdFx0dmFyIGFjdHVhbEhpbnQ7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gYXJndW1lbnRzWzFdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhY3R1YWxIaW50ID0gdG9TdHIuY2FsbChPKSA9PT0gJ1tvYmplY3QgRGF0ZV0nID8gU3RyaW5nIDogTnVtYmVyO1xuXHRcdH1cblxuXHRcdGlmIChhY3R1YWxIaW50ID09PSBTdHJpbmcgfHwgYWN0dWFsSGludCA9PT0gTnVtYmVyKSB7XG5cdFx0XHR2YXIgbWV0aG9kcyA9IGFjdHVhbEhpbnQgPT09IFN0cmluZyA/IFsndG9TdHJpbmcnLCAndmFsdWVPZiddIDogWyd2YWx1ZU9mJywgJ3RvU3RyaW5nJ107XG5cdFx0XHR2YXIgdmFsdWUsIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRpZiAoaXNDYWxsYWJsZShPW21ldGhvZHNbaV1dKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gT1ttZXRob2RzW2ldXSgpO1xuXHRcdFx0XHRcdGlmIChpc1ByaW1pdGl2ZSh2YWx1ZSkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ05vIGRlZmF1bHQgdmFsdWUnKTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBbW0RlZmF1bHRWYWx1ZV1dIGhpbnQgc3VwcGxpZWQnKTtcblx0fVxufTtcblxuLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtOS4xXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChpc1ByaW1pdGl2ZShpbnB1dCkpIHtcblx0XHRyZXR1cm4gaW5wdXQ7XG5cdH1cblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0cmV0dXJuIEVTNWludGVybmFsU2xvdHNbJ1tbRGVmYXVsdFZhbHVlXV0nXShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gRVM1aW50ZXJuYWxTbG90c1snW1tEZWZhdWx0VmFsdWVdXSddKGlucHV0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2116\n")},4149:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE0OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLXRvLXByaW1pdGl2ZS9oZWxwZXJzL2lzUHJpbWl0aXZlLmpzPzRkZTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKHZhbHVlKSB7XG5cdHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4149\n")},7648:function(module){"use strict";eval("\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQkFBaUI7QUFDckM7QUFDQTs7QUFFQSwrRUFBK0Usc0NBQXNDOztBQUVySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcz82ODhlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyogZXNsaW50IG5vLWludmFsaWQtdGhpczogMSAqL1xuXG52YXIgRVJST1JfTUVTU0FHRSA9ICdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICc7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmNUeXBlID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5jYWxsKHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kO1xuICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoYXQsXG4gICAgICAgICAgICAgICAgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBNYXRoLm1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzLnB1c2goJyQnICsgaSk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGJvdW5kQXJncy5qb2luKCcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgdmFyIEVtcHR5ID0gZnVuY3Rpb24gRW1wdHkoKSB7fTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gdGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJvdW5kO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7648\n")},8612:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(7648);\n\nmodule.exports = Function.prototype.bind || implementation;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanM/MGY3YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8612\n")},210:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = __webpack_require__(1405)();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet\n};\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = __webpack_require__(8612);\nvar hasOwn = __webpack_require__(7642);\nvar $concat = bind.call(Function.call, Array.prototype.concat);\nvar $spliceApply = bind.call(Function.apply, Array.prototype.splice);\nvar $replace = bind.call(Function.call, String.prototype.replace);\nvar $strSlice = bind.call(Function.call, String.prototype.slice);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcz8wMGNlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRTeW50YXhFcnJvciA9IFN5bnRheEVycm9yO1xudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xudmFyICRUeXBlRXJyb3IgPSBUeXBlRXJyb3I7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKHt9LCAnJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQkZ09QRCA9IG51bGw7IC8vIHRoaXMgaXMgSUUgOCwgd2hpY2ggaGFzIGEgYnJva2VuIGdPUERcblx0fVxufVxuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5fX3Byb3RvX187IH07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cblxudmFyIG5lZWRzRXZhbCA9IHt9O1xuXG52YXIgVHlwZWRBcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0JyVBZ2dyZWdhdGVFcnJvciUnOiB0eXBlb2YgQWdncmVnYXRlRXJyb3IgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQWdncmVnYXRlRXJyb3IsXG5cdCclQXJyYXklJzogQXJyYXksXG5cdCclQXJyYXlCdWZmZXIlJzogdHlwZW9mIEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFycmF5QnVmZmVyLFxuXHQnJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGcm9tU3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Z1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiBuZWVkc0V2YWwsXG5cdCclQXRvbWljcyUnOiB0eXBlb2YgQXRvbWljcyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBdG9taWNzLFxuXHQnJUJpZ0ludCUnOiB0eXBlb2YgQmlnSW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEJpZ0ludCxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6IEVycm9yLFxuXHQnJWV2YWwlJzogZXZhbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXG5cdCclRXZhbEVycm9yJSc6IEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IE1hcCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclTWF0aCUnOiBNYXRoLFxuXHQnJU51bWJlciUnOiBOdW1iZXIsXG5cdCclT2JqZWN0JSc6IE9iamVjdCxcblx0JyVwYXJzZUZsb2F0JSc6IHBhcnNlRmxvYXQsXG5cdCclcGFyc2VJbnQlJzogcGFyc2VJbnQsXG5cdCclUHJvbWlzZSUnOiB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm9taXNlLFxuXHQnJVByb3h5JSc6IHR5cGVvZiBQcm94eSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBQcm94eSxcblx0JyVSYW5nZUVycm9yJSc6IFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8obmV3IFNldCgpW1N5bWJvbC5pdGVyYXRvcl0oKSksXG5cdCclU2hhcmVkQXJyYXlCdWZmZXIlJzogdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNoYXJlZEFycmF5QnVmZmVyLFxuXHQnJVN0cmluZyUnOiBTdHJpbmcsXG5cdCclU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlJzogaGFzU3ltYm9scyA/IGdldFByb3RvKCcnW1N5bWJvbC5pdGVyYXRvcl0oKSkgOiB1bmRlZmluZWQsXG5cdCclU3ltYm9sJSc6IGhhc1N5bWJvbHMgPyBTeW1ib2wgOiB1bmRlZmluZWQsXG5cdCclU3ludGF4RXJyb3IlJzogJFN5bnRheEVycm9yLFxuXHQnJVRocm93VHlwZUVycm9yJSc6IFRocm93VHlwZUVycm9yLFxuXHQnJVR5cGVkQXJyYXklJzogVHlwZWRBcnJheSxcblx0JyVUeXBlRXJyb3IlJzogJFR5cGVFcnJvcixcblx0JyVVaW50OEFycmF5JSc6IHR5cGVvZiBVaW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4QXJyYXksXG5cdCclVWludDhDbGFtcGVkQXJyYXklJzogdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQ4Q2xhbXBlZEFycmF5LFxuXHQnJVVpbnQxNkFycmF5JSc6IHR5cGVvZiBVaW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MTZBcnJheSxcblx0JyVVaW50MzJBcnJheSUnOiB0eXBlb2YgVWludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDMyQXJyYXksXG5cdCclVVJJRXJyb3IlJzogVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXRcbn07XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKEZ1bmN0aW9uLmNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbChGdW5jdGlvbi5hcHBseSwgQXJyYXkucHJvdG90eXBlLnNwbGljZSk7XG52YXIgJHJlcGxhY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoRnVuY3Rpb24uY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0dmFyIHBhcnRzID0gc3RyaW5nVG9QYXRoKG5hbWUpO1xuXHR2YXIgaW50cmluc2ljQmFzZU5hbWUgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHNbMF0gOiAnJztcblxuXHR2YXIgaW50cmluc2ljID0gZ2V0QmFzZUludHJpbnNpYygnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJywgYWxsb3dNaXNzaW5nKTtcblx0dmFyIGludHJpbnNpY1JlYWxOYW1lID0gaW50cmluc2ljLm5hbWU7XG5cdHZhciB2YWx1ZSA9IGludHJpbnNpYy52YWx1ZTtcblx0dmFyIHNraXBGdXJ0aGVyQ2FjaGluZyA9IGZhbHNlO1xuXG5cdHZhciBhbGlhcyA9IGludHJpbnNpYy5hbGlhcztcblx0aWYgKGFsaWFzKSB7XG5cdFx0aW50cmluc2ljQmFzZU5hbWUgPSBhbGlhc1swXTtcblx0XHQkc3BsaWNlQXBwbHkocGFydHMsICRjb25jYXQoWzAsIDFdLCBhbGlhcykpO1xuXHR9XG5cblx0Zm9yICh2YXIgaSA9IDEsIGlzT3duID0gdHJ1ZTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG5cdFx0dmFyIHBhcnQgPSBwYXJ0c1tpXTtcblx0XHR2YXIgZmlyc3QgPSAkc3RyU2xpY2UocGFydCwgMCwgMSk7XG5cdFx0dmFyIGxhc3QgPSAkc3RyU2xpY2UocGFydCwgLTEpO1xuXHRcdGlmIChcblx0XHRcdChcblx0XHRcdFx0KGZpcnN0ID09PSAnXCInIHx8IGZpcnN0ID09PSBcIidcIiB8fCBmaXJzdCA9PT0gJ2AnKVxuXHRcdFx0XHR8fCAobGFzdCA9PT0gJ1wiJyB8fCBsYXN0ID09PSBcIidcIiB8fCBsYXN0ID09PSAnYCcpXG5cdFx0XHQpXG5cdFx0XHQmJiBmaXJzdCAhPT0gbGFzdFxuXHRcdCkge1xuXHRcdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcigncHJvcGVydHkgbmFtZXMgd2l0aCBxdW90ZXMgbXVzdCBoYXZlIG1hdGNoaW5nIHF1b3RlcycpO1xuXHRcdH1cblx0XHRpZiAocGFydCA9PT0gJ2NvbnN0cnVjdG9yJyB8fCAhaXNPd24pIHtcblx0XHRcdHNraXBGdXJ0aGVyQ2FjaGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aW50cmluc2ljQmFzZU5hbWUgKz0gJy4nICsgcGFydDtcblx0XHRpbnRyaW5zaWNSZWFsTmFtZSA9ICclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnO1xuXG5cdFx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNSZWFsTmFtZSkpIHtcblx0XHRcdHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV07XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSAhPSBudWxsKSB7XG5cdFx0XHRpZiAoIShwYXJ0IGluIHZhbHVlKSkge1xuXHRcdFx0XHRpZiAoIWFsbG93TWlzc2luZykge1xuXHRcdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdiYXNlIGludHJpbnNpYyBmb3IgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IHRoZSBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLicpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICgkZ09QRCAmJiAoaSArIDEpID49IHBhcnRzLmxlbmd0aCkge1xuXHRcdFx0XHR2YXIgZGVzYyA9ICRnT1BEKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0aXNPd24gPSAhIWRlc2M7XG5cblx0XHRcdFx0Ly8gQnkgY29udmVudGlvbiwgd2hlbiBhIGRhdGEgcHJvcGVydHkgaXMgY29udmVydGVkIHRvIGFuIGFjY2Vzc29yXG5cdFx0XHRcdC8vIHByb3BlcnR5IHRvIGVtdWxhdGUgYSBkYXRhIHByb3BlcnR5IHRoYXQgZG9lcyBub3Qgc3VmZmVyIGZyb21cblx0XHRcdFx0Ly8gdGhlIG92ZXJyaWRlIG1pc3Rha2UsIHRoYXQgYWNjZXNzb3IncyBnZXR0ZXIgaXMgbWFya2VkIHdpdGhcblx0XHRcdFx0Ly8gYW4gYG9yaWdpbmFsVmFsdWVgIHByb3BlcnR5LiBIZXJlLCB3aGVuIHdlIGRldGVjdCB0aGlzLCB3ZVxuXHRcdFx0XHQvLyB1cGhvbGQgdGhlIGlsbHVzaW9uIGJ5IHByZXRlbmRpbmcgdG8gc2VlIHRoYXQgb3JpZ2luYWwgZGF0YVxuXHRcdFx0XHQvLyBwcm9wZXJ0eSwgaS5lLiwgcmV0dXJuaW5nIHRoZSB2YWx1ZSByYXRoZXIgdGhhbiB0aGUgZ2V0dGVyXG5cdFx0XHRcdC8vIGl0c2VsZi5cblx0XHRcdFx0aWYgKGlzT3duICYmICdnZXQnIGluIGRlc2MgJiYgISgnb3JpZ2luYWxWYWx1ZScgaW4gZGVzYy5nZXQpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBkZXNjLmdldDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpc093biA9IGhhc093bih2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHR9XG5cblx0XHRcdGlmIChpc093biAmJiAhc2tpcEZ1cnRoZXJDYWNoaW5nKSB7XG5cdFx0XHRcdElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")},1405:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = __webpack_require__(5419);\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLG9CQUFvQixtQkFBTyxDQUFDLElBQVM7O0FBRXJDO0FBQ0EseUNBQXlDO0FBQ3pDLHFDQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsMENBQTBDOztBQUUxQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcz81MTU2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIG9yaWdTeW1ib2wgPSB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2w7XG52YXIgaGFzU3ltYm9sU2hhbSA9IHJlcXVpcmUoJy4vc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1405\n")},5419:function(module){"use strict";eval("\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQyxrRUFBa0U7QUFDbEUscUVBQXFFOztBQUVyRTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLHVDQUF1Qzs7QUFFdkMsMkRBQTJEO0FBQzNELCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEMsMkVBQTJFOztBQUUzRSx5R0FBeUc7O0FBRXpHO0FBQ0EsNkNBQTZDOztBQUU3Qyw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanM/MTY5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yIChzeW0gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5419\n")},6410:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(5419);\n\nmodule.exports = function hasToStringTagShams() {\n\treturn hasSymbols() && !!Symbol.toStringTag;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQxMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFtQjs7QUFFNUM7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9oYXMtdG9zdHJpbmd0YWcvc2hhbXMuanM/MDdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNUb1N0cmluZ1RhZ1NoYW1zKCkge1xuXHRyZXR1cm4gaGFzU3ltYm9scygpICYmICEhU3ltYm9sLnRvU3RyaW5nVGFnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6410\n")},7642:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar bind = __webpack_require__(8612);\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzY0Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2hhcy9zcmMvaW5kZXguanM/YTBkMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQuY2FsbChGdW5jdGlvbi5jYWxsLCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7642\n")},9496:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar has = __webpack_require__(7642);\nvar channel = __webpack_require__(7478)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar SLOT = {\n\tassert: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tchannel.assert(O);\n\t},\n\tget: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn slots && slots['$' + slot];\n\t},\n\thas: function (O, slot) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\treturn !!slots && has(slots, '$' + slot);\n\t},\n\tset: function (O, slot, V) {\n\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\tthrow new $TypeError('`O` is not an object');\n\t\t}\n\t\tif (typeof slot !== 'string') {\n\t\t\tthrow new $TypeError('`slot` must be a string');\n\t\t}\n\t\tvar slots = channel.get(O);\n\t\tif (!slots) {\n\t\t\tslots = {};\n\t\t\tchannel.set(O, slots);\n\t\t}\n\t\tslots['$' + slot] = V;\n\t}\n};\n\nif (Object.freeze) {\n\tObject.freeze(SLOT);\n}\n\nmodule.exports = SLOT;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLFVBQVUsbUJBQU8sQ0FBQyxJQUFLO0FBQ3ZCLGNBQWMsbUJBQU8sQ0FBQyxJQUFjOztBQUVwQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pbnRlcm5hbC1zbG90L2luZGV4LmpzPzY1ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xudmFyIGNoYW5uZWwgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwnKSgpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFNMT1QgPSB7XG5cdGFzc2VydDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0Y2hhbm5lbC5hc3NlcnQoTyk7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24gKE8sIHNsb3QpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0cmV0dXJuIHNsb3RzICYmIHNsb3RzWyckJyArIHNsb3RdO1xuXHR9LFxuXHRoYXM6IGZ1bmN0aW9uIChPLCBzbG90KSB7XG5cdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYE9gIGlzIG5vdCBhbiBvYmplY3QnKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBzbG90ICE9PSAnc3RyaW5nJykge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BzbG90YCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdFx0fVxuXHRcdHZhciBzbG90cyA9IGNoYW5uZWwuZ2V0KE8pO1xuXHRcdHJldHVybiAhIXNsb3RzICYmIGhhcyhzbG90cywgJyQnICsgc2xvdCk7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24gKE8sIHNsb3QsIFYpIHtcblx0XHRpZiAoIU8gfHwgKHR5cGVvZiBPICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgTyAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdgT2AgaXMgbm90IGFuIG9iamVjdCcpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHNsb3QgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYHNsb3RgIG11c3QgYmUgYSBzdHJpbmcnKTtcblx0XHR9XG5cdFx0dmFyIHNsb3RzID0gY2hhbm5lbC5nZXQoTyk7XG5cdFx0aWYgKCFzbG90cykge1xuXHRcdFx0c2xvdHMgPSB7fTtcblx0XHRcdGNoYW5uZWwuc2V0KE8sIHNsb3RzKTtcblx0XHR9XG5cdFx0c2xvdHNbJyQnICsgc2xvdF0gPSBWO1xuXHR9XG59O1xuXG5pZiAoT2JqZWN0LmZyZWV6ZSkge1xuXHRPYmplY3QuZnJlZXplKFNMT1QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNMT1Q7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9496\n")},5320:function(module){"use strict";eval("\n\nvar fnToStr = Function.prototype.toString;\nvar reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;\nvar badArrayLike;\nvar isCallableMarker;\nif (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {\n\ttry {\n\t\tbadArrayLike = Object.defineProperty({}, 'length', {\n\t\t\tget: function () {\n\t\t\t\tthrow isCallableMarker;\n\t\t\t}\n\t\t});\n\t\tisCallableMarker = {};\n\t\t// eslint-disable-next-line no-throw-literal\n\t\treflectApply(function () { throw 42; }, null, badArrayLike);\n\t} catch (_) {\n\t\tif (_ !== isCallableMarker) {\n\t\t\treflectApply = null;\n\t\t}\n\t}\n} else {\n\treflectApply = null;\n}\n\nvar constructorRegex = /^\\s*class\\b/;\nvar isES6ClassFn = function isES6ClassFunction(value) {\n\ttry {\n\t\tvar fnStr = fnToStr.call(value);\n\t\treturn constructorRegex.test(fnStr);\n\t} catch (e) {\n\t\treturn false; // not a function\n\t}\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n\ttry {\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tfnToStr.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`\n/* globals document: false */\nvar documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};\n\nmodule.exports = reflectApply\n\t? function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\ttry {\n\t\t\treflectApply(value, null, badArrayLike);\n\t\t} catch (e) {\n\t\t\tif (e !== isCallableMarker) { return false; }\n\t\t}\n\t\treturn !isES6ClassFn(value);\n\t}\n\t: function isCallable(value) {\n\t\tif (value === documentDotAll) { return true; }\n\t\tif (!value) { return false; }\n\t\tif (typeof value !== 'function' && typeof value !== 'object') { return false; }\n\t\tif (typeof value === 'function' && !value.prototype) { return true; }\n\t\tif (hasToStringTag) { return tryFunctionObject(value); }\n\t\tif (isES6ClassFn(value)) { return false; }\n\t\tvar strClass = toStr.call(value);\n\t\treturn strClass === fnClass || strClass === genClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLGdCQUFnQjtBQUNoQixrRUFBa0U7QUFDbEUseURBQXlEO0FBQ3pELHdCQUF3QjtBQUN4Qiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1jYWxsYWJsZS9pbmRleC5qcz8yMWQwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGZuVG9TdHIgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgcmVmbGVjdEFwcGx5ID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QgIT09IG51bGwgJiYgUmVmbGVjdC5hcHBseTtcbnZhciBiYWRBcnJheUxpa2U7XG52YXIgaXNDYWxsYWJsZU1hcmtlcjtcbmlmICh0eXBlb2YgcmVmbGVjdEFwcGx5ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0dHJ5IHtcblx0XHRiYWRBcnJheUxpa2UgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdsZW5ndGgnLCB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dGhyb3cgaXNDYWxsYWJsZU1hcmtlcjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpc0NhbGxhYmxlTWFya2VyID0ge307XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcblx0XHRyZWZsZWN0QXBwbHkoZnVuY3Rpb24gKCkgeyB0aHJvdyA0MjsgfSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0fSBjYXRjaCAoXykge1xuXHRcdGlmIChfICE9PSBpc0NhbGxhYmxlTWFya2VyKSB7XG5cdFx0XHRyZWZsZWN0QXBwbHkgPSBudWxsO1xuXHRcdH1cblx0fVxufSBlbHNlIHtcblx0cmVmbGVjdEFwcGx5ID0gbnVsbDtcbn1cblxudmFyIGNvbnN0cnVjdG9yUmVnZXggPSAvXlxccypjbGFzc1xcYi87XG52YXIgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0Z1bmN0aW9uKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0dmFyIGZuU3RyID0gZm5Ub1N0ci5jYWxsKHZhbHVlKTtcblx0XHRyZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KGZuU3RyKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTsgLy8gbm90IGEgZnVuY3Rpb25cblx0fVxufTtcblxudmFyIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25Ub1N0cih2YWx1ZSkge1xuXHR0cnkge1xuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZuVG9TdHIuY2FsbCh2YWx1ZSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZuQ2xhc3MgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xudmFyIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgISFTeW1ib2wudG9TdHJpbmdUYWc7IC8vIGJldHRlcjogdXNlIGBoYXMtdG9zdHJpbmd0YWdgXG4vKiBnbG9iYWxzIGRvY3VtZW50OiBmYWxzZSAqL1xudmFyIGRvY3VtZW50RG90QWxsID0gdHlwZW9mIGRvY3VtZW50ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZG9jdW1lbnQuYWxsID09PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5hbGwgIT09IHVuZGVmaW5lZCA/IGRvY3VtZW50LmFsbCA6IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RBcHBseVxuXHQ/IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHtcblx0XHRpZiAodmFsdWUgPT09IGRvY3VtZW50RG90QWxsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0aWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhdmFsdWUucHJvdG90eXBlKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0dHJ5IHtcblx0XHRcdHJlZmxlY3RBcHBseSh2YWx1ZSwgbnVsbCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRpZiAoZSAhPT0gaXNDYWxsYWJsZU1hcmtlcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9XG5cdFx0cmV0dXJuICFpc0VTNkNsYXNzRm4odmFsdWUpO1xuXHR9XG5cdDogZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSA9PT0gZG9jdW1lbnREb3RBbGwpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICF2YWx1ZS5wcm90b3R5cGUpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfVxuXHRcdGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHZhciBzdHJDbGFzcyA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5320\n")},8923:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar getDay = Date.prototype.getDay;\nvar tryDateObject = function tryDateGetDayCall(value) {\n\ttry {\n\t\tgetDay.call(value);\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = __webpack_require__(6410)();\n\nmodule.exports = function isDateObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\treturn hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODkyMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsSUFBdUI7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvaXMtZGF0ZS1vYmplY3QvaW5kZXguanM/MGU2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBnZXREYXkgPSBEYXRlLnByb3RvdHlwZS5nZXREYXk7XG52YXIgdHJ5RGF0ZU9iamVjdCA9IGZ1bmN0aW9uIHRyeURhdGVHZXREYXlDYWxsKHZhbHVlKSB7XG5cdHRyeSB7XG5cdFx0Z2V0RGF5LmNhbGwodmFsdWUpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJztcbnZhciBoYXNUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJ2hhcy10b3N0cmluZ3RhZy9zaGFtcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNEYXRlT2JqZWN0KHZhbHVlKSB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeURhdGVPYmplY3QodmFsdWUpIDogdG9TdHIuY2FsbCh2YWx1ZSkgPT09IGRhdGVDbGFzcztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8923\n")},8420:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBound = __webpack_require__(1924);\nvar hasToStringTag = __webpack_require__(6410)();\nvar has;\nvar $exec;\nvar isRegexMarker;\nvar badStringifier;\n\nif (hasToStringTag) {\n\thas = callBound('Object.prototype.hasOwnProperty');\n\t$exec = callBound('RegExp.prototype.exec');\n\tisRegexMarker = {};\n\n\tvar throwRegexMarker = function () {\n\t\tthrow isRegexMarker;\n\t};\n\tbadStringifier = {\n\t\ttoString: throwRegexMarker,\n\t\tvalueOf: throwRegexMarker\n\t};\n\n\tif (typeof Symbol.toPrimitive === 'symbol') {\n\t\tbadStringifier[Symbol.toPrimitive] = throwRegexMarker;\n\t}\n}\n\nvar $toString = callBound('Object.prototype.toString');\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar regexClass = '[object RegExp]';\n\nmodule.exports = hasToStringTag\n\t// eslint-disable-next-line consistent-return\n\t? function isRegex(value) {\n\t\tif (!value || typeof value !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar descriptor = gOPD(value, 'lastIndex');\n\t\tvar hasLastIndexDataProperty = descriptor && has(descriptor, 'value');\n\t\tif (!hasLastIndexDataProperty) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t$exec(value, badStringifier);\n\t\t} catch (e) {\n\t\t\treturn e === isRegexMarker;\n\t\t}\n\t}\n\t: function isRegex(value) {\n\t\t// In older browsers, typeof regex incorrectly returns 'function'\n\t\tif (!value || (typeof value !== 'object' && typeof value !== 'function')) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $toString(value) === regexClass;\n\t};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQyMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxxQkFBcUIsbUJBQU8sQ0FBQyxJQUF1QjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2lzLXJlZ2V4L2luZGV4LmpzP2Q4ZDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kL2NhbGxCb3VuZCcpO1xudmFyIGhhc1RvU3RyaW5nVGFnID0gcmVxdWlyZSgnaGFzLXRvc3RyaW5ndGFnL3NoYW1zJykoKTtcbnZhciBoYXM7XG52YXIgJGV4ZWM7XG52YXIgaXNSZWdleE1hcmtlcjtcbnZhciBiYWRTdHJpbmdpZmllcjtcblxuaWYgKGhhc1RvU3RyaW5nVGFnKSB7XG5cdGhhcyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eScpO1xuXHQkZXhlYyA9IGNhbGxCb3VuZCgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cdGlzUmVnZXhNYXJrZXIgPSB7fTtcblxuXHR2YXIgdGhyb3dSZWdleE1hcmtlciA9IGZ1bmN0aW9uICgpIHtcblx0XHR0aHJvdyBpc1JlZ2V4TWFya2VyO1xuXHR9O1xuXHRiYWRTdHJpbmdpZmllciA9IHtcblx0XHR0b1N0cmluZzogdGhyb3dSZWdleE1hcmtlcixcblx0XHR2YWx1ZU9mOiB0aHJvd1JlZ2V4TWFya2VyXG5cdH07XG5cblx0aWYgKHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgPT09ICdzeW1ib2wnKSB7XG5cdFx0YmFkU3RyaW5naWZpZXJbU3ltYm9sLnRvUHJpbWl0aXZlXSA9IHRocm93UmVnZXhNYXJrZXI7XG5cdH1cbn1cblxudmFyICR0b1N0cmluZyA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZycpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIHJlZ2V4Q2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJztcblxubW9kdWxlLmV4cG9ydHMgPSBoYXNUb1N0cmluZ1RhZ1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0PyBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSBnT1BEKHZhbHVlLCAnbGFzdEluZGV4Jyk7XG5cdFx0dmFyIGhhc0xhc3RJbmRleERhdGFQcm9wZXJ0eSA9IGRlc2NyaXB0b3IgJiYgaGFzKGRlc2NyaXB0b3IsICd2YWx1ZScpO1xuXHRcdGlmICghaGFzTGFzdEluZGV4RGF0YVByb3BlcnR5KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdCRleGVjKHZhbHVlLCBiYWRTdHJpbmdpZmllcik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGUgPT09IGlzUmVnZXhNYXJrZXI7XG5cdFx0fVxuXHR9XG5cdDogZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkge1xuXHRcdC8vIEluIG9sZGVyIGJyb3dzZXJzLCB0eXBlb2YgcmVnZXggaW5jb3JyZWN0bHkgcmV0dXJucyAnZnVuY3Rpb24nXG5cdFx0aWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICR0b1N0cmluZyh2YWx1ZSkgPT09IHJlZ2V4Q2xhc3M7XG5cdH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8420\n")},2636:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\nvar hasSymbols = __webpack_require__(1405)();\n\nif (hasSymbols) {\n\tvar symToStr = Symbol.prototype.toString;\n\tvar symStringRegex = /^Symbol\\(.*\\)$/;\n\tvar isSymbolObject = function isRealSymbolObject(value) {\n\t\tif (typeof value.valueOf() !== 'symbol') {\n\t\t\treturn false;\n\t\t}\n\t\treturn symStringRegex.test(symToStr.call(value));\n\t};\n\n\tmodule.exports = function isSymbol(value) {\n\t\tif (typeof value === 'symbol') {\n\t\t\treturn true;\n\t\t}\n\t\tif (toStr.call(value) !== '[object Symbol]') {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\treturn isSymbolObject(value);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n} else {\n\n\tmodule.exports = function isSymbol(value) {\n\t\t// this environment does not support Symbols.\n\t\treturn false && 0;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsU0FBUyxNQUFLLElBQUksQ0FBSztBQUN2QjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9pcy1zeW1ib2wvaW5kZXguanM/ZmVjNSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxuaWYgKGhhc1N5bWJvbHMpIHtcblx0dmFyIHN5bVRvU3RyID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIHN5bVN0cmluZ1JlZ2V4ID0gL15TeW1ib2xcXCguKlxcKSQvO1xuXHR2YXIgaXNTeW1ib2xPYmplY3QgPSBmdW5jdGlvbiBpc1JlYWxTeW1ib2xPYmplY3QodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlLnZhbHVlT2YoKSAhPT0gJ3N5bWJvbCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHN5bVN0cmluZ1JlZ2V4LnRlc3Qoc3ltVG9TdHIuY2FsbCh2YWx1ZSkpO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmICh0b1N0ci5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBpc1N5bWJvbE9iamVjdCh2YWx1ZSk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcbn0gZWxzZSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuXHRcdC8vIHRoaXMgZW52aXJvbm1lbnQgZG9lcyBub3Qgc3VwcG9ydCBTeW1ib2xzLlxuXHRcdHJldHVybiBmYWxzZSAmJiB2YWx1ZTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2636\n")},631:function(module,__unused_webpack_exports,__webpack_require__){eval("var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = __webpack_require__(4654).custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n if (typeof depth === 'undefined') { depth = 0; }\n if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n return isArray(obj) ? '[Array]' : '[Object]';\n }\n\n var indent = getIndent(opts, depth);\n\n if (typeof seen === 'undefined') {\n seen = [];\n } else if (indexOf(seen, obj) >= 0) {\n return '[Circular]';\n }\n\n function inspect(value, from, noIndent) {\n if (from) {\n seen = seen.slice();\n seen.push(from);\n }\n if (noIndent) {\n var newOpts = {\n depth: opts.depth\n };\n if (has(opts, 'quoteStyle')) {\n newOpts.quoteStyle = opts.quoteStyle;\n }\n return inspect_(value, newOpts, depth + 1, seen);\n }\n return inspect_(value, opts, depth + 1, seen);\n }\n\n if (typeof obj === 'function') {\n var name = nameOf(obj);\n var keys = arrObjKeys(obj, inspect);\n return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');\n }\n if (isSymbol(obj)) {\n var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n }\n if (isElement(obj)) {\n var s = '<' + String(obj.nodeName).toLowerCase();\n var attrs = obj.attributes || [];\n for (var i = 0; i < attrs.length; i++) {\n s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n }\n s += '>';\n if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n s += '';\n return s;\n }\n if (isArray(obj)) {\n if (obj.length === 0) { return '[]'; }\n var xs = arrObjKeys(obj, inspect);\n if (indent && !singleLineValues(xs)) {\n return '[' + indentedJoin(xs, indent) + ']';\n }\n return '[ ' + xs.join(', ') + ' ]';\n }\n if (isError(obj)) {\n var parts = arrObjKeys(obj, inspect);\n if (parts.length === 0) { return '[' + String(obj) + ']'; }\n return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';\n }\n if (typeof obj === 'object' && customInspect) {\n if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {\n return obj[inspectSymbol]();\n } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n return obj.inspect();\n }\n }\n if (isMap(obj)) {\n var mapParts = [];\n mapForEach.call(obj, function (value, key) {\n mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n });\n return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n }\n if (isSet(obj)) {\n var setParts = [];\n setForEach.call(obj, function (value) {\n setParts.push(inspect(value, obj));\n });\n return collectionOf('Set', setSize.call(obj), setParts, indent);\n }\n if (isWeakMap(obj)) {\n return weakCollectionOf('WeakMap');\n }\n if (isWeakSet(obj)) {\n return weakCollectionOf('WeakSet');\n }\n if (isWeakRef(obj)) {\n return weakCollectionOf('WeakRef');\n }\n if (isNumber(obj)) {\n return markBoxed(inspect(Number(obj)));\n }\n if (isBigInt(obj)) {\n return markBoxed(inspect(bigIntValueOf.call(obj)));\n }\n if (isBoolean(obj)) {\n return markBoxed(booleanValueOf.call(obj));\n }\n if (isString(obj)) {\n return markBoxed(inspect(String(obj)));\n }\n if (!isDate(obj) && !isRegExp(obj)) {\n var ys = arrObjKeys(obj, inspect);\n var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n var protoTag = obj instanceof Object ? '' : 'null prototype';\n var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';\n var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');\n if (ys.length === 0) { return tag + '{}'; }\n if (indent) {\n return tag + '{' + indentedJoin(ys, indent) + '}';\n }\n return tag + '{ ' + ys.join(', ') + ' }';\n }\n return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '\"' : \"'\";\n return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n return String(s).replace(/\"/g, '"');\n}\n\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n if (hasShammedSymbols) {\n return obj && typeof obj === 'object' && obj instanceof Symbol;\n }\n if (typeof obj === 'symbol') {\n return true;\n }\n if (!obj || typeof obj !== 'object' || !symToString) {\n return false;\n }\n try {\n symToString.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isBigInt(obj) {\n if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n return false;\n }\n try {\n bigIntValueOf.call(obj);\n return true;\n } catch (e) {}\n return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n if (f.name) { return f.name; }\n var m = match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n if (m) { return m[1]; }\n return null;\n}\n\nfunction indexOf(xs, x) {\n if (xs.indexOf) { return xs.indexOf(x); }\n for (var i = 0, l = xs.length; i < l; i++) {\n if (xs[i] === x) { return i; }\n }\n return -1;\n}\n\nfunction isMap(x) {\n if (!mapSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n mapSize.call(x);\n try {\n setSize.call(x);\n } catch (s) {\n return true;\n }\n return x instanceof Map; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakMap(x) {\n if (!weakMapHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakMapHas.call(x, weakMapHas);\n try {\n weakSetHas.call(x, weakSetHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakRef(x) {\n if (!weakRefDeref || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakRefDeref.call(x);\n return true;\n } catch (e) {}\n return false;\n}\n\nfunction isSet(x) {\n if (!setSize || !x || typeof x !== 'object') {\n return false;\n }\n try {\n setSize.call(x);\n try {\n mapSize.call(x);\n } catch (m) {\n return true;\n }\n return x instanceof Set; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isWeakSet(x) {\n if (!weakSetHas || !x || typeof x !== 'object') {\n return false;\n }\n try {\n weakSetHas.call(x, weakSetHas);\n try {\n weakMapHas.call(x, weakMapHas);\n } catch (s) {\n return true;\n }\n return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n } catch (e) {}\n return false;\n}\n\nfunction isElement(x) {\n if (!x || typeof x !== 'object') { return false; }\n if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n return true;\n }\n return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n if (str.length > opts.maxStringLength) {\n var remaining = str.length - opts.maxStringLength;\n var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;\n }\n // eslint-disable-next-line no-control-regex\n var s = str.replace(/(['\\\\])/g, '\\\\$1').replace(/[\\x00-\\x1f]/g, lowbyte);\n return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n var n = c.charCodeAt(0);\n var x = {\n 8: 'b',\n 9: 't',\n 10: 'n',\n 12: 'f',\n 13: 'r'\n }[n];\n if (x) { return '\\\\' + x; }\n return '\\\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();\n}\n\nfunction markBoxed(str) {\n return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');\n return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n for (var i = 0; i < xs.length; i++) {\n if (indexOf(xs[i], '\\n') >= 0) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIndent(opts, depth) {\n var baseIndent;\n if (opts.indent === '\\t') {\n baseIndent = '\\t';\n } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n baseIndent = Array(opts.indent + 1).join(' ');\n } else {\n return null;\n }\n return {\n base: baseIndent,\n prev: Array(depth + 1).join(baseIndent)\n };\n}\n\nfunction indentedJoin(xs, indent) {\n if (xs.length === 0) { return ''; }\n var lineJoiner = '\\n' + indent.prev + indent.base;\n return lineJoiner + xs.join(',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n var isArr = isArray(obj);\n var xs = [];\n if (isArr) {\n xs.length = obj.length;\n for (var i = 0; i < obj.length; i++) {\n xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n }\n }\n var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n var symMap;\n if (hasShammedSymbols) {\n symMap = {};\n for (var k = 0; k < syms.length; k++) {\n symMap['$' + syms[k]] = syms[k];\n }\n }\n\n for (var key in obj) { // eslint-disable-line no-restricted-syntax\n if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n continue; // eslint-disable-line no-restricted-syntax, no-continue\n } else if ((/[^\\w$]/).test(key)) {\n xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n } else {\n xs.push(key + ': ' + inspect(obj[key], obj));\n }\n }\n if (typeof gOPS === 'function') {\n for (var j = 0; j < syms.length; j++) {\n if (isEnumerable.call(obj, syms[j])) {\n xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n }\n }\n }\n return xs;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3QtaW5zcGVjdC9pbmRleC5qcz8yNzE0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xudmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbnZhciBnUE8gPSAodHlwZW9mIFJlZmxlY3QgPT09ICdmdW5jdGlvbicgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoXG4gICAgW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICA/IGZ1bmN0aW9uIChPKSB7XG4gICAgICAgICAgICByZXR1cm4gTy5fX3Byb3RvX187IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgfVxuICAgICAgICA6IG51bGxcbik7XG5cbnZhciBpbnNwZWN0Q3VzdG9tID0gcmVxdWlyZSgnLi91dGlsLmluc3BlY3QnKS5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGluc3BlY3RDdXN0b20gJiYgaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyAhPT0gJ3VuZGVmaW5lZCcgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiBudWxsO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgKG9wdHMucXVvdGVTdHlsZSAhPT0gJ3NpbmdsZScgJiYgb3B0cy5xdW90ZVN0eWxlICE9PSAnZG91YmxlJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb25zIFwiaW5kZW50XCIgbXVzdCBiZSBcIlxcXFx0XCIsIGFuIGludGVnZXIgPiAwLCBvciBgbnVsbGAnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICByZXR1cm4gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9IHNlZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICAgIHZhciBuZXdPcHRzID0ge1xuICAgICAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhhcyhvcHRzLCAncXVvdGVTdHlsZScpKSB7XG4gICAgICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBuZXdPcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgb3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgcmV0dXJuICdbRnVuY3Rpb24nICsgKG5hbWUgPyAnOiAnICsgbmFtZSA6ICcgKGFub255bW91cyknKSArICddJyArIChrZXlzLmxlbmd0aCA+IDAgPyAnIHsgJyArIGtleXMuam9pbignLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/IFN0cmluZyhvYmopLnJlcGxhY2UoL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArIFN0cmluZyhvYmoubm9kZU5hbWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgU3RyaW5nKG9iai5ub2RlTmFtZSkudG9Mb3dlckNhc2UoKSArICc+JztcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgaWYgKG9iai5sZW5ndGggPT09IDApIHsgcmV0dXJuICdbXSc7IH1cbiAgICAgICAgdmFyIHhzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdbJyArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArICddJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1sgJyArIHhzLmpvaW4oJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgcGFydHMuam9pbignLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmpbaW5zcGVjdFN5bWJvbF0oKTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJyAmJiB0eXBlb2Ygb2JqLmluc3BlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmouaW5zcGVjdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgc2V0Rm9yRWFjaC5jYWxsKG9iaiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyB0b1N0cihvYmopLnNsaWNlKDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyBbXS5jb25jYXQoc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSkuam9pbignOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArIHlzLmpvaW4oJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBxdW90ZUNoYXIgPSAob3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZSkgPT09ICdkb3VibGUnID8gJ1wiJyA6IFwiJ1wiO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNEYXRlKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRGF0ZV0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzRXJyb3Iob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBFcnJvcl0nICYmICghdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0b1N0cmluZ1RhZyBpbiBvYmopKTsgfVxuZnVuY3Rpb24gaXNTdHJpbmcob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBTdHJpbmddJyAmJiAoIXRvU3RyaW5nVGFnIHx8ICEodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgdG9TdHJpbmdUYWcgaW4gb2JqKSk7IH1cbmZ1bmN0aW9uIGlzTnVtYmVyKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5mdW5jdGlvbiBpc0Jvb2xlYW4ob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgJiYgKCF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIHRvU3RyaW5nVGFnIGluIG9iaikpOyB9XG5cbi8vIFN5bWJvbCBhbmQgQmlnSW50IGRvIGhhdmUgU3ltYm9sLnRvU3RyaW5nVGFnIGJ5IHNwZWMsIHNvIHRoYXQgY2FuJ3QgYmUgdXNlZCB0byBlbGltaW5hdGUgZmFsc2UgcG9zaXRpdmVzXG5mdW5jdGlvbiBpc1N5bWJvbChvYmopIHtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogaW5zdGFuY2VvZiBTeW1ib2w7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3ltYm9sJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIXN5bVRvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgIWJpZ0ludFZhbHVlT2YpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBiaWdJbnRWYWx1ZU9mLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSBpbiB0aGlzOyB9O1xuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGhhc093bi5jYWxsKG9iaiwga2V5KTtcbn1cblxuZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgcmV0dXJuIG9iamVjdFRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxuZnVuY3Rpb24gbmFtZU9mKGYpIHtcbiAgICBpZiAoZi5uYW1lKSB7IHJldHVybiBmLm5hbWU7IH1cbiAgICB2YXIgbSA9IG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKHN0ci5zbGljZSgwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9IHN0ci5yZXBsYWNlKC8oWydcXFxcXSkvZywgJ1xcXFwkMScpLnJlcGxhY2UoL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyBuLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgcmV0dXJuICdPYmplY3QoJyArIHN0ciArICcpJztcbn1cblxuZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgKyAnIHsgPyB9Jztcbn1cblxuZnVuY3Rpb24gY29sbGVjdGlvbk9mKHR5cGUsIHNpemUsIGVudHJpZXMsIGluZGVudCkge1xuICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiBlbnRyaWVzLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9IEFycmF5KG9wdHMuaW5kZW50ICsgMSkuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiBBcnJheShkZXB0aCArIDEpLmpvaW4oYmFzZUluZGVudClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgIGlmICh4cy5sZW5ndGggPT09IDApIHsgcmV0dXJuICcnOyB9XG4gICAgdmFyIGxpbmVKb2luZXIgPSAnXFxuJyArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgcmV0dXJuIGxpbmVKb2luZXIgKyB4cy5qb2luKCcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCgvW15cXHckXS8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgeHMucHVzaChpbnNwZWN0KGtleSwgb2JqKSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhzLnB1c2goa2V5ICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ09QUyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChpc0VudW1lcmFibGUuY2FsbChvYmosIHN5bXNbal0pKSB7XG4gICAgICAgICAgICAgICAgeHMucHVzaCgnWycgKyBpbnNwZWN0KHN5bXNbal0pICsgJ106ICcgKyBpbnNwZWN0KG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHhzO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n")},8987:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar keysShim;\nif (!Object.keys) {\n\t// modified from https://github.com/es-shims/es5-shim\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar toStr = Object.prototype.toString;\n\tvar isArgs = __webpack_require__(1414); // eslint-disable-line global-require\n\tvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\tvar hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');\n\tvar hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n\tvar dontEnums = [\n\t\t'toString',\n\t\t'toLocaleString',\n\t\t'valueOf',\n\t\t'hasOwnProperty',\n\t\t'isPrototypeOf',\n\t\t'propertyIsEnumerable',\n\t\t'constructor'\n\t];\n\tvar equalsConstructorPrototype = function (o) {\n\t\tvar ctor = o.constructor;\n\t\treturn ctor && ctor.prototype === o;\n\t};\n\tvar excludedKeys = {\n\t\t$applicationCache: true,\n\t\t$console: true,\n\t\t$external: true,\n\t\t$frame: true,\n\t\t$frameElement: true,\n\t\t$frames: true,\n\t\t$innerHeight: true,\n\t\t$innerWidth: true,\n\t\t$onmozfullscreenchange: true,\n\t\t$onmozfullscreenerror: true,\n\t\t$outerHeight: true,\n\t\t$outerWidth: true,\n\t\t$pageXOffset: true,\n\t\t$pageYOffset: true,\n\t\t$parent: true,\n\t\t$scrollLeft: true,\n\t\t$scrollTop: true,\n\t\t$scrollX: true,\n\t\t$scrollY: true,\n\t\t$self: true,\n\t\t$webkitIndexedDB: true,\n\t\t$webkitStorageInfo: true,\n\t\t$window: true\n\t};\n\tvar hasAutomationEqualityBug = (function () {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined') { return false; }\n\t\tfor (var k in window) {\n\t\t\ttry {\n\t\t\t\tif (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tequalsConstructorPrototype(window[k]);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}());\n\tvar equalsConstructorPrototypeIfNotBuggy = function (o) {\n\t\t/* global window */\n\t\tif (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t}\n\t\ttry {\n\t\t\treturn equalsConstructorPrototype(o);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tkeysShim = function keys(object) {\n\t\tvar isObject = object !== null && typeof object === 'object';\n\t\tvar isFunction = toStr.call(object) === '[object Function]';\n\t\tvar isArguments = isArgs(object);\n\t\tvar isString = isObject && toStr.call(object) === '[object String]';\n\t\tvar theKeys = [];\n\n\t\tif (!isObject && !isFunction && !isArguments) {\n\t\t\tthrow new TypeError('Object.keys called on a non-object');\n\t\t}\n\n\t\tvar skipProto = hasProtoEnumBug && isFunction;\n\t\tif (isString && object.length > 0 && !has.call(object, 0)) {\n\t\t\tfor (var i = 0; i < object.length; ++i) {\n\t\t\t\ttheKeys.push(String(i));\n\t\t\t}\n\t\t}\n\n\t\tif (isArguments && object.length > 0) {\n\t\t\tfor (var j = 0; j < object.length; ++j) {\n\t\t\t\ttheKeys.push(String(j));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var name in object) {\n\t\t\t\tif (!(skipProto && name === 'prototype') && has.call(object, name)) {\n\t\t\t\t\ttheKeys.push(String(name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (hasDontEnumBug) {\n\t\t\tvar skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n\t\t\tfor (var k = 0; k < dontEnums.length; ++k) {\n\t\t\t\tif (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n\t\t\t\t\ttheKeys.push(dontEnums[k]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn theKeys;\n\t};\n}\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBTyxDQUFDLElBQWUsR0FBRztBQUN4QztBQUNBLDJDQUEyQyxnQkFBZ0I7QUFDM0QsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW1wbGVtZW50YXRpb24uanM/YjE4OSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8987\n")},2215:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar slice = Array.prototype.slice;\nvar isArgs = __webpack_require__(1414);\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(8987);\n\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n\tif (Object.keys) {\n\t\tvar keysWorksWithArguments = (function () {\n\t\t\t// Safari 5.0 bug\n\t\t\tvar args = Object.keys(arguments);\n\t\t\treturn args && args.length === arguments.length;\n\t\t}(1, 2));\n\t\tif (!keysWorksWithArguments) {\n\t\t\tObject.keys = function keys(object) { // eslint-disable-line func-name-matching\n\t\t\t\tif (isArgs(object)) {\n\t\t\t\t\treturn originalKeys(slice.call(object));\n\t\t\t\t}\n\t\t\t\treturn originalKeys(object);\n\t\t\t};\n\t\t}\n\t} else {\n\t\tObject.keys = keysShim;\n\t}\n\treturn Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxJQUFlOztBQUVwQztBQUNBLDZDQUE2QyxzQkFBc0IsRUFBRSxtQkFBTyxDQUFDLElBQWtCOztBQUUvRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcz9kNmM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2215\n")},1414:function(module){"use strict";eval("\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n\tvar str = toStr.call(value);\n\tvar isArgs = str === '[object Arguments]';\n\tif (!isArgs) {\n\t\tisArgs = str !== '[object Array]' &&\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof value.length === 'number' &&\n\t\t\tvalue.length >= 0 &&\n\t\t\ttoStr.call(value.callee) === '[object Function]';\n\t}\n\treturn isArgs;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQxNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanM/ZDRhYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1414\n")},3697:function(module){"use strict";eval("\n\nvar $Object = Object;\nvar $TypeError = TypeError;\n\nmodule.exports = function flags() {\n\tif (this != null && this !== $Object(this)) {\n\t\tthrow new $TypeError('RegExp.prototype.flags getter called on non-object');\n\t}\n\tvar result = '';\n\tif (this.global) {\n\t\tresult += 'g';\n\t}\n\tif (this.ignoreCase) {\n\t\tresult += 'i';\n\t}\n\tif (this.multiline) {\n\t\tresult += 'm';\n\t}\n\tif (this.dotAll) {\n\t\tresult += 's';\n\t}\n\tif (this.unicode) {\n\t\tresult += 'u';\n\t}\n\tif (this.sticky) {\n\t\tresult += 'y';\n\t}\n\treturn result;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY5Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL2ltcGxlbWVudGF0aW9uLmpzPzU3MDgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkVHlwZUVycm9yID0gVHlwZUVycm9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsYWdzKCkge1xuXHRpZiAodGhpcyAhPSBudWxsICYmIHRoaXMgIT09ICRPYmplY3QodGhpcykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUmVnRXhwLnByb3RvdHlwZS5mbGFncyBnZXR0ZXIgY2FsbGVkIG9uIG5vbi1vYmplY3QnKTtcblx0fVxuXHR2YXIgcmVzdWx0ID0gJyc7XG5cdGlmICh0aGlzLmdsb2JhbCkge1xuXHRcdHJlc3VsdCArPSAnZyc7XG5cdH1cblx0aWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuXHRcdHJlc3VsdCArPSAnaSc7XG5cdH1cblx0aWYgKHRoaXMubXVsdGlsaW5lKSB7XG5cdFx0cmVzdWx0ICs9ICdtJztcblx0fVxuXHRpZiAodGhpcy5kb3RBbGwpIHtcblx0XHRyZXN1bHQgKz0gJ3MnO1xuXHR9XG5cdGlmICh0aGlzLnVuaWNvZGUpIHtcblx0XHRyZXN1bHQgKz0gJ3UnO1xuXHR9XG5cdGlmICh0aGlzLnN0aWNreSkge1xuXHRcdHJlc3VsdCArPSAneSc7XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3697\n")},2847:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar callBind = __webpack_require__(5559);\n\nvar implementation = __webpack_require__(3697);\nvar getPolyfill = __webpack_require__(1721);\nvar shim = __webpack_require__(2753);\n\nvar flagsBound = callBind(implementation);\n\ndefine(flagsBound, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = flagsBound;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsZUFBZSxtQkFBTyxDQUFDLElBQVc7O0FBRWxDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9pbmRleC5qcz9lNzEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGZsYWdzQm91bmQgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShmbGFnc0JvdW5kLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbGFnc0JvdW5kO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2847\n")},1721:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(3697);\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar $gOPD = Object.getOwnPropertyDescriptor;\nvar $TypeError = TypeError;\n\nmodule.exports = function getPolyfill() {\n\tif (!supportsDescriptors) {\n\t\tthrow new $TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tif ((/a/mig).flags === 'gim') {\n\t\tvar descriptor = $gOPD(RegExp.prototype, 'flags');\n\t\tif (descriptor && typeof descriptor.get === 'function' && typeof (/a/).dotAll === 'boolean') {\n\t\t\treturn descriptor.get;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcyMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0MsMEJBQTBCLDZDQUFnRDtBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvcmVnZXhwLnByb3RvdHlwZS5mbGFncy9wb2x5ZmlsbC5qcz81N2VjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJykuc3VwcG9ydHNEZXNjcmlwdG9ycztcbnZhciAkZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG52YXIgJFR5cGVFcnJvciA9IFR5cGVFcnJvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0aWYgKCgvYS9taWcpLmZsYWdzID09PSAnZ2ltJykge1xuXHRcdHZhciBkZXNjcmlwdG9yID0gJGdPUEQoUmVnRXhwLnByb3RvdHlwZSwgJ2ZsYWdzJyk7XG5cdFx0aWYgKGRlc2NyaXB0b3IgJiYgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiAoL2EvKS5kb3RBbGwgPT09ICdib29sZWFuJykge1xuXHRcdFx0cmV0dXJuIGRlc2NyaXB0b3IuZ2V0O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1721\n")},2753:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar supportsDescriptors = __webpack_require__(4289).supportsDescriptors;\nvar getPolyfill = __webpack_require__(1721);\nvar gOPD = Object.getOwnPropertyDescriptor;\nvar defineProperty = Object.defineProperty;\nvar TypeErr = TypeError;\nvar getProto = Object.getPrototypeOf;\nvar regex = /a/;\n\nmodule.exports = function shimFlags() {\n\tif (!supportsDescriptors || !getProto) {\n\t\tthrow new TypeErr('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');\n\t}\n\tvar polyfill = getPolyfill();\n\tvar proto = getProto(regex);\n\tvar descriptor = gOPD(proto, 'flags');\n\tif (!descriptor || descriptor.get !== polyfill) {\n\t\tdefineProperty(proto, 'flags', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tget: polyfill\n\t\t});\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc1My5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQkFBMEIsNkNBQWdEO0FBQzFFLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9yZWdleHAucHJvdG90eXBlLmZsYWdzL3NoaW0uanM/MWM3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBzdXBwb3J0c0Rlc2NyaXB0b3JzID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKS5zdXBwb3J0c0Rlc2NyaXB0b3JzO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIGdPUEQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIFR5cGVFcnIgPSBUeXBlRXJyb3I7XG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG52YXIgcmVnZXggPSAvYS87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbUZsYWdzKCkge1xuXHRpZiAoIXN1cHBvcnRzRGVzY3JpcHRvcnMgfHwgIWdldFByb3RvKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnIoJ1JlZ0V4cC5wcm90b3R5cGUuZmxhZ3MgcmVxdWlyZXMgYSB0cnVlIEVTNSBlbnZpcm9ubWVudCB0aGF0IHN1cHBvcnRzIHByb3BlcnR5IGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0dmFyIHBvbHlmaWxsID0gZ2V0UG9seWZpbGwoKTtcblx0dmFyIHByb3RvID0gZ2V0UHJvdG8ocmVnZXgpO1xuXHR2YXIgZGVzY3JpcHRvciA9IGdPUEQocHJvdG8sICdmbGFncycpO1xuXHRpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5nZXQgIT09IHBvbHlmaWxsKSB7XG5cdFx0ZGVmaW5lUHJvcGVydHkocHJvdG8sICdmbGFncycsIHtcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdGVudW1lcmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiBwb2x5ZmlsbFxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiBwb2x5ZmlsbDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2753\n")},7478:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\nvar inspect = __webpack_require__(631);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ3OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLGNBQWMsbUJBQU8sQ0FBQyxHQUFnQjs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcz81NDAyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRXZWFrTWFwID0gR2V0SW50cmluc2ljKCclV2Vha01hcCUnLCB0cnVlKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG52YXIgJG1hcEdldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5nZXQnLCB0cnVlKTtcbnZhciAkbWFwU2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNldCcsIHRydWUpO1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG5cbi8qXG4gKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleS5cbiAqXG4gKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkXG4gKiBhZ2FpbiB3ZSBkb24ndCBuZWVkIHRvIHRyYXZlcnNlIHRoZSB3aG9sZSBsaXN0LiBCeSBkb2luZyBzbywgYWxsIHRoZSByZWNlbnRseVxuICogdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuICovXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0Zm9yICh2YXIgcHJldiA9IGxpc3QsIGN1cnI7IChjdXJyID0gcHJldi5uZXh0KSAhPT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0Y3Vyci5uZXh0ID0gbGlzdC5uZXh0O1xuXHRcdFx0bGlzdC5uZXh0ID0gY3VycjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdFx0cmV0dXJuIGN1cnI7XG5cdFx0fVxuXHR9XG59O1xuXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbnZhciBsaXN0U2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSwgdmFsdWUpIHtcblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRpZiAobm9kZSkge1xuXHRcdG5vZGUudmFsdWUgPSB2YWx1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBQcmVwZW5kIHRoZSBuZXcgbm9kZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG5cdFx0b2JqZWN0cy5uZXh0ID0geyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHRrZXk6IGtleSxcblx0XHRcdG5leHQ6IG9iamVjdHMubmV4dCxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cbn07XG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0cmV0dXJuICEhbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdHZhciAkd207XG5cdHZhciAkbTtcblx0dmFyICRvO1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEdldCgkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEdldCgkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RHZXQoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCRvKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbG9uZWx5LWlmXG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoJE1hcCkge1xuXHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCRtYXBTZXQoJG0sIGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCEkbykge1xuXHRcdFx0XHRcdC8qXG5cdFx0XHRcdFx0ICogSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlXG5cdFx0XHRcdFx0ICogdG8gc3BlY2lhbC1jYXNlIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBub2RlOiB3ZSBjYW4gYWx3YXlzIHJlZmVyIHRvXG5cdFx0XHRcdFx0ICogaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkbyA9IHsga2V5OiB7fSwgbmV4dDogbnVsbCB9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxpc3RTZXQoJG8sIGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7478\n")},9505:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar GetMethod = __webpack_require__(7364);\nvar IsRegExp = __webpack_require__(840);\nvar ToString = __webpack_require__(6846);\nvar RequireObjectCoercible = __webpack_require__(9619);\nvar callBound = __webpack_require__(1924);\nvar hasSymbols = __webpack_require__(1405)();\nvar flagsGetter = __webpack_require__(2847);\n\nvar $indexOf = callBound('String.prototype.indexOf');\n\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar getMatcher = function getMatcher(regexp) { // eslint-disable-line consistent-return\n\tvar matcherPolyfill = regexpMatchAllPolyfill();\n\tif (hasSymbols && typeof Symbol.matchAll === 'symbol') {\n\t\tvar matcher = GetMethod(regexp, Symbol.matchAll);\n\t\tif (matcher === RegExp.prototype[Symbol.matchAll] && matcher !== matcherPolyfill) {\n\t\t\treturn matcherPolyfill;\n\t\t}\n\t\treturn matcher;\n\t}\n\t// fallback for pre-Symbol.matchAll environments\n\tif (IsRegExp(regexp)) {\n\t\treturn matcherPolyfill;\n\t}\n};\n\nmodule.exports = function matchAll(regexp) {\n\tvar O = RequireObjectCoercible(this);\n\n\tif (typeof regexp !== 'undefined' && regexp !== null) {\n\t\tvar isRegExp = IsRegExp(regexp);\n\t\tif (isRegExp) {\n\t\t\t// workaround for older engines that lack RegExp.prototype.flags\n\t\t\tvar flags = 'flags' in regexp ? Get(regexp, 'flags') : flagsGetter(regexp);\n\t\t\tRequireObjectCoercible(flags);\n\t\t\tif ($indexOf(ToString(flags), 'g') < 0) {\n\t\t\t\tthrow new TypeError('matchAll requires a global regular expression');\n\t\t\t}\n\t\t}\n\n\t\tvar matcher = getMatcher(regexp);\n\t\tif (typeof matcher !== 'undefined') {\n\t\t\treturn Call(matcher, regexp, [O]);\n\t\t}\n\t}\n\n\tvar S = ToString(O);\n\t// var rx = RegExpCreate(regexp, 'g');\n\tvar rx = new RegExp(regexp, 'g');\n\treturn Call(getMatcher(rx), rx, [S]);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixXQUFXLG1CQUFPLENBQUMsR0FBdUI7QUFDMUMsVUFBVSxtQkFBTyxDQUFDLElBQXNCO0FBQ3hDLGdCQUFnQixtQkFBTyxDQUFDLElBQTRCO0FBQ3BELGVBQWUsbUJBQU8sQ0FBQyxHQUEyQjtBQUNsRCxlQUFlLG1CQUFPLENBQUMsSUFBMkI7QUFDbEQsNkJBQTZCLG1CQUFPLENBQUMsSUFBeUM7QUFDOUUsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUEsNkJBQTZCLG1CQUFPLENBQUMsSUFBNEI7O0FBRWpFLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbXBsZW1lbnRhdGlvbi5qcz9jMTdkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbGwgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0NhbGwnKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIEdldE1ldGhvZCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvR2V0TWV0aG9kJyk7XG52YXIgSXNSZWdFeHAgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0lzUmVnRXhwJyk7XG52YXIgVG9TdHJpbmcgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL1RvU3RyaW5nJyk7XG52YXIgUmVxdWlyZU9iamVjdENvZXJjaWJsZSA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xudmFyIGZsYWdzR2V0dGVyID0gcmVxdWlyZSgncmVnZXhwLnByb3RvdHlwZS5mbGFncycpO1xuXG52YXIgJGluZGV4T2YgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuaW5kZXhPZicpO1xuXG52YXIgcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsJyk7XG5cbnZhciBnZXRNYXRjaGVyID0gZnVuY3Rpb24gZ2V0TWF0Y2hlcihyZWdleHApIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHR2YXIgbWF0Y2hlclBvbHlmaWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRpZiAoaGFzU3ltYm9scyAmJiB0eXBlb2YgU3ltYm9sLm1hdGNoQWxsID09PSAnc3ltYm9sJykge1xuXHRcdHZhciBtYXRjaGVyID0gR2V0TWV0aG9kKHJlZ2V4cCwgU3ltYm9sLm1hdGNoQWxsKTtcblx0XHRpZiAobWF0Y2hlciA9PT0gUmVnRXhwLnByb3RvdHlwZVtTeW1ib2wubWF0Y2hBbGxdICYmIG1hdGNoZXIgIT09IG1hdGNoZXJQb2x5ZmlsbCkge1xuXHRcdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZXI7XG5cdH1cblx0Ly8gZmFsbGJhY2sgZm9yIHByZS1TeW1ib2wubWF0Y2hBbGwgZW52aXJvbm1lbnRzXG5cdGlmIChJc1JlZ0V4cChyZWdleHApKSB7XG5cdFx0cmV0dXJuIG1hdGNoZXJQb2x5ZmlsbDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtYXRjaEFsbChyZWdleHApIHtcblx0dmFyIE8gPSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKHRoaXMpO1xuXG5cdGlmICh0eXBlb2YgcmVnZXhwICE9PSAndW5kZWZpbmVkJyAmJiByZWdleHAgIT09IG51bGwpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBJc1JlZ0V4cChyZWdleHApO1xuXHRcdGlmIChpc1JlZ0V4cCkge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3Igb2xkZXIgZW5naW5lcyB0aGF0IGxhY2sgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xuXHRcdFx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiByZWdleHAgPyBHZXQocmVnZXhwLCAnZmxhZ3MnKSA6IGZsYWdzR2V0dGVyKHJlZ2V4cCk7XG5cdFx0XHRSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGZsYWdzKTtcblx0XHRcdGlmICgkaW5kZXhPZihUb1N0cmluZyhmbGFncyksICdnJykgPCAwKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ21hdGNoQWxsIHJlcXVpcmVzIGEgZ2xvYmFsIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHZhciBtYXRjaGVyID0gZ2V0TWF0Y2hlcihyZWdleHApO1xuXHRcdGlmICh0eXBlb2YgbWF0Y2hlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBDYWxsKG1hdGNoZXIsIHJlZ2V4cCwgW09dKTtcblx0XHR9XG5cdH1cblxuXHR2YXIgUyA9IFRvU3RyaW5nKE8pO1xuXHQvLyB2YXIgcnggPSBSZWdFeHBDcmVhdGUocmVnZXhwLCAnZycpO1xuXHR2YXIgcnggPSBuZXcgUmVnRXhwKHJlZ2V4cCwgJ2cnKTtcblx0cmV0dXJuIENhbGwoZ2V0TWF0Y2hlcihyeCksIHJ4LCBbU10pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9505\n")},4956:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar callBind = __webpack_require__(5559);\nvar define = __webpack_require__(4289);\n\nvar implementation = __webpack_require__(9505);\nvar getPolyfill = __webpack_require__(3447);\nvar shim = __webpack_require__(2376);\n\nvar boundMatchAll = callBind(implementation);\n\ndefine(boundMatchAll, {\n\tgetPolyfill: getPolyfill,\n\timplementation: implementation,\n\tshim: shim\n});\n\nmodule.exports = boundMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDk1Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixlQUFlLG1CQUFPLENBQUMsSUFBVztBQUNsQyxhQUFhLG1CQUFPLENBQUMsSUFBbUI7O0FBRXhDLHFCQUFxQixtQkFBTyxDQUFDLElBQWtCO0FBQy9DLGtCQUFrQixtQkFBTyxDQUFDLElBQVk7QUFDdEMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9pbmRleC5qcz9iMWNjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kJyk7XG52YXIgZGVmaW5lID0gcmVxdWlyZSgnZGVmaW5lLXByb3BlcnRpZXMnKTtcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xudmFyIGdldFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbCcpO1xudmFyIHNoaW0gPSByZXF1aXJlKCcuL3NoaW0nKTtcblxudmFyIGJvdW5kTWF0Y2hBbGwgPSBjYWxsQmluZChpbXBsZW1lbnRhdGlvbik7XG5cbmRlZmluZShib3VuZE1hdGNoQWxsLCB7XG5cdGdldFBvbHlmaWxsOiBnZXRQb2x5ZmlsbCxcblx0aW1wbGVtZW50YXRpb246IGltcGxlbWVudGF0aW9uLFxuXHRzaGltOiBzaGltXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBib3VuZE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4956\n")},6966:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar hasSymbols = __webpack_require__(1405)();\nvar regexpMatchAll = __webpack_require__(7201);\n\nmodule.exports = function getRegExpMatchAllPolyfill() {\n\tif (!hasSymbols || typeof Symbol.matchAll !== 'symbol' || typeof RegExp.prototype[Symbol.matchAll] !== 'function') {\n\t\treturn regexpMatchAll;\n\t}\n\treturn RegExp.prototype[Symbol.matchAll];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk2Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFhO0FBQ3RDLHFCQUFxQixtQkFBTyxDQUFDLElBQW1COztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcG9seWZpbGwtcmVnZXhwLW1hdGNoYWxsLmpzPzZjMTgiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciByZWdleHBNYXRjaEFsbCA9IHJlcXVpcmUoJy4vcmVnZXhwLW1hdGNoYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UmVnRXhwTWF0Y2hBbGxQb2x5ZmlsbCgpIHtcblx0aWYgKCFoYXNTeW1ib2xzIHx8IHR5cGVvZiBTeW1ib2wubWF0Y2hBbGwgIT09ICdzeW1ib2wnIHx8IHR5cGVvZiBSZWdFeHAucHJvdG90eXBlW1N5bWJvbC5tYXRjaEFsbF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gcmVnZXhwTWF0Y2hBbGw7XG5cdH1cblx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbU3ltYm9sLm1hdGNoQWxsXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6966\n")},3447:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar implementation = __webpack_require__(9505);\n\nmodule.exports = function getPolyfill() {\n\tif (String.prototype.matchAll) {\n\t\ttry {\n\t\t\t''.matchAll(RegExp.prototype);\n\t\t} catch (e) {\n\t\t\treturn String.prototype.matchAll;\n\t\t}\n\t}\n\treturn implementation;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzQ0Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixxQkFBcUIsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvc3RyaW5nLnByb3RvdHlwZS5tYXRjaGFsbC9wb2x5ZmlsbC5qcz9iOGExIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbCkge1xuXHRcdHRyeSB7XG5cdFx0XHQnJy5tYXRjaEFsbChSZWdFeHAucHJvdG90eXBlKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5tYXRjaEFsbDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3447\n")},7201:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// var Construct = require('es-abstract/2021/Construct');\nvar CreateRegExpStringIterator = __webpack_require__(3937);\nvar Get = __webpack_require__(1391);\nvar Set = __webpack_require__(105);\nvar SpeciesConstructor = __webpack_require__(9655);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\nvar flagsGetter = __webpack_require__(2847);\n\nvar OrigRegExp = RegExp;\n\nvar supportsConstructingWithFlags = 'flags' in RegExp.prototype;\n\nvar constructRegexWithFlags = function constructRegex(C, R) {\n\tvar matcher;\n\t// workaround for older engines that lack RegExp.prototype.flags\n\tvar flags = 'flags' in R ? Get(R, 'flags') : ToString(flagsGetter(R));\n\tif (supportsConstructingWithFlags && typeof flags === 'string') {\n\t\tmatcher = new C(R, flags);\n\t} else if (C === OrigRegExp) {\n\t\t// workaround for older engines that can not construct a RegExp with flags\n\t\tmatcher = new C(R.source, flags);\n\t} else {\n\t\tmatcher = new C(R, flags);\n\t}\n\treturn { flags: flags, matcher: matcher };\n};\n\nvar regexMatchAll = function SymbolMatchAll(string) {\n\tvar R = this;\n\tif (Type(R) !== 'Object') {\n\t\tthrow new TypeError('\"this\" value must be an Object');\n\t}\n\tvar S = ToString(string);\n\tvar C = SpeciesConstructor(R, OrigRegExp);\n\n\tvar tmp = constructRegexWithFlags(C, R);\n\t// var flags = ToString(Get(R, 'flags'));\n\tvar flags = tmp.flags;\n\t// var matcher = Construct(C, [R, flags]);\n\tvar matcher = tmp.matcher;\n\n\tvar lastIndex = ToLength(Get(R, 'lastIndex'));\n\tSet(matcher, 'lastIndex', lastIndex, true);\n\tvar global = flags.indexOf('g') > -1;\n\tvar fullUnicode = flags.indexOf('u') > -1;\n\treturn CreateRegExpStringIterator(matcher, S, global, fullUnicode);\n};\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nif (defineP && gOPD) {\n\tvar desc = gOPD(regexMatchAll, 'name');\n\tif (desc && desc.configurable) {\n\t\tdefineP(regexMatchAll, 'name', { value: '[Symbol.matchAll]' });\n\t}\n}\n\nmodule.exports = regexMatchAll;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLGlDQUFpQyxtQkFBTyxDQUFDLElBQTZDO0FBQ3RGLFVBQVUsbUJBQU8sQ0FBQyxJQUFzQjtBQUN4QyxVQUFVLG1CQUFPLENBQUMsR0FBc0I7QUFDeEMseUJBQXlCLG1CQUFPLENBQUMsSUFBcUM7QUFDdEUsZUFBZSxtQkFBTyxDQUFDLElBQTJCO0FBQ2xELGVBQWUsbUJBQU8sQ0FBQyxJQUEyQjtBQUNsRCxXQUFXLG1CQUFPLENBQUMsSUFBdUI7QUFDMUMsa0JBQWtCLG1CQUFPLENBQUMsSUFBd0I7O0FBRWxEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNEJBQTRCO0FBQy9EO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvcmVnZXhwLW1hdGNoYWxsLmpzP2ZhODkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgQ29uc3RydWN0ID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9Db25zdHJ1Y3QnKTtcbnZhciBDcmVhdGVSZWdFeHBTdHJpbmdJdGVyYXRvciA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3InKTtcbnZhciBHZXQgPSByZXF1aXJlKCdlcy1hYnN0cmFjdC8yMDIxL0dldCcpO1xudmFyIFNldCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvU2V0Jyk7XG52YXIgU3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9TcGVjaWVzQ29uc3RydWN0b3InKTtcbnZhciBUb0xlbmd0aCA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9MZW5ndGgnKTtcbnZhciBUb1N0cmluZyA9IHJlcXVpcmUoJ2VzLWFic3RyYWN0LzIwMjEvVG9TdHJpbmcnKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnZXMtYWJzdHJhY3QvMjAyMS9UeXBlJyk7XG52YXIgZmxhZ3NHZXR0ZXIgPSByZXF1aXJlKCdyZWdleHAucHJvdG90eXBlLmZsYWdzJyk7XG5cbnZhciBPcmlnUmVnRXhwID0gUmVnRXhwO1xuXG52YXIgc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgPSAnZmxhZ3MnIGluIFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyA9IGZ1bmN0aW9uIGNvbnN0cnVjdFJlZ2V4KEMsIFIpIHtcblx0dmFyIG1hdGNoZXI7XG5cdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBsYWNrIFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3Ncblx0dmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSID8gR2V0KFIsICdmbGFncycpIDogVG9TdHJpbmcoZmxhZ3NHZXR0ZXIoUikpO1xuXHRpZiAoc3VwcG9ydHNDb25zdHJ1Y3RpbmdXaXRoRmxhZ3MgJiYgdHlwZW9mIGZsYWdzID09PSAnc3RyaW5nJykge1xuXHRcdG1hdGNoZXIgPSBuZXcgQyhSLCBmbGFncyk7XG5cdH0gZWxzZSBpZiAoQyA9PT0gT3JpZ1JlZ0V4cCkge1xuXHRcdC8vIHdvcmthcm91bmQgZm9yIG9sZGVyIGVuZ2luZXMgdGhhdCBjYW4gbm90IGNvbnN0cnVjdCBhIFJlZ0V4cCB3aXRoIGZsYWdzXG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIuc291cmNlLCBmbGFncyk7XG5cdH0gZWxzZSB7XG5cdFx0bWF0Y2hlciA9IG5ldyBDKFIsIGZsYWdzKTtcblx0fVxuXHRyZXR1cm4geyBmbGFnczogZmxhZ3MsIG1hdGNoZXI6IG1hdGNoZXIgfTtcbn07XG5cbnZhciByZWdleE1hdGNoQWxsID0gZnVuY3Rpb24gU3ltYm9sTWF0Y2hBbGwoc3RyaW5nKSB7XG5cdHZhciBSID0gdGhpcztcblx0aWYgKFR5cGUoUikgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignXCJ0aGlzXCIgdmFsdWUgbXVzdCBiZSBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9IFRvU3RyaW5nKHN0cmluZyk7XG5cdHZhciBDID0gU3BlY2llc0NvbnN0cnVjdG9yKFIsIE9yaWdSZWdFeHApO1xuXG5cdHZhciB0bXAgPSBjb25zdHJ1Y3RSZWdleFdpdGhGbGFncyhDLCBSKTtcblx0Ly8gdmFyIGZsYWdzID0gVG9TdHJpbmcoR2V0KFIsICdmbGFncycpKTtcblx0dmFyIGZsYWdzID0gdG1wLmZsYWdzO1xuXHQvLyB2YXIgbWF0Y2hlciA9IENvbnN0cnVjdChDLCBbUiwgZmxhZ3NdKTtcblx0dmFyIG1hdGNoZXIgPSB0bXAubWF0Y2hlcjtcblxuXHR2YXIgbGFzdEluZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFNldChtYXRjaGVyLCAnbGFzdEluZGV4JywgbGFzdEluZGV4LCB0cnVlKTtcblx0dmFyIGdsb2JhbCA9IGZsYWdzLmluZGV4T2YoJ2cnKSA+IC0xO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBmbGFncy5pbmRleE9mKCd1JykgPiAtMTtcblx0cmV0dXJuIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKG1hdGNoZXIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpO1xufTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0dmFyIGRlc2MgPSBnT1BEKHJlZ2V4TWF0Y2hBbGwsICduYW1lJyk7XG5cdGlmIChkZXNjICYmIGRlc2MuY29uZmlndXJhYmxlKSB7XG5cdFx0ZGVmaW5lUChyZWdleE1hdGNoQWxsLCAnbmFtZScsIHsgdmFsdWU6ICdbU3ltYm9sLm1hdGNoQWxsXScgfSk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZWdleE1hdGNoQWxsO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7201\n")},2376:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar define = __webpack_require__(4289);\nvar hasSymbols = __webpack_require__(1405)();\nvar getPolyfill = __webpack_require__(3447);\nvar regexpMatchAllPolyfill = __webpack_require__(6966);\n\nvar defineP = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nmodule.exports = function shimMatchAll() {\n\tvar polyfill = getPolyfill();\n\tdefine(\n\t\tString.prototype,\n\t\t{ matchAll: polyfill },\n\t\t{ matchAll: function () { return String.prototype.matchAll !== polyfill; } }\n\t);\n\tif (hasSymbols) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tvar symbol = Symbol.matchAll || (Symbol['for'] ? Symbol['for']('Symbol.matchAll') : Symbol('Symbol.matchAll'));\n\t\tdefine(\n\t\t\tSymbol,\n\t\t\t{ matchAll: symbol },\n\t\t\t{ matchAll: function () { return Symbol.matchAll !== symbol; } }\n\t\t);\n\n\t\tif (defineP && gOPD) {\n\t\t\tvar desc = gOPD(Symbol, symbol);\n\t\t\tif (!desc || desc.configurable) {\n\t\t\t\tdefineP(Symbol, symbol, {\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t\tenumerable: false,\n\t\t\t\t\tvalue: symbol,\n\t\t\t\t\twritable: false\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tvar regexpMatchAll = regexpMatchAllPolyfill();\n\t\tvar func = {};\n\t\tfunc[symbol] = regexpMatchAll;\n\t\tvar predicate = {};\n\t\tpredicate[symbol] = function () {\n\t\t\treturn RegExp.prototype[symbol] !== regexpMatchAll;\n\t\t};\n\t\tdefine(RegExp.prototype, func, predicate);\n\t}\n\treturn polyfill;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM3Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixhQUFhLG1CQUFPLENBQUMsSUFBbUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsSUFBYTtBQUN0QyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFZO0FBQ3RDLDZCQUE2QixtQkFBTyxDQUFDLElBQTRCOztBQUVqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEIsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxrQkFBa0I7QUFDdkIsS0FBSyx3QkFBd0I7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL3N0cmluZy5wcm90b3R5cGUubWF0Y2hhbGwvc2hpbS5qcz85Yzg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmluZSA9IHJlcXVpcmUoJ2RlZmluZS1wcm9wZXJ0aWVzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcbnZhciBnZXRQb2x5ZmlsbCA9IHJlcXVpcmUoJy4vcG9seWZpbGwnKTtcbnZhciByZWdleHBNYXRjaEFsbFBvbHlmaWxsID0gcmVxdWlyZSgnLi9wb2x5ZmlsbC1yZWdleHAtbWF0Y2hhbGwnKTtcblxudmFyIGRlZmluZVAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2hpbU1hdGNoQWxsKCkge1xuXHR2YXIgcG9seWZpbGwgPSBnZXRQb2x5ZmlsbCgpO1xuXHRkZWZpbmUoXG5cdFx0U3RyaW5nLnByb3RvdHlwZSxcblx0XHR7IG1hdGNoQWxsOiBwb2x5ZmlsbCB9LFxuXHRcdHsgbWF0Y2hBbGw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwgIT09IHBvbHlmaWxsOyB9IH1cblx0KTtcblx0aWYgKGhhc1N5bWJvbHMpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1wcm9wZXJ0aWVzXG5cdFx0dmFyIHN5bWJvbCA9IFN5bWJvbC5tYXRjaEFsbCB8fCAoU3ltYm9sWydmb3InXSA/IFN5bWJvbFsnZm9yJ10oJ1N5bWJvbC5tYXRjaEFsbCcpIDogU3ltYm9sKCdTeW1ib2wubWF0Y2hBbGwnKSk7XG5cdFx0ZGVmaW5lKFxuXHRcdFx0U3ltYm9sLFxuXHRcdFx0eyBtYXRjaEFsbDogc3ltYm9sIH0sXG5cdFx0XHR7IG1hdGNoQWxsOiBmdW5jdGlvbiAoKSB7IHJldHVybiBTeW1ib2wubWF0Y2hBbGwgIT09IHN5bWJvbDsgfSB9XG5cdFx0KTtcblxuXHRcdGlmIChkZWZpbmVQICYmIGdPUEQpIHtcblx0XHRcdHZhciBkZXNjID0gZ09QRChTeW1ib2wsIHN5bWJvbCk7XG5cdFx0XHRpZiAoIWRlc2MgfHwgZGVzYy5jb25maWd1cmFibGUpIHtcblx0XHRcdFx0ZGVmaW5lUChTeW1ib2wsIHN5bWJvbCwge1xuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IHN5bWJvbCxcblx0XHRcdFx0XHR3cml0YWJsZTogZmFsc2Vcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIHJlZ2V4cE1hdGNoQWxsID0gcmVnZXhwTWF0Y2hBbGxQb2x5ZmlsbCgpO1xuXHRcdHZhciBmdW5jID0ge307XG5cdFx0ZnVuY1tzeW1ib2xdID0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0dmFyIHByZWRpY2F0ZSA9IHt9O1xuXHRcdHByZWRpY2F0ZVtzeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFJlZ0V4cC5wcm90b3R5cGVbc3ltYm9sXSAhPT0gcmVnZXhwTWF0Y2hBbGw7XG5cdFx0fTtcblx0XHRkZWZpbmUoUmVnRXhwLnByb3RvdHlwZSwgZnVuYywgcHJlZGljYXRlKTtcblx0fVxuXHRyZXR1cm4gcG9seWZpbGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2376\n")},4654:function(){},4766:function(module){eval('!function(t,e){ true?module.exports=e():0}(self,(function(){return(()=>{var t={426:(t,e,n)=>{var r=n(529);function o(t,e,n){Array.isArray(t)?t.push(e):t[n]=e}t.exports=function(t){var e,n,i,u=[];if(Array.isArray(t))n=[],e=t.length-1;else{if("object"!=typeof t||null===t)throw new TypeError("Expecting an Array or an Object, but `"+(null===t?"null":typeof t)+"` provided.");n={},i=Object.keys(t),e=i.length-1}return function n(c,a){var l,s,f,d;for(s=i?i[a]:a,Array.isArray(t[s])||(void 0===t[s]?t[s]=[]:t[s]=[t[s]]),l=0;l=e?u.push(f):n(f,a+1)}(n,0),u}},529:t=>{t.exports=function(){for(var t={},n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.r(r),n.d(r,{default:()=>X,getCssSelector:()=>Q});var t,e,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t};function i(t){return null!=t&&"object"===(void 0===t?"undefined":o(t))&&1===t.nodeType&&"object"===o(t.style)&&"object"===o(t.ownerDocument)}function u(t="unknown problem",...e){console.warn(`CssSelectorGenerator: ${t}`,...e)}!function(t){t.NONE="none",t.DESCENDANT="descendant",t.CHILD="child"}(t||(t={})),function(t){t.id="id",t.class="class",t.tag="tag",t.attribute="attribute",t.nthchild="nthchild",t.nthoftype="nthoftype"}(e||(e={}));const c={selectors:[e.id,e.class,e.tag,e.attribute],includeTag:!1,whitelist:[],blacklist:[],combineWithinSelector:!0,combineBetweenSelectors:!0,root:null,maxCombinations:Number.POSITIVE_INFINITY,maxCandidates:Number.POSITIVE_INFINITY};function a(t){return t instanceof RegExp}function l(t){return["string","function"].includes(typeof t)||a(t)}function s(t){return Array.isArray(t)?t.filter(l):[]}function f(t){const e=[Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE,Node.ELEMENT_NODE];return function(t){return t instanceof Node}(t)&&e.includes(t.nodeType)}function d(t,e){if(f(t))return t.contains(e)||u("element root mismatch","Provided root does not contain the element. This will most likely result in producing a fallback selector using element\'s real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will nto work as intended."),t;const n=e.getRootNode({composed:!1});return f(n)?(n!==document&&u("shadow root inferred","You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended."),n):e.ownerDocument.querySelector(":root")}function p(t){return"number"==typeof t?t:Number.POSITIVE_INFINITY}function m(t=[]){const[e=[],...n]=t;return 0===n.length?e:n.reduce(((t,e)=>t.filter((t=>e.includes(t)))),e)}function h(t){return[].concat(...t)}function y(t){const e=t.map((t=>{if(a(t))return e=>t.test(e);if("function"==typeof t)return e=>{const n=t(e);return"boolean"!=typeof n?(u("pattern matcher function invalid","Provided pattern matching function does not return boolean. It\'s result will be ignored.",t),!1):n};if("string"==typeof t){const e=new RegExp("^"+t.replace(/[|\\\\{}()[\\]^$+?.]/g,"\\\\$&").replace(/\\*/g,".+")+"$");return t=>e.test(t)}return u("pattern matcher invalid","Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.",t),()=>!1}));return t=>e.some((e=>e(t)))}function g(t,e,n){const r=Array.from(d(n,t[0]).querySelectorAll(e));return r.length===t.length&&t.every((t=>r.includes(t)))}function b(t,e){e=null!=e?e:function(t){return t.ownerDocument.querySelector(":root")}(t);const n=[];let r=t;for(;i(r)&&r!==e;)n.push(r),r=r.parentElement;return n}function v(t,e){return m(t.map((t=>b(t,e))))}const N={[t.NONE]:{type:t.NONE,value:""},[t.DESCENDANT]:{type:t.DESCENDANT,value:" > "},[t.CHILD]:{type:t.CHILD,value:" "}},S=new RegExp(["^$","\\\\s","^\\\\d"].join("|")),E=new RegExp(["^$","^\\\\d"].join("|")),w=[e.nthoftype,e.tag,e.id,e.class,e.attribute,e.nthchild];var x=n(426),A=n.n(x);const C=y(["class","id","ng-*"]);function O({nodeName:t}){return`[${t}]`}function T({nodeName:t,nodeValue:e}){return`[${t}=\'${Y(e)}\']`}function I({nodeName:t}){return!C(t)}function j(t){const e=Array.from(t.attributes).filter(I);return[...e.map(O),...e.map(T)]}function D(t){return(t.getAttribute("class")||"").trim().split(/\\s+/).filter((t=>!E.test(t))).map((t=>`.${Y(t)}`))}function $(t){const e=t.getAttribute("id")||"",n=`#${Y(e)}`,r=t.getRootNode({composed:!1});return!S.test(e)&&g([t],n,r)?[n]:[]}function P(t){const e=t.parentNode;if(e){const n=Array.from(e.childNodes).filter(i).indexOf(t);if(n>-1)return[`:nth-child(${n+1})`]}return[]}function R(t){return[Y(t.tagName.toLowerCase())]}function _(t){const e=[...new Set(h(t.map(R)))];return 0===e.length||e.length>1?[]:[e[0]]}function k(t){const e=_([t])[0],n=t.parentElement;if(n){const r=Array.from(n.children).filter((t=>t.tagName.toLowerCase()===e)).indexOf(t);if(r>-1)return[`${e}:nth-of-type(${r+1})`]}return[]}function M(t=[],{maxResults:e=Number.POSITIVE_INFINITY}={}){const n=[];let r=0,o=q(1);for(;o.length<=t.length&&rt[e]))),o=L(o,t.length-1);return n}function L(t=[],e=0){const n=t.length;if(0===n)return[];const r=[...t];r[n-1]+=1;for(let t=n-1;t>=0;t--)if(r[t]>e){if(0===t)return q(n+1);r[t-1]++,r[t]=r[t-1]+1}return r[n-1]>e?q(n+1):r}function q(t=1){return Array.from(Array(t).keys())}const F=":".charCodeAt(0).toString(16).toUpperCase(),V=/[ !"#$%&\'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;function Y(t=""){var e,n;return null!==(n=null===(e=null===CSS||void 0===CSS?void 0:CSS.escape)||void 0===e?void 0:e.call(CSS,t))&&void 0!==n?n:function(t=""){return t.split("").map((t=>":"===t?`\\\\${F} `:V.test(t)?`\\\\${t}`:escape(t).replace(/%/g,"\\\\"))).join("")}(t)}const B={tag:_,id:function(t){return 0===t.length||t.length>1?[]:$(t[0])},class:function(t){return m(t.map(D))},attribute:function(t){return m(t.map(j))},nthchild:function(t){return m(t.map(P))},nthoftype:function(t){return m(t.map(k))}},G={tag:R,id:$,class:D,attribute:j,nthchild:P,nthoftype:k};function W(t){return t.includes(e.tag)||t.includes(e.nthoftype)?[...t]:[...t,e.tag]}function H(t={}){const n=[...w];return t[e.tag]&&t[e.nthoftype]&&n.splice(n.indexOf(e.tag),1),n.map((e=>{return(r=t)[n=e]?r[n].join(""):"";var n,r})).join("")}function U(t,e,n="",r){const o=function(t,e){return""===e?t:function(t,e){return[...t.map((t=>e+" "+t)),...t.map((t=>e+" > "+t))]}(t,e)}(function(t,e,n){const r=h(function(t,e){return function(t){const{selectors:e,combineBetweenSelectors:n,includeTag:r,maxCandidates:o}=t,i=n?M(e,{maxResults:o}):e.map((t=>[t]));return r?i.map(W):i}(e).map((e=>function(t,e){const n={};return t.forEach((t=>{const r=e[t];r.length>0&&(n[t]=r)})),A()(n).map(H)}(e,t))).filter((t=>t.length>0))}(function(t,e){const{blacklist:n,whitelist:r,combineWithinSelector:o,maxCombinations:i}=e,u=y(n),c=y(r);return function(t){const{selectors:e,includeTag:n}=t,r=[].concat(e);return n&&!r.includes("tag")&&r.push("tag"),r}(e).reduce(((e,n)=>{const r=function(t=[],e){return t.sort(((t,n)=>{const r=e(t),o=e(n);return r&&!o?-1:!r&&o?1:0}))}(function(t=[],e,n){return t.filter((t=>n(t)||!e(t)))}(function(t,e){var n;return(null!==(n=B[e])&&void 0!==n?n:()=>[])(t)}(t,n),u,c),c);return e[n]=o?M(r,{maxResults:i}):r.map((t=>[t])),e}),{})}(t,n),n));return[...new Set(r)]}(t,r.root,r),n);for(const e of o)if(g(t,e,r.root))return e;return null}function z(t){return{value:t,include:!1}}function J({selectors:t,operator:n}){let r=[...w];t[e.tag]&&t[e.nthoftype]&&(r=r.filter((t=>t!==e.tag)));let o="";return r.forEach((e=>{(t[e]||[]).forEach((({value:t,include:e})=>{e&&(o+=t)}))})),n.value+o}function K(n){return[":root",...b(n).reverse().map((n=>{const r=function(e,n,r=t.NONE){const o={};return n.forEach((t=>{Reflect.set(o,t,function(t,e){return G[e](t)}(e,t).map(z))})),{element:e,operator:N[r],selectors:o}}(n,[e.nthchild],t.DESCENDANT);return r.selectors.nthchild.forEach((t=>{t.include=!0})),r})).map(J)].join("")}function Q(t,n={}){const r=function(t){const e=(Array.isArray(t)?t:[t]).filter(i);return[...new Set(e)]}(t),o=function(t,n={}){const r=Object.assign(Object.assign({},c),n);return{selectors:(o=r.selectors,Array.isArray(o)?o.filter((t=>{return n=e,r=t,Object.values(n).includes(r);var n,r})):[]),whitelist:s(r.whitelist),blacklist:s(r.blacklist),root:d(r.root,t),combineWithinSelector:!!r.combineWithinSelector,combineBetweenSelectors:!!r.combineBetweenSelectors,includeTag:!!r.includeTag,maxCombinations:p(r.maxCombinations),maxCandidates:p(r.maxCandidates)};var o}(r[0],n);let u="",a=o.root;function l(){return function(t,e,n="",r){if(0===t.length)return null;const o=[t.length>1?t:[],...v(t,e).map((t=>[t]))];for(const t of o){const e=U(t,0,n,r);if(e)return{foundElements:t,selector:e}}return null}(r,a,u,o)}let f=l();for(;f;){const{foundElements:t,selector:e}=f;if(g(r,e,o.root))return e;a=t[0],u=e,f=l()}return r.length>1?r.map((t=>Q(t,o))).join(", "):function(t){return t.map(K).join(", ")}(r)}const X=Q})(),r})()}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QiwwQkFBMEIsR0FBRyxvQkFBb0Isa0NBQWtDLGVBQWUsTUFBTSxnREFBZ0QsY0FBYyxtQkFBbUIsYUFBYSxvQkFBb0IsSUFBSSxFQUFFLFVBQVUsc0JBQXNCLGdCQUFnQiwyQ0FBMkMsWUFBWSxjQUFjLE9BQU8sb0JBQW9CLFlBQVksdUJBQXVCLEVBQUUsYUFBYSx1REFBdUQsU0FBUyxzQkFBc0Isc0JBQXNCLGtCQUFrQixJQUFJLFVBQVUsR0FBRyxhQUFhLGNBQWMsMENBQTBDLCtCQUErQixXQUFXLHNCQUFzQiw4QkFBOEIsZUFBZSxjQUFjLElBQUkscUNBQXFDLDhCQUE4Qix5Q0FBeUMsYUFBYSxLQUFLLG9CQUFvQixpQkFBaUIsRUFBRSxvQkFBb0IsMkNBQTJDLHNCQUFzQixxQkFBcUIsRUFBRSxzQ0FBc0MsT0FBTyxPQUFPLHdEQUF3RCw0Q0FBNEMsUUFBUSwrUUFBK1EsTUFBTSxTQUFTLGtCQUFrQixhQUFhLDRCQUE0Qiw0QkFBNEIsa0RBQWtELGtCQUFrQixtQkFBbUIsWUFBWSw0QkFBNEIsWUFBWSxVQUFVLFVBQVUsS0FBSyxFQUFFLEVBQUUsTUFBTSwyQkFBMkIsR0FBRywwQkFBMEIsaUJBQWlCLDREQUE0RCwyQkFBMkIsSUFBSSxVQUFVLE1BQU0sSUFBSSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvY3NzLXNlbGVjdG9yLWdlbmVyYXRvci9idWlsZC9pbmRleC5qcz81OWY4Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtdLGUpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpOnQuQ3NzU2VsZWN0b3JHZW5lcmF0b3I9ZSgpfShzZWxmLChmdW5jdGlvbigpe3JldHVybigoKT0+e3ZhciB0PXs0MjY6KHQsZSxuKT0+e3ZhciByPW4oNTI5KTtmdW5jdGlvbiBvKHQsZSxuKXtBcnJheS5pc0FycmF5KHQpP3QucHVzaChlKTp0W25dPWV9dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciBlLG4saSx1PVtdO2lmKEFycmF5LmlzQXJyYXkodCkpbj1bXSxlPXQubGVuZ3RoLTE7ZWxzZXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8bnVsbD09PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGluZyBhbiBBcnJheSBvciBhbiBPYmplY3QsIGJ1dCBgXCIrKG51bGw9PT10P1wibnVsbFwiOnR5cGVvZiB0KStcImAgcHJvdmlkZWQuXCIpO249e30saT1PYmplY3Qua2V5cyh0KSxlPWkubGVuZ3RoLTF9cmV0dXJuIGZ1bmN0aW9uIG4oYyxhKXt2YXIgbCxzLGYsZDtmb3Iocz1pP2lbYV06YSxBcnJheS5pc0FycmF5KHRbc10pfHwodm9pZCAwPT09dFtzXT90W3NdPVtdOnRbc109W3Rbc11dKSxsPTA7bDx0W3NdLmxlbmd0aDtsKyspbygoZD1jLGY9QXJyYXkuaXNBcnJheShkKT9bXS5jb25jYXQoZCk6cihkKSksdFtzXVtsXSxzKSxhPj1lP3UucHVzaChmKTpuKGYsYSsxKX0obiwwKSx1fX0sNTI5OnQ9Pnt0LmV4cG9ydHM9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9e30sbj0wO248YXJndW1lbnRzLmxlbmd0aDtuKyspe3ZhciByPWFyZ3VtZW50c1tuXTtmb3IodmFyIG8gaW4gcillLmNhbGwocixvKSYmKHRbb109cltvXSl9cmV0dXJuIHR9O3ZhciBlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHl9fSxlPXt9O2Z1bmN0aW9uIG4ocil7dmFyIG89ZVtyXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGk9ZVtyXT17ZXhwb3J0czp7fX07cmV0dXJuIHRbcl0oaSxpLmV4cG9ydHMsbiksaS5leHBvcnRzfW4ubj10PT57dmFyIGU9dCYmdC5fX2VzTW9kdWxlPygpPT50LmRlZmF1bHQ6KCk9PnQ7cmV0dXJuIG4uZChlLHthOmV9KSxlfSxuLmQ9KHQsZSk9Pntmb3IodmFyIHIgaW4gZSluLm8oZSxyKSYmIW4ubyh0LHIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodCxyLHtlbnVtZXJhYmxlOiEwLGdldDplW3JdfSl9LG4ubz0odCxlKT0+T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZSksbi5yPXQ9PntcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wudG9TdHJpbmdUYWcmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFN5bWJvbC50b1N0cmluZ1RhZyx7dmFsdWU6XCJNb2R1bGVcIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pfTt2YXIgcj17fTtyZXR1cm4oKCk9PntcInVzZSBzdHJpY3RcIjtuLnIociksbi5kKHIse2RlZmF1bHQ6KCk9PlgsZ2V0Q3NzU2VsZWN0b3I6KCk9PlF9KTt2YXIgdCxlLG89XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbD9cInN5bWJvbFwiOnR5cGVvZiB0fTtmdW5jdGlvbiBpKHQpe3JldHVybiBudWxsIT10JiZcIm9iamVjdFwiPT09KHZvaWQgMD09PXQ/XCJ1bmRlZmluZWRcIjpvKHQpKSYmMT09PXQubm9kZVR5cGUmJlwib2JqZWN0XCI9PT1vKHQuc3R5bGUpJiZcIm9iamVjdFwiPT09byh0Lm93bmVyRG9jdW1lbnQpfWZ1bmN0aW9uIHUodD1cInVua25vd24gcHJvYmxlbVwiLC4uLmUpe2NvbnNvbGUud2FybihgQ3NzU2VsZWN0b3JHZW5lcmF0b3I6ICR7dH1gLC4uLmUpfSFmdW5jdGlvbih0KXt0Lk5PTkU9XCJub25lXCIsdC5ERVNDRU5EQU5UPVwiZGVzY2VuZGFudFwiLHQuQ0hJTEQ9XCJjaGlsZFwifSh0fHwodD17fSkpLGZ1bmN0aW9uKHQpe3QuaWQ9XCJpZFwiLHQuY2xhc3M9XCJjbGFzc1wiLHQudGFnPVwidGFnXCIsdC5hdHRyaWJ1dGU9XCJhdHRyaWJ1dGVcIix0Lm50aGNoaWxkPVwibnRoY2hpbGRcIix0Lm50aG9mdHlwZT1cIm50aG9mdHlwZVwifShlfHwoZT17fSkpO2NvbnN0IGM9e3NlbGVjdG9yczpbZS5pZCxlLmNsYXNzLGUudGFnLGUuYXR0cmlidXRlXSxpbmNsdWRlVGFnOiExLHdoaXRlbGlzdDpbXSxibGFja2xpc3Q6W10sY29tYmluZVdpdGhpblNlbGVjdG9yOiEwLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOiEwLHJvb3Q6bnVsbCxtYXhDb21iaW5hdGlvbnM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG1heENhbmRpZGF0ZXM6TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZfTtmdW5jdGlvbiBhKHQpe3JldHVybiB0IGluc3RhbmNlb2YgUmVnRXhwfWZ1bmN0aW9uIGwodCl7cmV0dXJuW1wic3RyaW5nXCIsXCJmdW5jdGlvblwiXS5pbmNsdWRlcyh0eXBlb2YgdCl8fGEodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90LmZpbHRlcihsKTpbXX1mdW5jdGlvbiBmKHQpe2NvbnN0IGU9W05vZGUuRE9DVU1FTlRfTk9ERSxOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUsTm9kZS5FTEVNRU5UX05PREVdO3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIE5vZGV9KHQpJiZlLmluY2x1ZGVzKHQubm9kZVR5cGUpfWZ1bmN0aW9uIGQodCxlKXtpZihmKHQpKXJldHVybiB0LmNvbnRhaW5zKGUpfHx1KFwiZWxlbWVudCByb290IG1pc21hdGNoXCIsXCJQcm92aWRlZCByb290IGRvZXMgbm90IGNvbnRhaW4gdGhlIGVsZW1lbnQuIFRoaXMgd2lsbCBtb3N0IGxpa2VseSByZXN1bHQgaW4gcHJvZHVjaW5nIGEgZmFsbGJhY2sgc2VsZWN0b3IgdXNpbmcgZWxlbWVudCdzIHJlYWwgcm9vdCBub2RlLiBJZiB5b3UgcGxhbiB0byB1c2UgdGhlIHNlbGVjdG9yIHVzaW5nIHByb3ZpZGVkIHJvb3QgKGUuZy4gYHJvb3QucXVlcnlTZWxlY3RvcmApLCBpdCB3aWxsIG50byB3b3JrIGFzIGludGVuZGVkLlwiKSx0O2NvbnN0IG49ZS5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4gZihuKT8obiE9PWRvY3VtZW50JiZ1KFwic2hhZG93IHJvb3QgaW5mZXJyZWRcIixcIllvdSBkaWQgbm90IHByb3ZpZGUgYSByb290IGFuZCB0aGUgZWxlbWVudCBpcyBhIGNoaWxkIG9mIFNoYWRvdyBET00uIFRoaXMgd2lsbCBwcm9kdWNlIGEgc2VsZWN0b3IgdXNpbmcgU2hhZG93Um9vdCBhcyBhIHJvb3QuIElmIHlvdSBwbGFuIHRvIHVzZSB0aGUgc2VsZWN0b3IgdXNpbmcgZG9jdW1lbnQgYXMgYSByb290IChlLmcuIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCksIGl0IHdpbGwgbm90IHdvcmsgYXMgaW50ZW5kZWQuXCIpLG4pOmUub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9ZnVuY3Rpb24gcCh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdD90Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWX1mdW5jdGlvbiBtKHQ9W10pe2NvbnN0W2U9W10sLi4ubl09dDtyZXR1cm4gMD09PW4ubGVuZ3RoP2U6bi5yZWR1Y2UoKCh0LGUpPT50LmZpbHRlcigodD0+ZS5pbmNsdWRlcyh0KSkpKSxlKX1mdW5jdGlvbiBoKHQpe3JldHVybltdLmNvbmNhdCguLi50KX1mdW5jdGlvbiB5KHQpe2NvbnN0IGU9dC5tYXAoKHQ9PntpZihhKHQpKXJldHVybiBlPT50LnRlc3QoZSk7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdClyZXR1cm4gZT0+e2NvbnN0IG49dChlKTtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIG4/KHUoXCJwYXR0ZXJuIG1hdGNoZXIgZnVuY3Rpb24gaW52YWxpZFwiLFwiUHJvdmlkZWQgcGF0dGVybiBtYXRjaGluZyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYm9vbGVhbi4gSXQncyByZXN1bHQgd2lsbCBiZSBpZ25vcmVkLlwiLHQpLCExKTpufTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7Y29uc3QgZT1uZXcgUmVnRXhwKFwiXlwiK3QucmVwbGFjZSgvW3xcXFxce30oKVtcXF1eJCs/Ll0vZyxcIlxcXFwkJlwiKS5yZXBsYWNlKC9cXCovZyxcIi4rXCIpK1wiJFwiKTtyZXR1cm4gdD0+ZS50ZXN0KHQpfXJldHVybiB1KFwicGF0dGVybiBtYXRjaGVyIGludmFsaWRcIixcIlBhdHRlcm4gbWF0Y2hpbmcgb25seSBhY2NlcHRzIHN0cmluZ3MsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYW5kL29yIGZ1bmN0aW9ucy4gVGhpcyBpdGVtIGlzIGludmFsaWQgYW5kIHdpbGwgYmUgaWdub3JlZC5cIix0KSwoKT0+ITF9KSk7cmV0dXJuIHQ9PmUuc29tZSgoZT0+ZSh0KSkpfWZ1bmN0aW9uIGcodCxlLG4pe2NvbnN0IHI9QXJyYXkuZnJvbShkKG4sdFswXSkucXVlcnlTZWxlY3RvckFsbChlKSk7cmV0dXJuIHIubGVuZ3RoPT09dC5sZW5ndGgmJnQuZXZlcnkoKHQ9PnIuaW5jbHVkZXModCkpKX1mdW5jdGlvbiBiKHQsZSl7ZT1udWxsIT1lP2U6ZnVuY3Rpb24odCl7cmV0dXJuIHQub3duZXJEb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiOnJvb3RcIil9KHQpO2NvbnN0IG49W107bGV0IHI9dDtmb3IoO2kocikmJnIhPT1lOyluLnB1c2gocikscj1yLnBhcmVudEVsZW1lbnQ7cmV0dXJuIG59ZnVuY3Rpb24gdih0LGUpe3JldHVybiBtKHQubWFwKCh0PT5iKHQsZSkpKSl9Y29uc3QgTj17W3QuTk9ORV06e3R5cGU6dC5OT05FLHZhbHVlOlwiXCJ9LFt0LkRFU0NFTkRBTlRdOnt0eXBlOnQuREVTQ0VOREFOVCx2YWx1ZTpcIiA+IFwifSxbdC5DSElMRF06e3R5cGU6dC5DSElMRCx2YWx1ZTpcIiBcIn19LFM9bmV3IFJlZ0V4cChbXCJeJFwiLFwiXFxcXHNcIixcIl5cXFxcZFwiXS5qb2luKFwifFwiKSksRT1uZXcgUmVnRXhwKFtcIl4kXCIsXCJeXFxcXGRcIl0uam9pbihcInxcIikpLHc9W2UubnRob2Z0eXBlLGUudGFnLGUuaWQsZS5jbGFzcyxlLmF0dHJpYnV0ZSxlLm50aGNoaWxkXTt2YXIgeD1uKDQyNiksQT1uLm4oeCk7Y29uc3QgQz15KFtcImNsYXNzXCIsXCJpZFwiLFwibmctKlwiXSk7ZnVuY3Rpb24gTyh7bm9kZU5hbWU6dH0pe3JldHVybmBbJHt0fV1gfWZ1bmN0aW9uIFQoe25vZGVOYW1lOnQsbm9kZVZhbHVlOmV9KXtyZXR1cm5gWyR7dH09JyR7WShlKX0nXWB9ZnVuY3Rpb24gSSh7bm9kZU5hbWU6dH0pe3JldHVybiFDKHQpfWZ1bmN0aW9uIGoodCl7Y29uc3QgZT1BcnJheS5mcm9tKHQuYXR0cmlidXRlcykuZmlsdGVyKEkpO3JldHVyblsuLi5lLm1hcChPKSwuLi5lLm1hcChUKV19ZnVuY3Rpb24gRCh0KXtyZXR1cm4odC5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKXx8XCJcIikudHJpbSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKCh0PT4hRS50ZXN0KHQpKSkubWFwKCh0PT5gLiR7WSh0KX1gKSl9ZnVuY3Rpb24gJCh0KXtjb25zdCBlPXQuZ2V0QXR0cmlidXRlKFwiaWRcIil8fFwiXCIsbj1gIyR7WShlKX1gLHI9dC5nZXRSb290Tm9kZSh7Y29tcG9zZWQ6ITF9KTtyZXR1cm4hUy50ZXN0KGUpJiZnKFt0XSxuLHIpP1tuXTpbXX1mdW5jdGlvbiBQKHQpe2NvbnN0IGU9dC5wYXJlbnROb2RlO2lmKGUpe2NvbnN0IG49QXJyYXkuZnJvbShlLmNoaWxkTm9kZXMpLmZpbHRlcihpKS5pbmRleE9mKHQpO2lmKG4+LTEpcmV0dXJuW2A6bnRoLWNoaWxkKCR7bisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBSKHQpe3JldHVybltZKHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKV19ZnVuY3Rpb24gXyh0KXtjb25zdCBlPVsuLi5uZXcgU2V0KGgodC5tYXAoUikpKV07cmV0dXJuIDA9PT1lLmxlbmd0aHx8ZS5sZW5ndGg+MT9bXTpbZVswXV19ZnVuY3Rpb24gayh0KXtjb25zdCBlPV8oW3RdKVswXSxuPXQucGFyZW50RWxlbWVudDtpZihuKXtjb25zdCByPUFycmF5LmZyb20obi5jaGlsZHJlbikuZmlsdGVyKCh0PT50LnRhZ05hbWUudG9Mb3dlckNhc2UoKT09PWUpKS5pbmRleE9mKHQpO2lmKHI+LTEpcmV0dXJuW2Ake2V9Om50aC1vZi10eXBlKCR7cisxfSlgXX1yZXR1cm5bXX1mdW5jdGlvbiBNKHQ9W10se21heFJlc3VsdHM6ZT1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9PXt9KXtjb25zdCBuPVtdO2xldCByPTAsbz1xKDEpO2Zvcig7by5sZW5ndGg8PXQubGVuZ3RoJiZyPGU7KXIrPTEsbi5wdXNoKG8ubWFwKChlPT50W2VdKSkpLG89TChvLHQubGVuZ3RoLTEpO3JldHVybiBufWZ1bmN0aW9uIEwodD1bXSxlPTApe2NvbnN0IG49dC5sZW5ndGg7aWYoMD09PW4pcmV0dXJuW107Y29uc3Qgcj1bLi4udF07cltuLTFdKz0xO2ZvcihsZXQgdD1uLTE7dD49MDt0LS0paWYoclt0XT5lKXtpZigwPT09dClyZXR1cm4gcShuKzEpO3JbdC0xXSsrLHJbdF09clt0LTFdKzF9cmV0dXJuIHJbbi0xXT5lP3EobisxKTpyfWZ1bmN0aW9uIHEodD0xKXtyZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0KS5rZXlzKCkpfWNvbnN0IEY9XCI6XCIuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSxWPS9bICFcIiMkJSYnKClcXFtcXF17fH08PiorLC4vOz0/QF5gflxcXFxdLztmdW5jdGlvbiBZKHQ9XCJcIil7dmFyIGUsbjtyZXR1cm4gbnVsbCE9PShuPW51bGw9PT0oZT1udWxsPT09Q1NTfHx2b2lkIDA9PT1DU1M/dm9pZCAwOkNTUy5lc2NhcGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwoQ1NTLHQpKSYmdm9pZCAwIT09bj9uOmZ1bmN0aW9uKHQ9XCJcIil7cmV0dXJuIHQuc3BsaXQoXCJcIikubWFwKCh0PT5cIjpcIj09PXQ/YFxcXFwke0Z9IGA6Vi50ZXN0KHQpP2BcXFxcJHt0fWA6ZXNjYXBlKHQpLnJlcGxhY2UoLyUvZyxcIlxcXFxcIikpKS5qb2luKFwiXCIpfSh0KX1jb25zdCBCPXt0YWc6XyxpZDpmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQubGVuZ3RofHx0Lmxlbmd0aD4xP1tdOiQodFswXSl9LGNsYXNzOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKEQpKX0sYXR0cmlidXRlOmZ1bmN0aW9uKHQpe3JldHVybiBtKHQubWFwKGopKX0sbnRoY2hpbGQ6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoUCkpfSxudGhvZnR5cGU6ZnVuY3Rpb24odCl7cmV0dXJuIG0odC5tYXAoaykpfX0sRz17dGFnOlIsaWQ6JCxjbGFzczpELGF0dHJpYnV0ZTpqLG50aGNoaWxkOlAsbnRob2Z0eXBlOmt9O2Z1bmN0aW9uIFcodCl7cmV0dXJuIHQuaW5jbHVkZXMoZS50YWcpfHx0LmluY2x1ZGVzKGUubnRob2Z0eXBlKT9bLi4udF06Wy4uLnQsZS50YWddfWZ1bmN0aW9uIEgodD17fSl7Y29uc3Qgbj1bLi4ud107cmV0dXJuIHRbZS50YWddJiZ0W2UubnRob2Z0eXBlXSYmbi5zcGxpY2Uobi5pbmRleE9mKGUudGFnKSwxKSxuLm1hcCgoZT0+e3JldHVybihyPXQpW249ZV0/cltuXS5qb2luKFwiXCIpOlwiXCI7dmFyIG4scn0pKS5qb2luKFwiXCIpfWZ1bmN0aW9uIFUodCxlLG49XCJcIixyKXtjb25zdCBvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJcIj09PWU/dDpmdW5jdGlvbih0LGUpe3JldHVyblsuLi50Lm1hcCgodD0+ZStcIiBcIit0KSksLi4udC5tYXAoKHQ9PmUrXCIgPiBcIit0KSldfSh0LGUpfShmdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2NvbnN0e3NlbGVjdG9yczplLGNvbWJpbmVCZXR3ZWVuU2VsZWN0b3JzOm4saW5jbHVkZVRhZzpyLG1heENhbmRpZGF0ZXM6b309dCxpPW4/TShlLHttYXhSZXN1bHRzOm99KTplLm1hcCgodD0+W3RdKSk7cmV0dXJuIHI/aS5tYXAoVyk6aX0oZSkubWFwKChlPT5mdW5jdGlvbih0LGUpe2NvbnN0IG49e307cmV0dXJuIHQuZm9yRWFjaCgodD0+e2NvbnN0IHI9ZVt0XTtyLmxlbmd0aD4wJiYoblt0XT1yKX0pKSxBKCkobikubWFwKEgpfShlLHQpKSkuZmlsdGVyKCh0PT50Lmxlbmd0aD4wKSl9KGZ1bmN0aW9uKHQsZSl7Y29uc3R7YmxhY2tsaXN0Om4sd2hpdGVsaXN0OnIsY29tYmluZVdpdGhpblNlbGVjdG9yOm8sbWF4Q29tYmluYXRpb25zOml9PWUsdT15KG4pLGM9eShyKTtyZXR1cm4gZnVuY3Rpb24odCl7Y29uc3R7c2VsZWN0b3JzOmUsaW5jbHVkZVRhZzpufT10LHI9W10uY29uY2F0KGUpO3JldHVybiBuJiYhci5pbmNsdWRlcyhcInRhZ1wiKSYmci5wdXNoKFwidGFnXCIpLHJ9KGUpLnJlZHVjZSgoKGUsbik9Pntjb25zdCByPWZ1bmN0aW9uKHQ9W10sZSl7cmV0dXJuIHQuc29ydCgoKHQsbik9Pntjb25zdCByPWUodCksbz1lKG4pO3JldHVybiByJiYhbz8tMTohciYmbz8xOjB9KSl9KGZ1bmN0aW9uKHQ9W10sZSxuKXtyZXR1cm4gdC5maWx0ZXIoKHQ9Pm4odCl8fCFlKHQpKSl9KGZ1bmN0aW9uKHQsZSl7dmFyIG47cmV0dXJuKG51bGwhPT0obj1CW2VdKSYmdm9pZCAwIT09bj9uOigpPT5bXSkodCl9KHQsbiksdSxjKSxjKTtyZXR1cm4gZVtuXT1vP00ocix7bWF4UmVzdWx0czppfSk6ci5tYXAoKHQ9Plt0XSkpLGV9KSx7fSl9KHQsbiksbikpO3JldHVyblsuLi5uZXcgU2V0KHIpXX0odCxyLnJvb3Qsciksbik7Zm9yKGNvbnN0IGUgb2YgbylpZihnKHQsZSxyLnJvb3QpKXJldHVybiBlO3JldHVybiBudWxsfWZ1bmN0aW9uIHoodCl7cmV0dXJue3ZhbHVlOnQsaW5jbHVkZTohMX19ZnVuY3Rpb24gSih7c2VsZWN0b3JzOnQsb3BlcmF0b3I6bn0pe2xldCByPVsuLi53XTt0W2UudGFnXSYmdFtlLm50aG9mdHlwZV0mJihyPXIuZmlsdGVyKCh0PT50IT09ZS50YWcpKSk7bGV0IG89XCJcIjtyZXR1cm4gci5mb3JFYWNoKChlPT57KHRbZV18fFtdKS5mb3JFYWNoKCgoe3ZhbHVlOnQsaW5jbHVkZTplfSk9PntlJiYobys9dCl9KSl9KSksbi52YWx1ZStvfWZ1bmN0aW9uIEsobil7cmV0dXJuW1wiOnJvb3RcIiwuLi5iKG4pLnJldmVyc2UoKS5tYXAoKG49Pntjb25zdCByPWZ1bmN0aW9uKGUsbixyPXQuTk9ORSl7Y29uc3Qgbz17fTtyZXR1cm4gbi5mb3JFYWNoKCh0PT57UmVmbGVjdC5zZXQobyx0LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIEdbZV0odCl9KGUsdCkubWFwKHopKX0pKSx7ZWxlbWVudDplLG9wZXJhdG9yOk5bcl0sc2VsZWN0b3JzOm99fShuLFtlLm50aGNoaWxkXSx0LkRFU0NFTkRBTlQpO3JldHVybiByLnNlbGVjdG9ycy5udGhjaGlsZC5mb3JFYWNoKCh0PT57dC5pbmNsdWRlPSEwfSkpLHJ9KSkubWFwKEopXS5qb2luKFwiXCIpfWZ1bmN0aW9uIFEodCxuPXt9KXtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IGU9KEFycmF5LmlzQXJyYXkodCk/dDpbdF0pLmZpbHRlcihpKTtyZXR1cm5bLi4ubmV3IFNldChlKV19KHQpLG89ZnVuY3Rpb24odCxuPXt9KXtjb25zdCByPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxjKSxuKTtyZXR1cm57c2VsZWN0b3JzOihvPXIuc2VsZWN0b3JzLEFycmF5LmlzQXJyYXkobyk/by5maWx0ZXIoKHQ9PntyZXR1cm4gbj1lLHI9dCxPYmplY3QudmFsdWVzKG4pLmluY2x1ZGVzKHIpO3ZhciBuLHJ9KSk6W10pLHdoaXRlbGlzdDpzKHIud2hpdGVsaXN0KSxibGFja2xpc3Q6cyhyLmJsYWNrbGlzdCkscm9vdDpkKHIucm9vdCx0KSxjb21iaW5lV2l0aGluU2VsZWN0b3I6ISFyLmNvbWJpbmVXaXRoaW5TZWxlY3Rvcixjb21iaW5lQmV0d2VlblNlbGVjdG9yczohIXIuY29tYmluZUJldHdlZW5TZWxlY3RvcnMsaW5jbHVkZVRhZzohIXIuaW5jbHVkZVRhZyxtYXhDb21iaW5hdGlvbnM6cChyLm1heENvbWJpbmF0aW9ucyksbWF4Q2FuZGlkYXRlczpwKHIubWF4Q2FuZGlkYXRlcyl9O3ZhciBvfShyWzBdLG4pO2xldCB1PVwiXCIsYT1vLnJvb3Q7ZnVuY3Rpb24gbCgpe3JldHVybiBmdW5jdGlvbih0LGUsbj1cIlwiLHIpe2lmKDA9PT10Lmxlbmd0aClyZXR1cm4gbnVsbDtjb25zdCBvPVt0Lmxlbmd0aD4xP3Q6W10sLi4udih0LGUpLm1hcCgodD0+W3RdKSldO2Zvcihjb25zdCB0IG9mIG8pe2NvbnN0IGU9VSh0LDAsbixyKTtpZihlKXJldHVybntmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX19cmV0dXJuIG51bGx9KHIsYSx1LG8pfWxldCBmPWwoKTtmb3IoO2Y7KXtjb25zdHtmb3VuZEVsZW1lbnRzOnQsc2VsZWN0b3I6ZX09ZjtpZihnKHIsZSxvLnJvb3QpKXJldHVybiBlO2E9dFswXSx1PWUsZj1sKCl9cmV0dXJuIHIubGVuZ3RoPjE/ci5tYXAoKHQ9PlEodCxvKSkpLmpvaW4oXCIsIFwiKTpmdW5jdGlvbih0KXtyZXR1cm4gdC5tYXAoSykuam9pbihcIiwgXCIpfShyKX1jb25zdCBYPVF9KSgpLHJ9KSgpfSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4766\n')},7912:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjAvSXNBcnJheS5qcz8zNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7912\n")},4200:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar CodePointAt = __webpack_require__(2432);\nvar IsIntegralNumber = __webpack_require__(7312);\nvar Type = __webpack_require__(3633);\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-advancestringindex\n\nmodule.exports = function AdvanceStringIndex(S, index, unicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tif (!IsIntegralNumber(index) || index < 0 || index > MAX_SAFE_INTEGER) {\n\t\tthrow new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');\n\t}\n\tif (Type(unicode) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `unicode` must be a Boolean');\n\t}\n\tif (!unicode) {\n\t\treturn index + 1;\n\t}\n\tvar length = S.length;\n\tif ((index + 1) >= length) {\n\t\treturn index + 1;\n\t}\n\tvar cp = CodePointAt(S, index);\n\treturn index + cp['[[CodeUnitCount]]'];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDIwMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlO0FBQ3pDLHVCQUF1QixtQkFBTyxDQUFDLElBQW9CO0FBQ25ELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9BZHZhbmNlU3RyaW5nSW5kZXguanM/MWJmMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBDb2RlUG9pbnRBdCA9IHJlcXVpcmUoJy4vQ29kZVBvaW50QXQnKTtcbnZhciBJc0ludGVncmFsTnVtYmVyID0gcmVxdWlyZSgnLi9Jc0ludGVncmFsTnVtYmVyJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbWF4U2FmZUludGVnZXInKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMi4wLyNzZWMtYWR2YW5jZXN0cmluZ2luZGV4XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQWR2YW5jZVN0cmluZ0luZGV4KFMsIGluZGV4LCB1bmljb2RlKSB7XG5cdGlmIChUeXBlKFMpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgU2AgbXVzdCBiZSBhIFN0cmluZycpO1xuXHR9XG5cdGlmICghSXNJbnRlZ3JhbE51bWJlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gTUFYX1NBRkVfSU5URUdFUikge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgbGVuZ3RoYCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMCBhbmQgPD0gMioqNTMnKTtcblx0fVxuXHRpZiAoVHlwZSh1bmljb2RlKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGB1bmljb2RlYCBtdXN0IGJlIGEgQm9vbGVhbicpO1xuXHR9XG5cdGlmICghdW5pY29kZSkge1xuXHRcdHJldHVybiBpbmRleCArIDE7XG5cdH1cblx0dmFyIGxlbmd0aCA9IFMubGVuZ3RoO1xuXHRpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGluZGV4ICsgMTtcblx0fVxuXHR2YXIgY3AgPSBDb2RlUG9pbnRBdChTLCBpbmRleCk7XG5cdHJldHVybiBpbmRleCArIGNwWydbW0NvZGVVbml0Q291bnRdXSddO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4200\n")},581:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar callBound = __webpack_require__(1924);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsArray = __webpack_require__(6975);\n\nvar $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-call\n\nmodule.exports = function Call(F, V) {\n\tvar argumentsList = arguments.length > 2 ? arguments[2] : [];\n\tif (!IsArray(argumentsList)) {\n\t\tthrow new $TypeError('Assertion failed: optional `argumentsList`, if provided, must be a List');\n\t}\n\treturn $apply(F, V, argumentsList);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTgxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7QUFDMUMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7O0FBRTdDOztBQUVBLGNBQWMsbUJBQU8sQ0FBQyxJQUFXOztBQUVqQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DYWxsLmpzP2I4OGUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBJc0FycmF5ID0gcmVxdWlyZSgnLi9Jc0FycmF5Jyk7XG5cbnZhciAkYXBwbHkgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmFwcGx5JScsIHRydWUpIHx8IGNhbGxCb3VuZCgnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWNhbGxcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDYWxsKEYsIFYpIHtcblx0dmFyIGFyZ3VtZW50c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IFtdO1xuXHRpZiAoIUlzQXJyYXkoYXJndW1lbnRzTGlzdCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogb3B0aW9uYWwgYGFyZ3VtZW50c0xpc3RgLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBhIExpc3QnKTtcblx0fVxuXHRyZXR1cm4gJGFwcGx5KEYsIFYsIGFyZ3VtZW50c0xpc3QpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///581\n")},2432:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar callBound = __webpack_require__(1924);\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\nvar Type = __webpack_require__(3633);\nvar UTF16SurrogatePairToCodePoint = __webpack_require__(4857);\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $charCodeAt = callBound('String.prototype.charCodeAt');\n\n// https://ecma-international.org/ecma-262/12.0/#sec-codepointat\n\nmodule.exports = function CodePointAt(string, position) {\n\tif (Type(string) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `string` must be a String');\n\t}\n\tvar size = string.length;\n\tif (position < 0 || position >= size) {\n\t\tthrow new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');\n\t}\n\tvar first = $charCodeAt(string, position);\n\tvar cp = $charAt(string, position);\n\tvar firstIsLeading = isLeadingSurrogate(first);\n\tvar firstIsTrailing = isTrailingSurrogate(first);\n\tif (!firstIsLeading && !firstIsTrailing) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': false\n\t\t};\n\t}\n\tif (firstIsTrailing || (position + 1 === size)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\tvar second = $charCodeAt(string, position + 1);\n\tif (!isTrailingSurrogate(second)) {\n\t\treturn {\n\t\t\t'[[CodePoint]]': cp,\n\t\t\t'[[CodeUnitCount]]': 1,\n\t\t\t'[[IsUnpairedSurrogate]]': true\n\t\t};\n\t}\n\n\treturn {\n\t\t'[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),\n\t\t'[[CodeUnitCount]]': 2,\n\t\t'[[IsUnpairedSurrogate]]': false\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCO0FBQzdDLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixvQ0FBb0MsbUJBQU8sQ0FBQyxJQUFpQzs7QUFFN0U7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ29kZVBvaW50QXQuanM/NmRiNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBVVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludCA9IHJlcXVpcmUoJy4vVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQnKTtcblxudmFyICRjaGFyQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckF0Jyk7XG52YXIgJGNoYXJDb2RlQXQgPSBjYWxsQm91bmQoJ1N0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdCcpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvMTIuMC8jc2VjLWNvZGVwb2ludGF0XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gQ29kZVBvaW50QXQoc3RyaW5nLCBwb3NpdGlvbikge1xuXHRpZiAoVHlwZShzdHJpbmcpICE9PSAnU3RyaW5nJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgc3RyaW5nYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIHNpemUgPSBzdHJpbmcubGVuZ3RoO1xuXHRpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID49IHNpemUpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYHBvc2l0aW9uYCBtdXN0IGJlID49IDAsIGFuZCA8IHRoZSBsZW5ndGggb2YgYHN0cmluZ2AnKTtcblx0fVxuXHR2YXIgZmlyc3QgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGNwID0gJGNoYXJBdChzdHJpbmcsIHBvc2l0aW9uKTtcblx0dmFyIGZpcnN0SXNMZWFkaW5nID0gaXNMZWFkaW5nU3Vycm9nYXRlKGZpcnN0KTtcblx0dmFyIGZpcnN0SXNUcmFpbGluZyA9IGlzVHJhaWxpbmdTdXJyb2dhdGUoZmlyc3QpO1xuXHRpZiAoIWZpcnN0SXNMZWFkaW5nICYmICFmaXJzdElzVHJhaWxpbmcpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0J1tbQ29kZVBvaW50XV0nOiBjcCxcblx0XHRcdCdbW0NvZGVVbml0Q291bnRdXSc6IDEsXG5cdFx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHRcdH07XG5cdH1cblx0aWYgKGZpcnN0SXNUcmFpbGluZyB8fCAocG9zaXRpb24gKyAxID09PSBzaXplKSkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQnW1tDb2RlUG9pbnRdXSc6IGNwLFxuXHRcdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMSxcblx0XHRcdCdbW0lzVW5wYWlyZWRTdXJyb2dhdGVdXSc6IHRydWVcblx0XHR9O1xuXHR9XG5cdHZhciBzZWNvbmQgPSAkY2hhckNvZGVBdChzdHJpbmcsIHBvc2l0aW9uICsgMSk7XG5cdGlmICghaXNUcmFpbGluZ1N1cnJvZ2F0ZShzZWNvbmQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdCdbW0NvZGVQb2ludF1dJzogY3AsXG5cdFx0XHQnW1tDb2RlVW5pdENvdW50XV0nOiAxLFxuXHRcdFx0J1tbSXNVbnBhaXJlZFN1cnJvZ2F0ZV1dJzogdHJ1ZVxuXHRcdH07XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdCdbW0NvZGVQb2ludF1dJzogVVRGMTZTdXJyb2dhdGVQYWlyVG9Db2RlUG9pbnQoZmlyc3QsIHNlY29uZCksXG5cdFx0J1tbQ29kZVVuaXRDb3VudF1dJzogMixcblx0XHQnW1tJc1VucGFpcmVkU3Vycm9nYXRlXV0nOiBmYWxzZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2432\n")},2658:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject\n\nmodule.exports = function CreateIterResultObject(value, done) {\n\tif (Type(done) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: Type(done) is not Boolean');\n\t}\n\treturn {\n\t\tvalue: value,\n\t\tdone: done\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QuanM/ZmI1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlaXRlcnJlc3VsdG9iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodmFsdWUsIGRvbmUpIHtcblx0aWYgKFR5cGUoZG9uZSkgIT09ICdCb29sZWFuJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKGRvbmUpIGlzIG5vdCBCb29sZWFuJyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0ZG9uZTogZG9uZVxuXHR9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2658\n")},7730:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-createmethodproperty\n\nmodule.exports = function CreateMethodProperty(O, P, V) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar newDesc = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': false,\n\t\t'[[Value]]': V,\n\t\t'[[Writable]]': true\n\t};\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tnewDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzczMC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9DcmVhdGVNZXRob2RQcm9wZXJ0eS5qcz9mMGYzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtY3JlYXRlbWV0aG9kcHJvcGVydHlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBDcmVhdGVNZXRob2RQcm9wZXJ0eShPLCBQLCBWKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHR2YXIgbmV3RGVzYyA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogZmFsc2UsXG5cdFx0J1tbVmFsdWVdXSc6IFYsXG5cdFx0J1tbV3JpdGFibGVdXSc6IHRydWVcblx0fTtcblx0cmV0dXJuIERlZmluZU93blByb3BlcnR5KFxuXHRcdElzRGF0YURlc2NyaXB0b3IsXG5cdFx0U2FtZVZhbHVlLFxuXHRcdEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IsXG5cdFx0Tyxcblx0XHRQLFxuXHRcdG5ld0Rlc2Ncblx0KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7730\n")},3937:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\nvar hasSymbols = __webpack_require__(1405)();\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nvar AdvanceStringIndex = __webpack_require__(4200);\nvar CreateIterResultObject = __webpack_require__(2658);\nvar CreateMethodProperty = __webpack_require__(7730);\nvar Get = __webpack_require__(1391);\nvar OrdinaryObjectCreate = __webpack_require__(953);\nvar RegExpExec = __webpack_require__(6258);\nvar Set = __webpack_require__(105);\nvar ToLength = __webpack_require__(8305);\nvar ToString = __webpack_require__(6846);\nvar Type = __webpack_require__(3633);\n\nvar SLOT = __webpack_require__(9496);\n\nvar RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) {\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('`S` must be a string');\n\t}\n\tif (Type(global) !== 'Boolean') {\n\t\tthrow new $TypeError('`global` must be a boolean');\n\t}\n\tif (Type(fullUnicode) !== 'Boolean') {\n\t\tthrow new $TypeError('`fullUnicode` must be a boolean');\n\t}\n\tSLOT.set(this, '[[IteratingRegExp]]', R);\n\tSLOT.set(this, '[[IteratedString]]', S);\n\tSLOT.set(this, '[[Global]]', global);\n\tSLOT.set(this, '[[Unicode]]', fullUnicode);\n\tSLOT.set(this, '[[Done]]', false);\n};\n\nif (IteratorPrototype) {\n\tRegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype);\n}\n\nvar RegExpStringIteratorNext = function next() {\n\tvar O = this; // eslint-disable-line no-invalid-this\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('receiver must be an object');\n\t}\n\tif (\n\t\t!(O instanceof RegExpStringIterator)\n || !SLOT.has(O, '[[IteratingRegExp]]')\n || !SLOT.has(O, '[[IteratedString]]')\n || !SLOT.has(O, '[[Global]]')\n || !SLOT.has(O, '[[Unicode]]')\n || !SLOT.has(O, '[[Done]]')\n\t) {\n\t\tthrow new $TypeError('\"this\" value must be a RegExpStringIterator instance');\n\t}\n\tif (SLOT.get(O, '[[Done]]')) {\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tvar R = SLOT.get(O, '[[IteratingRegExp]]');\n\tvar S = SLOT.get(O, '[[IteratedString]]');\n\tvar global = SLOT.get(O, '[[Global]]');\n\tvar fullUnicode = SLOT.get(O, '[[Unicode]]');\n\tvar match = RegExpExec(R, S);\n\tif (match === null) {\n\t\tSLOT.set(O, '[[Done]]', true);\n\t\treturn CreateIterResultObject(undefined, true);\n\t}\n\tif (global) {\n\t\tvar matchStr = ToString(Get(match, '0'));\n\t\tif (matchStr === '') {\n\t\t\tvar thisIndex = ToLength(Get(R, 'lastIndex'));\n\t\t\tvar nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode);\n\t\t\tSet(R, 'lastIndex', nextIndex, true);\n\t\t}\n\t\treturn CreateIterResultObject(match, false);\n\t}\n\tSLOT.set(O, '[[Done]]', true);\n\treturn CreateIterResultObject(match, false);\n};\nCreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext);\n\nif (hasSymbols) {\n\tif (Symbol.toStringTag) {\n\t\tif ($defineProperty) {\n\t\t\t$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: 'RegExp String Iterator',\n\t\t\t\twritable: false\n\t\t\t});\n\t\t} else {\n\t\t\tRegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator';\n\t\t}\n\t}\n\n\tif (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') {\n\t\tvar iteratorFn = function SymbolIterator() {\n\t\t\treturn this;\n\t\t};\n\t\tCreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn);\n\t}\n}\n\n// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator\nmodule.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) {\n\t// assert R.global === global && R.unicode === fullUnicode?\n\treturn new RegExpStringIterator(R, S, global, fullUnicode);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkzNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlO0FBQzFDLGlCQUFpQixtQkFBTyxDQUFDLElBQWE7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsbUJBQU8sQ0FBQyxJQUFzQjtBQUN2RCw2QkFBNkIsbUJBQU8sQ0FBQyxJQUEwQjtBQUMvRCwyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUF3QjtBQUMzRCxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLFVBQVUsbUJBQU8sQ0FBQyxHQUFPO0FBQ3pCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxJQUFZO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQixXQUFXLG1CQUFPLENBQUMsSUFBZTs7QUFFbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvQ3JlYXRlUmVnRXhwU3RyaW5nSXRlcmF0b3IuanM/YjMwZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzJykoKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBHZXRJbnRyaW5zaWMoJyVJdGVyYXRvclByb3RvdHlwZSUnLCB0cnVlKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QuZGVmaW5lUHJvcGVydHklJywgdHJ1ZSk7XG5cbnZhciBBZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL0FkdmFuY2VTdHJpbmdJbmRleCcpO1xudmFyIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QgPSByZXF1aXJlKCcuL0NyZWF0ZUl0ZXJSZXN1bHRPYmplY3QnKTtcbnZhciBDcmVhdGVNZXRob2RQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ3JlYXRlTWV0aG9kUHJvcGVydHknKTtcbnZhciBHZXQgPSByZXF1aXJlKCcuL0dldCcpO1xudmFyIE9yZGluYXJ5T2JqZWN0Q3JlYXRlID0gcmVxdWlyZSgnLi9PcmRpbmFyeU9iamVjdENyZWF0ZScpO1xudmFyIFJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL1JlZ0V4cEV4ZWMnKTtcbnZhciBTZXQgPSByZXF1aXJlKCcuL1NldCcpO1xudmFyIFRvTGVuZ3RoID0gcmVxdWlyZSgnLi9Ub0xlbmd0aCcpO1xudmFyIFRvU3RyaW5nID0gcmVxdWlyZSgnLi9Ub1N0cmluZycpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIFNMT1QgPSByZXF1aXJlKCdpbnRlcm5hbC1zbG90Jyk7XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BTYCBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cdH1cblx0aWYgKFR5cGUoZ2xvYmFsKSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2BnbG9iYWxgIG11c3QgYmUgYSBib29sZWFuJyk7XG5cdH1cblx0aWYgKFR5cGUoZnVsbFVuaWNvZGUpICE9PSAnQm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYGZ1bGxVbmljb2RlYCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJywgUik7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0l0ZXJhdGVkU3RyaW5nXV0nLCBTKTtcblx0U0xPVC5zZXQodGhpcywgJ1tbR2xvYmFsXV0nLCBnbG9iYWwpO1xuXHRTTE9ULnNldCh0aGlzLCAnW1tVbmljb2RlXV0nLCBmdWxsVW5pY29kZSk7XG5cdFNMT1Quc2V0KHRoaXMsICdbW0RvbmVdXScsIGZhbHNlKTtcbn07XG5cbmlmIChJdGVyYXRvclByb3RvdHlwZSkge1xuXHRSZWdFeHBTdHJpbmdJdGVyYXRvci5wcm90b3R5cGUgPSBPcmRpbmFyeU9iamVjdENyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG59XG5cbnZhciBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuXHR2YXIgTyA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdyZWNlaXZlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHR9XG5cdGlmIChcblx0XHQhKE8gaW5zdGFuY2VvZiBSZWdFeHBTdHJpbmdJdGVyYXRvcilcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGluZ1JlZ0V4cF1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0l0ZXJhdGVkU3RyaW5nXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbR2xvYmFsXV0nKVxuICAgICAgICB8fCAhU0xPVC5oYXMoTywgJ1tbVW5pY29kZV1dJylcbiAgICAgICAgfHwgIVNMT1QuaGFzKE8sICdbW0RvbmVdXScpXG5cdCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdcInRoaXNcIiB2YWx1ZSBtdXN0IGJlIGEgUmVnRXhwU3RyaW5nSXRlcmF0b3IgaW5zdGFuY2UnKTtcblx0fVxuXHRpZiAoU0xPVC5nZXQoTywgJ1tbRG9uZV1dJykpIHtcblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdCh1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHZhciBSID0gU0xPVC5nZXQoTywgJ1tbSXRlcmF0aW5nUmVnRXhwXV0nKTtcblx0dmFyIFMgPSBTTE9ULmdldChPLCAnW1tJdGVyYXRlZFN0cmluZ11dJyk7XG5cdHZhciBnbG9iYWwgPSBTTE9ULmdldChPLCAnW1tHbG9iYWxdXScpO1xuXHR2YXIgZnVsbFVuaWNvZGUgPSBTTE9ULmdldChPLCAnW1tVbmljb2RlXV0nKTtcblx0dmFyIG1hdGNoID0gUmVnRXhwRXhlYyhSLCBTKTtcblx0aWYgKG1hdGNoID09PSBudWxsKSB7XG5cdFx0U0xPVC5zZXQoTywgJ1tbRG9uZV1dJywgdHJ1ZSk7XG5cdFx0cmV0dXJuIENyZWF0ZUl0ZXJSZXN1bHRPYmplY3QodW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRpZiAoZ2xvYmFsKSB7XG5cdFx0dmFyIG1hdGNoU3RyID0gVG9TdHJpbmcoR2V0KG1hdGNoLCAnMCcpKTtcblx0XHRpZiAobWF0Y2hTdHIgPT09ICcnKSB7XG5cdFx0XHR2YXIgdGhpc0luZGV4ID0gVG9MZW5ndGgoR2V0KFIsICdsYXN0SW5kZXgnKSk7XG5cdFx0XHR2YXIgbmV4dEluZGV4ID0gQWR2YW5jZVN0cmluZ0luZGV4KFMsIHRoaXNJbmRleCwgZnVsbFVuaWNvZGUpO1xuXHRcdFx0U2V0KFIsICdsYXN0SW5kZXgnLCBuZXh0SW5kZXgsIHRydWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xuXHR9XG5cdFNMT1Quc2V0KE8sICdbW0RvbmVdXScsIHRydWUpO1xuXHRyZXR1cm4gQ3JlYXRlSXRlclJlc3VsdE9iamVjdChtYXRjaCwgZmFsc2UpO1xufTtcbkNyZWF0ZU1ldGhvZFByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgJ25leHQnLCBSZWdFeHBTdHJpbmdJdGVyYXRvck5leHQpO1xuXG5pZiAoaGFzU3ltYm9scykge1xuXHRpZiAoU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0aWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHRcdFx0JGRlZmluZVByb3BlcnR5KFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiAnUmVnRXhwIFN0cmluZyBJdGVyYXRvcicsXG5cdFx0XHRcdHdyaXRhYmxlOiBmYWxzZVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wudG9TdHJpbmdUYWddID0gJ1JlZ0V4cCBTdHJpbmcgSXRlcmF0b3InO1xuXHRcdH1cblx0fVxuXG5cdGlmIChTeW1ib2wuaXRlcmF0b3IgJiYgdHlwZW9mIFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIGl0ZXJhdG9yRm4gPSBmdW5jdGlvbiBTeW1ib2xJdGVyYXRvcigpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH07XG5cdFx0Q3JlYXRlTWV0aG9kUHJvcGVydHkoUmVnRXhwU3RyaW5nSXRlcmF0b3IucHJvdG90eXBlLCBTeW1ib2wuaXRlcmF0b3IsIGl0ZXJhdG9yRm4pO1xuXHR9XG59XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWNyZWF0ZXJlZ2V4cHN0cmluZ2l0ZXJhdG9yXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENyZWF0ZVJlZ0V4cFN0cmluZ0l0ZXJhdG9yKFIsIFMsIGdsb2JhbCwgZnVsbFVuaWNvZGUpIHtcblx0Ly8gYXNzZXJ0IFIuZ2xvYmFsID09PSBnbG9iYWwgJiYgUi51bmljb2RlID09PSBmdWxsVW5pY29kZT9cblx0cmV0dXJuIG5ldyBSZWdFeHBTdHJpbmdJdGVyYXRvcihSLCBTLCBnbG9iYWwsIGZ1bGxVbmljb2RlKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3937\n")},3950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar isPropertyDescriptor = __webpack_require__(2435);\nvar DefineOwnProperty = __webpack_require__(3682);\n\nvar FromPropertyDescriptor = __webpack_require__(8334);\nvar IsAccessorDescriptor = __webpack_require__(9527);\nvar IsDataDescriptor = __webpack_require__(3746);\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar ToPropertyDescriptor = __webpack_require__(9916);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow\n\nmodule.exports = function DefinePropertyOrThrow(O, P, desc) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\tvar Desc = isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, desc) ? desc : ToPropertyDescriptor(desc);\n\tif (!isPropertyDescriptor({\n\t\tType: Type,\n\t\tIsDataDescriptor: IsDataDescriptor,\n\t\tIsAccessorDescriptor: IsAccessorDescriptor\n\t}, Desc)) {\n\t\tthrow new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');\n\t}\n\n\treturn DefineOwnProperty(\n\t\tIsDataDescriptor,\n\t\tSameValue,\n\t\tFromPropertyDescriptor,\n\t\tO,\n\t\tP,\n\t\tDesc\n\t);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSwyQkFBMkIsbUJBQU8sQ0FBQyxJQUFpQztBQUNwRSx3QkFBd0IsbUJBQU8sQ0FBQyxJQUE4Qjs7QUFFOUQsNkJBQTZCLG1CQUFPLENBQUMsSUFBMEI7QUFDL0QsMkJBQTJCLG1CQUFPLENBQUMsSUFBd0I7QUFDM0QsdUJBQXVCLG1CQUFPLENBQUMsSUFBb0I7QUFDbkQsb0JBQW9CLG1CQUFPLENBQUMsSUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsR0FBYTtBQUNyQywyQkFBMkIsbUJBQU8sQ0FBQyxJQUF3QjtBQUMzRCxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0RlZmluZVByb3BlcnR5T3JUaHJvdy5qcz82OTY3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpc1Byb3BlcnR5RGVzY3JpcHRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBEZWZpbmVPd25Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvRGVmaW5lT3duUHJvcGVydHknKTtcblxudmFyIEZyb21Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL0Zyb21Qcm9wZXJ0eURlc2NyaXB0b3InKTtcbnZhciBJc0FjY2Vzc29yRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vSXNBY2Nlc3NvckRlc2NyaXB0b3InKTtcbnZhciBJc0RhdGFEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9Jc0RhdGFEZXNjcmlwdG9yJyk7XG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVG9Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL1RvUHJvcGVydHlEZXNjcmlwdG9yJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZGVmaW5lcHJvcGVydHlvcnRocm93XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lUHJvcGVydHlPclRocm93KE8sIFAsIGRlc2MpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IFR5cGUoTykgaXMgbm90IE9iamVjdCcpO1xuXHR9XG5cblx0aWYgKCFJc1Byb3BlcnR5S2V5KFApKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IElzUHJvcGVydHlLZXkoUCkgaXMgbm90IHRydWUnKTtcblx0fVxuXG5cdHZhciBEZXNjID0gaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgZGVzYykgPyBkZXNjIDogVG9Qcm9wZXJ0eURlc2NyaXB0b3IoZGVzYyk7XG5cdGlmICghaXNQcm9wZXJ0eURlc2NyaXB0b3Ioe1xuXHRcdFR5cGU6IFR5cGUsXG5cdFx0SXNEYXRhRGVzY3JpcHRvcjogSXNEYXRhRGVzY3JpcHRvcixcblx0XHRJc0FjY2Vzc29yRGVzY3JpcHRvcjogSXNBY2Nlc3NvckRlc2NyaXB0b3Jcblx0fSwgRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogRGVzYyBpcyBub3QgYSB2YWxpZCBQcm9wZXJ0eSBEZXNjcmlwdG9yJyk7XG5cdH1cblxuXHRyZXR1cm4gRGVmaW5lT3duUHJvcGVydHkoXG5cdFx0SXNEYXRhRGVzY3JpcHRvcixcblx0XHRTYW1lVmFsdWUsXG5cdFx0RnJvbVByb3BlcnR5RGVzY3JpcHRvcixcblx0XHRPLFxuXHRcdFAsXG5cdFx0RGVzY1xuXHQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3950\n")},8334:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor\n\nmodule.exports = function FromPropertyDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn Desc;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tvar obj = {};\n\tif ('[[Value]]' in Desc) {\n\t\tobj.value = Desc['[[Value]]'];\n\t}\n\tif ('[[Writable]]' in Desc) {\n\t\tobj.writable = Desc['[[Writable]]'];\n\t}\n\tif ('[[Get]]' in Desc) {\n\t\tobj.get = Desc['[[Get]]'];\n\t}\n\tif ('[[Set]]' in Desc) {\n\t\tobj.set = Desc['[[Set]]'];\n\t}\n\tif ('[[Enumerable]]' in Desc) {\n\t\tobj.enumerable = Desc['[[Enumerable]]'];\n\t}\n\tif ('[[Configurable]]' in Desc) {\n\t\tobj.configurable = Desc['[[Configurable]]'];\n\t}\n\treturn obj;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMzNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFcEQsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Gcm9tUHJvcGVydHlEZXNjcmlwdG9yLmpzP2E4ZjciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWZyb21wcm9wZXJ0eWRlc2NyaXB0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKERlc2MpIHtcblx0aWYgKHR5cGVvZiBEZXNjID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiBEZXNjO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHR2YXIgb2JqID0ge307XG5cdGlmICgnW1tWYWx1ZV1dJyBpbiBEZXNjKSB7XG5cdFx0b2JqLnZhbHVlID0gRGVzY1snW1tWYWx1ZV1dJ107XG5cdH1cblx0aWYgKCdbW1dyaXRhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmoud3JpdGFibGUgPSBEZXNjWydbW1dyaXRhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbR2V0XV0nIGluIERlc2MpIHtcblx0XHRvYmouZ2V0ID0gRGVzY1snW1tHZXRdXSddO1xuXHR9XG5cdGlmICgnW1tTZXRdXScgaW4gRGVzYykge1xuXHRcdG9iai5zZXQgPSBEZXNjWydbW1NldF1dJ107XG5cdH1cblx0aWYgKCdbW0VudW1lcmFibGVdXScgaW4gRGVzYykge1xuXHRcdG9iai5lbnVtZXJhYmxlID0gRGVzY1snW1tFbnVtZXJhYmxlXV0nXTtcblx0fVxuXHRpZiAoJ1tbQ29uZmlndXJhYmxlXV0nIGluIERlc2MpIHtcblx0XHRvYmouY29uZmlndXJhYmxlID0gRGVzY1snW1tDb25maWd1cmFibGVdXSddO1xuXHR9XG5cdHJldHVybiBvYmo7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8334\n")},1391:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar inspect = __webpack_require__(631);\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar Type = __webpack_require__(3633);\n\n/**\n * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p\n * 1. Assert: Type(O) is Object.\n * 2. Assert: IsPropertyKey(P) is true.\n * 3. Return O.[[Get]](P, O).\n */\n\nmodule.exports = function Get(O, P) {\n\t// 7.3.1.1\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\t// 7.3.1.2\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));\n\t}\n\t// 7.3.1.3\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM5MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxjQUFjLG1CQUFPLENBQUMsR0FBZ0I7O0FBRXRDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0dldC5qcz83NzYwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8qKlxuICogNy4zLjEgR2V0IChPLCBQKSAtIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1nZXQtby1wXG4gKiAxLiBBc3NlcnQ6IFR5cGUoTykgaXMgT2JqZWN0LlxuICogMi4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAzLiBSZXR1cm4gTy5bW0dldF1dKFAsIE8pLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gR2V0KE8sIFApIHtcblx0Ly8gNy4zLjEuMVxuXHRpZiAoVHlwZShPKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogVHlwZShPKSBpcyBub3QgT2JqZWN0Jyk7XG5cdH1cblx0Ly8gNy4zLjEuMlxuXHRpZiAoIUlzUHJvcGVydHlLZXkoUCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogSXNQcm9wZXJ0eUtleShQKSBpcyBub3QgdHJ1ZSwgZ290ICcgKyBpbnNwZWN0KFApKTtcblx0fVxuXHQvLyA3LjMuMS4zXG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1391\n")},7364:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar GetV = __webpack_require__(8509);\nvar IsCallable = __webpack_require__(1787);\nvar IsPropertyKey = __webpack_require__(4305);\n\n/**\n * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let func be GetV(O, P).\n * 3. ReturnIfAbrupt(func).\n * 4. If func is either undefined or null, return undefined.\n * 5. If IsCallable(func) is false, throw a TypeError exception.\n * 6. Return func.\n */\n\nmodule.exports = function GetMethod(O, P) {\n\t// 7.3.9.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.9.2\n\tvar func = GetV(O, P);\n\n\t// 7.3.9.4\n\tif (func == null) {\n\t\treturn void 0;\n\t}\n\n\t// 7.3.9.5\n\tif (!IsCallable(func)) {\n\t\tthrow new $TypeError(P + 'is not a function');\n\t}\n\n\t// 7.3.9.6\n\treturn func;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzM2NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxXQUFXLG1CQUFPLENBQUMsSUFBUTtBQUMzQixpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjO0FBQ3ZDLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRNZXRob2QuanM/Yjg2MiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgR2V0ViA9IHJlcXVpcmUoJy4vR2V0VicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcbnZhciBJc1Byb3BlcnR5S2V5ID0gcmVxdWlyZSgnLi9Jc1Byb3BlcnR5S2V5Jyk7XG5cbi8qKlxuICogNy4zLjkgLSBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZ2V0bWV0aG9kXG4gKiAxLiBBc3NlcnQ6IElzUHJvcGVydHlLZXkoUCkgaXMgdHJ1ZS5cbiAqIDIuIExldCBmdW5jIGJlIEdldFYoTywgUCkuXG4gKiAzLiBSZXR1cm5JZkFicnVwdChmdW5jKS5cbiAqIDQuIElmIGZ1bmMgaXMgZWl0aGVyIHVuZGVmaW5lZCBvciBudWxsLCByZXR1cm4gdW5kZWZpbmVkLlxuICogNS4gSWYgSXNDYWxsYWJsZShmdW5jKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICogNi4gUmV0dXJuIGZ1bmMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRNZXRob2QoTywgUCkge1xuXHQvLyA3LjMuOS4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuOS4yXG5cdHZhciBmdW5jID0gR2V0VihPLCBQKTtcblxuXHQvLyA3LjMuOS40XG5cdGlmIChmdW5jID09IG51bGwpIHtcblx0XHRyZXR1cm4gdm9pZCAwO1xuXHR9XG5cblx0Ly8gNy4zLjkuNVxuXHRpZiAoIUlzQ2FsbGFibGUoZnVuYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcihQICsgJ2lzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHQvLyA3LjMuOS42XG5cdHJldHVybiBmdW5jO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7364\n")},8509:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar ToObject = __webpack_require__(821);\n\n/**\n * 7.3.2 GetV (V, P)\n * 1. Assert: IsPropertyKey(P) is true.\n * 2. Let O be ToObject(V).\n * 3. ReturnIfAbrupt(O).\n * 4. Return O.[[Get]](P, V).\n */\n\nmodule.exports = function GetV(V, P) {\n\t// 7.3.2.1\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: IsPropertyKey(P) is not true');\n\t}\n\n\t// 7.3.2.2-3\n\tvar O = ToObject(V);\n\n\t// 7.3.2.4\n\treturn O[P];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxvQkFBb0IsbUJBQU8sQ0FBQyxJQUFpQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsR0FBWTs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9HZXRWLmpzPzc0OWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzUHJvcGVydHlLZXkgPSByZXF1aXJlKCcuL0lzUHJvcGVydHlLZXknKTtcbnZhciBUb09iamVjdCA9IHJlcXVpcmUoJy4vVG9PYmplY3QnKTtcblxuLyoqXG4gKiA3LjMuMiBHZXRWIChWLCBQKVxuICogMS4gQXNzZXJ0OiBJc1Byb3BlcnR5S2V5KFApIGlzIHRydWUuXG4gKiAyLiBMZXQgTyBiZSBUb09iamVjdChWKS5cbiAqIDMuIFJldHVybklmQWJydXB0KE8pLlxuICogNC4gUmV0dXJuIE8uW1tHZXRdXShQLCBWKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldFYoViwgUCkge1xuXHQvLyA3LjMuMi4xXG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBJc1Byb3BlcnR5S2V5KFApIGlzIG5vdCB0cnVlJyk7XG5cdH1cblxuXHQvLyA3LjMuMi4yLTNcblx0dmFyIE8gPSBUb09iamVjdChWKTtcblxuXHQvLyA3LjMuMi40XG5cdHJldHVybiBPW1BdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8509\n")},9527:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isaccessordescriptor\n\nmodule.exports = function IsAccessorDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Get]]') && !has(Desc, '[[Set]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUyNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0FjY2Vzc29yRGVzY3JpcHRvci5qcz9hYTJiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgYXNzZXJ0UmVjb3JkID0gcmVxdWlyZSgnLi4vaGVscGVycy9hc3NlcnRSZWNvcmQnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYWNjZXNzb3JkZXNjcmlwdG9yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tHZXRdXScpICYmICFoYXMoRGVzYywgJ1tbU2V0XV0nKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9527\n")},6975:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Array = GetIntrinsic('%Array%');\n\n// eslint-disable-next-line global-require\nvar toStr = !$Array.isArray && __webpack_require__(1924)('Object.prototype.toString');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isarray\n\nmodule.exports = $Array.isArray || function IsArray(argument) {\n\treturn toStr(argument) === '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk3NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBLCtCQUErQixtQkFBTyxDQUFDLElBQXFCOztBQUU1RDs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNBcnJheS5qcz82ZGMxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRBcnJheSA9IEdldEludHJpbnNpYygnJUFycmF5JScpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmVcbnZhciB0b1N0ciA9ICEkQXJyYXkuaXNBcnJheSAmJiByZXF1aXJlKCdjYWxsLWJpbmQvY2FsbEJvdW5kJykoJ09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzYXJyYXlcblxubW9kdWxlLmV4cG9ydHMgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0b1N0cihhcmd1bWVudCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6975\n")},1787:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.11\n\nmodule.exports = __webpack_require__(5320);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTc4Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBdUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNDYWxsYWJsZS5qcz83ZmY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdpcy1jYWxsYWJsZScpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1787\n")},1974:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(4445);\n\nvar $construct = GetIntrinsic('%Reflect.construct%', true);\n\nvar DefinePropertyOrThrow = __webpack_require__(3950);\ntry {\n\tDefinePropertyOrThrow({}, '', { '[[Get]]': function () {} });\n} catch (e) {\n\t// Accessor properties aren't supported\n\tDefinePropertyOrThrow = null;\n}\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nif (DefinePropertyOrThrow && $construct) {\n\tvar isConstructorMarker = {};\n\tvar badArrayLike = {};\n\tDefinePropertyOrThrow(badArrayLike, 'length', {\n\t\t'[[Get]]': function () {\n\t\t\tthrow isConstructorMarker;\n\t\t},\n\t\t'[[Enumerable]]': true\n\t});\n\n\tmodule.exports = function IsConstructor(argument) {\n\t\ttry {\n\t\t\t// `Reflect.construct` invokes `IsConstructor(target)` before `Get(args, 'length')`:\n\t\t\t$construct(argument, badArrayLike);\n\t\t} catch (err) {\n\t\t\treturn err === isConstructorMarker;\n\t\t}\n\t};\n} else {\n\tmodule.exports = function IsConstructor(argument) {\n\t\t// unfortunately there's no way to truly check this without try/catch `new argument` in old environments\n\t\treturn typeof argument === 'function' && !!argument.prototype;\n\t};\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk3NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxJQUFvQjs7QUFFL0M7O0FBRUEsNEJBQTRCLG1CQUFPLENBQUMsSUFBeUI7QUFDN0Q7QUFDQSx5QkFBeUIsUUFBUSwyQkFBMkI7QUFDNUQsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL0lzQ29uc3RydWN0b3IuanM/ZDJhYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCcuLi9HZXRJbnRyaW5zaWMuanMnKTtcblxudmFyICRjb25zdHJ1Y3QgPSBHZXRJbnRyaW5zaWMoJyVSZWZsZWN0LmNvbnN0cnVjdCUnLCB0cnVlKTtcblxudmFyIERlZmluZVByb3BlcnR5T3JUaHJvdyA9IHJlcXVpcmUoJy4vRGVmaW5lUHJvcGVydHlPclRocm93Jyk7XG50cnkge1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coe30sICcnLCB7ICdbW0dldF1dJzogZnVuY3Rpb24gKCkge30gfSk7XG59IGNhdGNoIChlKSB7XG5cdC8vIEFjY2Vzc29yIHByb3BlcnRpZXMgYXJlbid0IHN1cHBvcnRlZFxuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3cgPSBudWxsO1xufVxuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNjb25zdHJ1Y3RvclxuXG5pZiAoRGVmaW5lUHJvcGVydHlPclRocm93ICYmICRjb25zdHJ1Y3QpIHtcblx0dmFyIGlzQ29uc3RydWN0b3JNYXJrZXIgPSB7fTtcblx0dmFyIGJhZEFycmF5TGlrZSA9IHt9O1xuXHREZWZpbmVQcm9wZXJ0eU9yVGhyb3coYmFkQXJyYXlMaWtlLCAnbGVuZ3RoJywge1xuXHRcdCdbW0dldF1dJzogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhyb3cgaXNDb25zdHJ1Y3Rvck1hcmtlcjtcblx0XHR9LFxuXHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWVcblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGBSZWZsZWN0LmNvbnN0cnVjdGAgaW52b2tlcyBgSXNDb25zdHJ1Y3Rvcih0YXJnZXQpYCBiZWZvcmUgYEdldChhcmdzLCAnbGVuZ3RoJylgOlxuXHRcdFx0JGNvbnN0cnVjdChhcmd1bWVudCwgYmFkQXJyYXlMaWtlKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHJldHVybiBlcnIgPT09IGlzQ29uc3RydWN0b3JNYXJrZXI7XG5cdFx0fVxuXHR9O1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG5cdFx0Ly8gdW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHdheSB0byB0cnVseSBjaGVjayB0aGlzIHdpdGhvdXQgdHJ5L2NhdGNoIGBuZXcgYXJndW1lbnRgIGluIG9sZCBlbnZpcm9ubWVudHNcblx0XHRyZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSAnZnVuY3Rpb24nICYmICEhYXJndW1lbnQucHJvdG90eXBlO1xuXHR9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1974\n")},3746:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar assertRecord = __webpack_require__(2188);\n\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isdatadescriptor\n\nmodule.exports = function IsDataDescriptor(Desc) {\n\tif (typeof Desc === 'undefined') {\n\t\treturn false;\n\t}\n\n\tassertRecord(Type, 'Property Descriptor', 'Desc', Desc);\n\n\tif (!has(Desc, '[[Value]]') && !has(Desc, '[[Writable]]')) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsSUFBeUI7O0FBRXBELFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0RhdGFEZXNjcmlwdG9yLmpzPzYwOGYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBhc3NlcnRSZWNvcmQgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Fzc2VydFJlY29yZCcpO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtaXNkYXRhZGVzY3JpcHRvclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzRGF0YURlc2NyaXB0b3IoRGVzYykge1xuXHRpZiAodHlwZW9mIERlc2MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0YXNzZXJ0UmVjb3JkKFR5cGUsICdQcm9wZXJ0eSBEZXNjcmlwdG9yJywgJ0Rlc2MnLCBEZXNjKTtcblxuXHRpZiAoIWhhcyhEZXNjLCAnW1tWYWx1ZV1dJykgJiYgIWhhcyhEZXNjLCAnW1tXcml0YWJsZV1dJykpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3746\n")},7312:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(4908);\nvar floor = __webpack_require__(375);\nvar Type = __webpack_require__(3633);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\n\n// https://tc39.es/ecma262/#sec-isintegralnumber\n\nmodule.exports = function IsIntegralNumber(argument) {\n\tif (Type(argument) !== 'Number' || $isNaN(argument) || !$isFinite(argument)) {\n\t\treturn false;\n\t}\n\tvar absValue = abs(argument);\n\treturn floor(absValue) === absValue;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzMxMi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBTztBQUN6QixZQUFZLG1CQUFPLENBQUMsR0FBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsYUFBYSxtQkFBTyxDQUFDLElBQWtCO0FBQ3ZDLGdCQUFnQixtQkFBTyxDQUFDLElBQXFCOztBQUU3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc0ludGVncmFsTnVtYmVyLmpzPzY5NDciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnLi9hYnMnKTtcbnZhciBmbG9vciA9IHJlcXVpcmUoJy4vZmxvb3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xuXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzaW50ZWdyYWxudW1iZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc0ludGVncmFsTnVtYmVyKGFyZ3VtZW50KSB7XG5cdGlmIChUeXBlKGFyZ3VtZW50KSAhPT0gJ051bWJlcicgfHwgJGlzTmFOKGFyZ3VtZW50KSB8fCAhJGlzRmluaXRlKGFyZ3VtZW50KSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWJzVmFsdWUgPSBhYnMoYXJndW1lbnQpO1xuXHRyZXR1cm4gZmxvb3IoYWJzVmFsdWUpID09PSBhYnNWYWx1ZTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7312\n")},4305:function(module){"use strict";eval("\n\n// https://ecma-international.org/ecma-262/6.0/#sec-ispropertykey\n\nmodule.exports = function IsPropertyKey(argument) {\n\treturn typeof argument === 'string' || typeof argument === 'symbol';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvSXNQcm9wZXJ0eUtleS5qcz83YTkyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcHJvcGVydHlrZXlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KSB7XG5cdHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4305\n")},840:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $match = GetIntrinsic('%Symbol.match%', true);\n\nvar hasRegExpMatcher = __webpack_require__(8420);\n\nvar ToBoolean = __webpack_require__(9731);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-isregexp\n\nmodule.exports = function IsRegExp(argument) {\n\tif (!argument || typeof argument !== 'object') {\n\t\treturn false;\n\t}\n\tif ($match) {\n\t\tvar isRegExp = argument[$match];\n\t\tif (typeof isRegExp !== 'undefined') {\n\t\t\treturn ToBoolean(isRegExp);\n\t\t}\n\t}\n\treturn hasRegExpMatcher(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLHVCQUF1QixtQkFBTyxDQUFDLElBQVU7O0FBRXpDLGdCQUFnQixtQkFBTyxDQUFDLElBQWE7O0FBRXJDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Jc1JlZ0V4cC5qcz80NTY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRtYXRjaCA9IEdldEludHJpbnNpYygnJVN5bWJvbC5tYXRjaCUnLCB0cnVlKTtcblxudmFyIGhhc1JlZ0V4cE1hdGNoZXIgPSByZXF1aXJlKCdpcy1yZWdleCcpO1xuXG52YXIgVG9Cb29sZWFuID0gcmVxdWlyZSgnLi9Ub0Jvb2xlYW4nKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWlzcmVnZXhwXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gSXNSZWdFeHAoYXJndW1lbnQpIHtcblx0aWYgKCFhcmd1bWVudCB8fCB0eXBlb2YgYXJndW1lbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICgkbWF0Y2gpIHtcblx0XHR2YXIgaXNSZWdFeHAgPSBhcmd1bWVudFskbWF0Y2hdO1xuXHRcdGlmICh0eXBlb2YgaXNSZWdFeHAgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gVG9Cb29sZWFuKGlzUmVnRXhwKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGhhc1JlZ0V4cE1hdGNoZXIoYXJndW1lbnQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},953:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $ObjectCreate = GetIntrinsic('%Object.create%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar IsArray = __webpack_require__(6975);\nvar Type = __webpack_require__(3633);\n\nvar hasProto = !({ __proto__: null } instanceof Object);\n\n// https://262.ecma-international.org/6.0/#sec-objectcreate\n\nmodule.exports = function OrdinaryObjectCreate(proto) {\n\tif (proto !== null && Type(proto) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `proto` must be null or an object');\n\t}\n\tvar additionalInternalSlotsList = arguments.length < 2 ? [] : arguments[1];\n\tif (!IsArray(additionalInternalSlotsList)) {\n\t\tthrow new $TypeError('Assertion failed: `additionalInternalSlotsList` must be an Array');\n\t}\n\t// var internalSlotsList = ['[[Prototype]]', '[[Extensible]]'];\n\tif (additionalInternalSlotsList.length > 0) {\n\t\tthrow new $SyntaxError('es-abstract does not yet support internal slots');\n\t\t// internalSlotsList.push(...additionalInternalSlotsList);\n\t}\n\t// var O = MakeBasicObject(internalSlotsList);\n\t// setProto(O, proto);\n\t// return O;\n\n\tif ($ObjectCreate) {\n\t\treturn $ObjectCreate(proto);\n\t}\n\tif (hasProto) {\n\t\treturn { __proto__: proto };\n\t}\n\n\tif (proto === null) {\n\t\tthrow new $SyntaxError('native Object.create support is required to create null objects');\n\t}\n\tvar T = function T() {};\n\tT.prototype = proto;\n\treturn new T();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBVztBQUNqQyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0IsbUJBQW1CLGtCQUFrQjs7QUFFckM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvT3JkaW5hcnlPYmplY3RDcmVhdGUuanM/YjY2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkT2JqZWN0Q3JlYXRlID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmNyZWF0ZSUnLCB0cnVlKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgSXNBcnJheSA9IHJlcXVpcmUoJy4vSXNBcnJheScpO1xudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcblxudmFyIGhhc1Byb3RvID0gISh7IF9fcHJvdG9fXzogbnVsbCB9IGluc3RhbmNlb2YgT2JqZWN0KTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy82LjAvI3NlYy1vYmplY3RjcmVhdGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBPcmRpbmFyeU9iamVjdENyZWF0ZShwcm90bykge1xuXHRpZiAocHJvdG8gIT09IG51bGwgJiYgVHlwZShwcm90bykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBwcm90b2AgbXVzdCBiZSBudWxsIG9yIGFuIG9iamVjdCcpO1xuXHR9XG5cdHZhciBhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IFtdIDogYXJndW1lbnRzWzFdO1xuXHRpZiAoIUlzQXJyYXkoYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0KSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgYWRkaXRpb25hbEludGVybmFsU2xvdHNMaXN0YCBtdXN0IGJlIGFuIEFycmF5Jyk7XG5cdH1cblx0Ly8gdmFyIGludGVybmFsU2xvdHNMaXN0ID0gWydbW1Byb3RvdHlwZV1dJywgJ1tbRXh0ZW5zaWJsZV1dJ107XG5cdGlmIChhZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QubGVuZ3RoID4gMCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2VzLWFic3RyYWN0IGRvZXMgbm90IHlldCBzdXBwb3J0IGludGVybmFsIHNsb3RzJyk7XG5cdFx0Ly8gaW50ZXJuYWxTbG90c0xpc3QucHVzaCguLi5hZGRpdGlvbmFsSW50ZXJuYWxTbG90c0xpc3QpO1xuXHR9XG5cdC8vIHZhciBPID0gTWFrZUJhc2ljT2JqZWN0KGludGVybmFsU2xvdHNMaXN0KTtcblx0Ly8gc2V0UHJvdG8oTywgcHJvdG8pO1xuXHQvLyByZXR1cm4gTztcblxuXHRpZiAoJE9iamVjdENyZWF0ZSkge1xuXHRcdHJldHVybiAkT2JqZWN0Q3JlYXRlKHByb3RvKTtcblx0fVxuXHRpZiAoaGFzUHJvdG8pIHtcblx0XHRyZXR1cm4geyBfX3Byb3RvX186IHByb3RvIH07XG5cdH1cblxuXHRpZiAocHJvdG8gPT09IG51bGwpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCduYXRpdmUgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBudWxsIG9iamVjdHMnKTtcblx0fVxuXHR2YXIgVCA9IGZ1bmN0aW9uIFQoKSB7fTtcblx0VC5wcm90b3R5cGUgPSBwcm90bztcblx0cmV0dXJuIG5ldyBUKCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///953\n")},6258:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar regexExec = __webpack_require__(1924)('RegExp.prototype.exec');\n\nvar Call = __webpack_require__(581);\nvar Get = __webpack_require__(1391);\nvar IsCallable = __webpack_require__(1787);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec\n\nmodule.exports = function RegExpExec(R, S) {\n\tif (Type(R) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `R` must be an Object');\n\t}\n\tif (Type(S) !== 'String') {\n\t\tthrow new $TypeError('Assertion failed: `S` must be a String');\n\t}\n\tvar exec = Get(R, 'exec');\n\tif (IsCallable(exec)) {\n\t\tvar result = Call(exec, R, [S]);\n\t\tif (result === null || Type(result) === 'Object') {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new $TypeError('\"exec\" method must return `null` or an Object');\n\t}\n\treturn regexExec(R, S);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjI1OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0MsV0FBVyxtQkFBTyxDQUFDLEdBQVE7QUFDM0IsVUFBVSxtQkFBTyxDQUFDLElBQU87QUFDekIsaUJBQWlCLG1CQUFPLENBQUMsSUFBYztBQUN2QyxXQUFXLG1CQUFPLENBQUMsSUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9SZWdFeHBFeGVjLmpzP2FhYTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIHJlZ2V4RXhlYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKSgnUmVnRXhwLnByb3RvdHlwZS5leGVjJyk7XG5cbnZhciBDYWxsID0gcmVxdWlyZSgnLi9DYWxsJyk7XG52YXIgR2V0ID0gcmVxdWlyZSgnLi9HZXQnKTtcbnZhciBJc0NhbGxhYmxlID0gcmVxdWlyZSgnLi9Jc0NhbGxhYmxlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBodHRwczovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcmVnZXhwZXhlY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFJlZ0V4cEV4ZWMoUiwgUykge1xuXHRpZiAoVHlwZShSKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYFJgIG11c3QgYmUgYW4gT2JqZWN0Jyk7XG5cdH1cblx0aWYgKFR5cGUoUykgIT09ICdTdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBTYCBtdXN0IGJlIGEgU3RyaW5nJyk7XG5cdH1cblx0dmFyIGV4ZWMgPSBHZXQoUiwgJ2V4ZWMnKTtcblx0aWYgKElzQ2FsbGFibGUoZXhlYykpIHtcblx0XHR2YXIgcmVzdWx0ID0gQ2FsbChleGVjLCBSLCBbU10pO1xuXHRcdGlmIChyZXN1bHQgPT09IG51bGwgfHwgVHlwZShyZXN1bHQpID09PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiZXhlY1wiIG1ldGhvZCBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gT2JqZWN0Jyk7XG5cdH1cblx0cmV0dXJuIHJlZ2V4RXhlYyhSLCBTKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6258\n")},9619:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = __webpack_require__(4559);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTYxOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiwwQ0FBcUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvUmVxdWlyZU9iamVjdENvZXJjaWJsZS5qcz9lZDA1Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi81L0NoZWNrT2JqZWN0Q29lcmNpYmxlJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9619\n")},484:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar $isNaN = __webpack_require__(9086);\n\n// http://262.ecma-international.org/5.1/#sec-9.12\n\nmodule.exports = function SameValue(x, y) {\n\tif (x === y) { // 0 === -0, but they are not identical.\n\t\tif (x === 0) { return 1 / x === 1 / y; }\n\t\treturn true;\n\t}\n\treturn $isNaN(x) && $isNaN(y);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGFBQWEsbUJBQU8sQ0FBQyxJQUFrQjs7QUFFdkM7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NhbWVWYWx1ZS5qcz9mMTM2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNOYU4nKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuMTJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTYW1lVmFsdWUoeCwgeSkge1xuXHRpZiAoeCA9PT0geSkgeyAvLyAwID09PSAtMCwgYnV0IHRoZXkgYXJlIG5vdCBpZGVudGljYWwuXG5cdFx0aWYgKHggPT09IDApIHsgcmV0dXJuIDEgLyB4ID09PSAxIC8geTsgfVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiAkaXNOYU4oeCkgJiYgJGlzTmFOKHkpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///484\n")},105:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsPropertyKey = __webpack_require__(4305);\nvar SameValue = __webpack_require__(484);\nvar Type = __webpack_require__(3633);\n\n// IE 9 does not throw in strict mode when writability/configurability/extensibility is violated\nvar noThrowOnStrictViolation = (function () {\n\ttry {\n\t\tdelete [].length;\n\t\treturn true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}());\n\n// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw\n\nmodule.exports = function Set(O, P, V, Throw) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: `O` must be an Object');\n\t}\n\tif (!IsPropertyKey(P)) {\n\t\tthrow new $TypeError('Assertion failed: `P` must be a Property Key');\n\t}\n\tif (Type(Throw) !== 'Boolean') {\n\t\tthrow new $TypeError('Assertion failed: `Throw` must be a Boolean');\n\t}\n\tif (Throw) {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\tif (noThrowOnStrictViolation && !SameValue(O[P], V)) {\n\t\t\tthrow new $TypeError('Attempted to assign to readonly property.');\n\t\t}\n\t\treturn true;\n\t}\n\ttry {\n\t\tO[P] = V; // eslint-disable-line no-param-reassign\n\t\treturn noThrowOnStrictViolation ? SameValue(O[P], V) : true;\n\t} catch (e) {\n\t\treturn false;\n\t}\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWE7QUFDckMsV0FBVyxtQkFBTyxDQUFDLElBQVE7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9TZXQuanM/ZWVlNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG52YXIgSXNQcm9wZXJ0eUtleSA9IHJlcXVpcmUoJy4vSXNQcm9wZXJ0eUtleScpO1xudmFyIFNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vU2FtZVZhbHVlJyk7XG52YXIgVHlwZSA9IHJlcXVpcmUoJy4vVHlwZScpO1xuXG4vLyBJRSA5IGRvZXMgbm90IHRocm93IGluIHN0cmljdCBtb2RlIHdoZW4gd3JpdGFiaWxpdHkvY29uZmlndXJhYmlsaXR5L2V4dGVuc2liaWxpdHkgaXMgdmlvbGF0ZWRcbnZhciBub1Rocm93T25TdHJpY3RWaW9sYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuXHR0cnkge1xuXHRcdGRlbGV0ZSBbXS5sZW5ndGg7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0oKSk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zZXQtby1wLXYtdGhyb3dcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTZXQoTywgUCwgViwgVGhyb3cpIHtcblx0aWYgKFR5cGUoTykgIT09ICdPYmplY3QnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBPYCBtdXN0IGJlIGFuIE9iamVjdCcpO1xuXHR9XG5cdGlmICghSXNQcm9wZXJ0eUtleShQKSkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBgUGAgbXVzdCBiZSBhIFByb3BlcnR5IEtleScpO1xuXHR9XG5cdGlmIChUeXBlKFRocm93KSAhPT0gJ0Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Fzc2VydGlvbiBmYWlsZWQ6IGBUaHJvd2AgbXVzdCBiZSBhIEJvb2xlYW4nKTtcblx0fVxuXHRpZiAoVGhyb3cpIHtcblx0XHRPW1BdID0gVjsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdGlmIChub1Rocm93T25TdHJpY3RWaW9sYXRpb24gJiYgIVNhbWVWYWx1ZShPW1BdLCBWKSkge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0F0dGVtcHRlZCB0byBhc3NpZ24gdG8gcmVhZG9ubHkgcHJvcGVydHkuJyk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRyeSB7XG5cdFx0T1tQXSA9IFY7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRyZXR1cm4gbm9UaHJvd09uU3RyaWN0VmlvbGF0aW9uID8gU2FtZVZhbHVlKE9bUF0sIFYpIDogdHJ1ZTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///105\n")},9655:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = __webpack_require__(1974);\nvar Type = __webpack_require__(3633);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n\tif (Type(O) !== 'Object') {\n\t\tthrow new $TypeError('Assertion failed: Type(O) is not Object');\n\t}\n\tvar C = O.constructor;\n\tif (typeof C === 'undefined') {\n\t\treturn defaultConstructor;\n\t}\n\tif (Type(C) !== 'Object') {\n\t\tthrow new $TypeError('O.constructor is not an Object');\n\t}\n\tvar S = $species ? C[$species] : void 0;\n\tif (S == null) {\n\t\treturn defaultConstructor;\n\t}\n\tif (IsConstructor(S)) {\n\t\treturn S;\n\t}\n\tthrow new $TypeError('no constructor found');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTY1NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLG9CQUFvQixtQkFBTyxDQUFDLElBQWlCO0FBQzdDLFdBQVcsbUJBQU8sQ0FBQyxJQUFROztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1NwZWNpZXNDb25zdHJ1Y3Rvci5qcz84MTA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRzcGVjaWVzID0gR2V0SW50cmluc2ljKCclU3ltYm9sLnNwZWNpZXMlJywgdHJ1ZSk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIElzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL0lzQ29uc3RydWN0b3InKTtcbnZhciBUeXBlID0gcmVxdWlyZSgnLi9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zcGVjaWVzY29uc3RydWN0b3JcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKSB7XG5cdGlmIChUeXBlKE8pICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdBc3NlcnRpb24gZmFpbGVkOiBUeXBlKE8pIGlzIG5vdCBPYmplY3QnKTtcblx0fVxuXHR2YXIgQyA9IE8uY29uc3RydWN0b3I7XG5cdGlmICh0eXBlb2YgQyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChUeXBlKEMpICE9PSAnT2JqZWN0Jykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdPLmNvbnN0cnVjdG9yIGlzIG5vdCBhbiBPYmplY3QnKTtcblx0fVxuXHR2YXIgUyA9ICRzcGVjaWVzID8gQ1skc3BlY2llc10gOiB2b2lkIDA7XG5cdGlmIChTID09IG51bGwpIHtcblx0XHRyZXR1cm4gZGVmYXVsdENvbnN0cnVjdG9yO1xuXHR9XG5cdGlmIChJc0NvbnN0cnVjdG9yKFMpKSB7XG5cdFx0cmV0dXJuIFM7XG5cdH1cblx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ25vIGNvbnN0cnVjdG9yIGZvdW5kJyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9655\n")},9731:function(module){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.2\n\nmodule.exports = function ToBoolean(value) { return !!value; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTczMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSw2Q0FBNkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9Cb29sZWFuLmpzPzdmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9Cb29sZWFuKHZhbHVlKSB7IHJldHVybiAhIXZhbHVlOyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9731\n")},751:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5ToInteger = __webpack_require__(775);\n\nvar ToNumber = __webpack_require__(5631);\n\n// https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif (number !== 0) {\n\t\tnumber = ES5ToInteger(number);\n\t}\n\treturn number === 0 ? 0 : number;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWdCOztBQUUzQyxlQUFlLG1CQUFPLENBQUMsSUFBWTs7QUFFbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvVG9JbnRlZ2VyT3JJbmZpbml0eS5qcz8zNTA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVTNVRvSW50ZWdlciA9IHJlcXVpcmUoJy4uLzUvVG9JbnRlZ2VyJyk7XG5cbnZhciBUb051bWJlciA9IHJlcXVpcmUoJy4vVG9OdW1iZXInKTtcblxuLy8gaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi8xMS4wLyNzZWMtdG9pbnRlZ2VyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9JbnRlZ2VyKHZhbHVlKSB7XG5cdHZhciBudW1iZXIgPSBUb051bWJlcih2YWx1ZSk7XG5cdGlmIChudW1iZXIgIT09IDApIHtcblx0XHRudW1iZXIgPSBFUzVUb0ludGVnZXIobnVtYmVyKTtcblx0fVxuXHRyZXR1cm4gbnVtYmVyID09PSAwID8gMCA6IG51bWJlcjtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///751\n")},8305:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar MAX_SAFE_INTEGER = __webpack_require__(1645);\n\nvar ToIntegerOrInfinity = __webpack_require__(751);\n\nmodule.exports = function ToLength(argument) {\n\tvar len = ToIntegerOrInfinity(argument);\n\tif (len <= 0) { return 0; } // includes converting -0 to +0\n\tif (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }\n\treturn len;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMwNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYix1QkFBdUIsbUJBQU8sQ0FBQyxJQUEyQjs7QUFFMUQsMEJBQTBCLG1CQUFPLENBQUMsR0FBdUI7O0FBRXpEO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub0xlbmd0aC5qcz9iYTg4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL21heFNhZmVJbnRlZ2VyJyk7XG5cbnZhciBUb0ludGVnZXJPckluZmluaXR5ID0gcmVxdWlyZSgnLi9Ub0ludGVnZXJPckluZmluaXR5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9MZW5ndGgoYXJndW1lbnQpIHtcblx0dmFyIGxlbiA9IFRvSW50ZWdlck9ySW5maW5pdHkoYXJndW1lbnQpO1xuXHRpZiAobGVuIDw9IDApIHsgcmV0dXJuIDA7IH0gLy8gaW5jbHVkZXMgY29udmVydGluZyAtMCB0byArMFxuXHRpZiAobGVuID4gTUFYX1NBRkVfSU5URUdFUikgeyByZXR1cm4gTUFYX1NBRkVfSU5URUdFUjsgfVxuXHRyZXR1cm4gbGVuO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8305\n")},5631:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = __webpack_require__(1924);\nvar regexTester = __webpack_require__(823);\nvar isPrimitive = __webpack_require__(4790);\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = ['\\u0085', '\\u200b', '\\ufffe'].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex);\n\n// whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\nvar ws = [\n\t'\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003',\n\t'\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028',\n\t'\\u2029\\uFEFF'\n].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\nvar $trim = function (value) {\n\treturn $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = __webpack_require__(4607);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tonumber\n\nmodule.exports = function ToNumber(argument) {\n\tvar value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\tif (typeof value === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a number');\n\t}\n\tif (typeof value === 'bigint') {\n\t\tthrow new $TypeError('Conversion from \\'BigInt\\' to \\'number\\' is not allowed.');\n\t}\n\tif (typeof value === 'string') {\n\t\tif (isBinary(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 2));\n\t\t} else if (isOctal(value)) {\n\t\t\treturn ToNumber($parseInteger($strSlice(value, 2), 8));\n\t\t} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n\t\t\treturn NaN;\n\t\t}\n\t\tvar trimmed = $trim(value);\n\t\tif (trimmed !== value) {\n\t\t\treturn ToNumber(trimmed);\n\t\t}\n\n\t}\n\treturn $Number(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYzMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjtBQUM3QyxrQkFBa0IsbUJBQU8sQ0FBQyxHQUF3QjtBQUNsRCxrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixtQkFBTyxDQUFDLElBQWU7O0FBRXpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub051bWJlci5qcz9jZGZlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJE51bWJlciA9IEdldEludHJpbnNpYygnJU51bWJlciUnKTtcbnZhciAkUmVnRXhwID0gR2V0SW50cmluc2ljKCclUmVnRXhwJScpO1xudmFyICRwYXJzZUludGVnZXIgPSBHZXRJbnRyaW5zaWMoJyVwYXJzZUludCUnKTtcblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcbnZhciByZWdleFRlc3RlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcmVnZXhUZXN0ZXInKTtcbnZhciBpc1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaXNQcmltaXRpdmUnKTtcblxudmFyICRzdHJTbGljZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5zbGljZScpO1xudmFyIGlzQmluYXJ5ID0gcmVnZXhUZXN0ZXIoL14wYlswMV0rJC9pKTtcbnZhciBpc09jdGFsID0gcmVnZXhUZXN0ZXIoL14wb1swLTddKyQvaSk7XG52YXIgaXNJbnZhbGlkSGV4TGl0ZXJhbCA9IHJlZ2V4VGVzdGVyKC9eWy0rXTB4WzAtOWEtZl0rJC9pKTtcbnZhciBub25XUyA9IFsnXFx1MDA4NScsICdcXHUyMDBiJywgJ1xcdWZmZmUnXS5qb2luKCcnKTtcbnZhciBub25XU3JlZ2V4ID0gbmV3ICRSZWdFeHAoJ1snICsgbm9uV1MgKyAnXScsICdnJyk7XG52YXIgaGFzTm9uV1MgPSByZWdleFRlc3Rlcihub25XU3JlZ2V4KTtcblxuLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS41LjQuMjBcbi8vIGltcGxlbWVudGF0aW9uIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvdjMuNC4wL2VzNS1zaGltLmpzI0wxMzA0LUwxMzI0XG52YXIgd3MgPSBbXG5cdCdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycsXG5cdCdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcsXG5cdCdcXHUyMDI5XFx1RkVGRidcbl0uam9pbignJyk7XG52YXIgdHJpbVJlZ2V4ID0gbmV3IFJlZ0V4cCgnKF5bJyArIHdzICsgJ10rKXwoWycgKyB3cyArICddKyQpJywgJ2cnKTtcbnZhciAkcmVwbGFjZSA9IGNhbGxCb3VuZCgnU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlJyk7XG52YXIgJHRyaW0gPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0cmV0dXJuICRyZXBsYWNlKHZhbHVlLCB0cmltUmVnZXgsICcnKTtcbn07XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbnVtYmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9OdW1iZXIoYXJndW1lbnQpIHtcblx0dmFyIHZhbHVlID0gaXNQcmltaXRpdmUoYXJndW1lbnQpID8gYXJndW1lbnQgOiBUb1ByaW1pdGl2ZShhcmd1bWVudCwgJE51bWJlcik7XG5cdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IGEgU3ltYm9sIHZhbHVlIHRvIGEgbnVtYmVyJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ29udmVyc2lvbiBmcm9tIFxcJ0JpZ0ludFxcJyB0byBcXCdudW1iZXJcXCcgaXMgbm90IGFsbG93ZWQuJyk7XG5cdH1cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRpZiAoaXNCaW5hcnkodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gVG9OdW1iZXIoJHBhcnNlSW50ZWdlcigkc3RyU2xpY2UodmFsdWUsIDIpLCAyKSk7XG5cdFx0fSBlbHNlIGlmIChpc09jdGFsKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIFRvTnVtYmVyKCRwYXJzZUludGVnZXIoJHN0clNsaWNlKHZhbHVlLCAyKSwgOCkpO1xuXHRcdH0gZWxzZSBpZiAoaGFzTm9uV1ModmFsdWUpIHx8IGlzSW52YWxpZEhleExpdGVyYWwodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHR2YXIgdHJpbW1lZCA9ICR0cmltKHZhbHVlKTtcblx0XHRpZiAodHJpbW1lZCAhPT0gdmFsdWUpIHtcblx0XHRcdHJldHVybiBUb051bWJlcih0cmltbWVkKTtcblx0XHR9XG5cblx0fVxuXHRyZXR1cm4gJE51bWJlcih2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5631\n")},821:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = __webpack_require__(9619);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toobject\n\nmodule.exports = function ToObject(value) {\n\tRequireObjectCoercible(value);\n\treturn $Object(value);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIxLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLDZCQUE2QixtQkFBTyxDQUFDLElBQTBCOztBQUUvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub09iamVjdC5qcz8zNGI3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRPYmplY3QgPSBHZXRJbnRyaW5zaWMoJyVPYmplY3QlJyk7XG5cbnZhciBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlID0gcmVxdWlyZSgnLi9SZXF1aXJlT2JqZWN0Q29lcmNpYmxlJyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b29iamVjdFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvT2JqZWN0KHZhbHVlKSB7XG5cdFJlcXVpcmVPYmplY3RDb2VyY2libGUodmFsdWUpO1xuXHRyZXR1cm4gJE9iamVjdCh2YWx1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///821\n")},4607:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar toPrimitive = __webpack_require__(1503);\n\n// https://ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\nmodule.exports = function ToPrimitive(input) {\n\tif (arguments.length > 1) {\n\t\treturn toPrimitive(input, arguments[1]);\n\t}\n\treturn toPrimitive(input);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDYwNy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUF3Qjs7QUFFbEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1RvUHJpbWl0aXZlLmpzPzkxOWUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXMyMDE1Jyk7XG5cbi8vIGh0dHBzOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b3ByaW1pdGl2ZVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0KSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdHJldHVybiB0b1ByaW1pdGl2ZShpbnB1dCwgYXJndW1lbnRzWzFdKTtcblx0fVxuXHRyZXR1cm4gdG9QcmltaXRpdmUoaW5wdXQpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4607\n")},9916:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar has = __webpack_require__(7642);\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar Type = __webpack_require__(3633);\nvar ToBoolean = __webpack_require__(9731);\nvar IsCallable = __webpack_require__(1787);\n\n// https://262.ecma-international.org/5.1/#sec-8.10.5\n\nmodule.exports = function ToPropertyDescriptor(Obj) {\n\tif (Type(Obj) !== 'Object') {\n\t\tthrow new $TypeError('ToPropertyDescriptor requires an object');\n\t}\n\n\tvar desc = {};\n\tif (has(Obj, 'enumerable')) {\n\t\tdesc['[[Enumerable]]'] = ToBoolean(Obj.enumerable);\n\t}\n\tif (has(Obj, 'configurable')) {\n\t\tdesc['[[Configurable]]'] = ToBoolean(Obj.configurable);\n\t}\n\tif (has(Obj, 'value')) {\n\t\tdesc['[[Value]]'] = Obj.value;\n\t}\n\tif (has(Obj, 'writable')) {\n\t\tdesc['[[Writable]]'] = ToBoolean(Obj.writable);\n\t}\n\tif (has(Obj, 'get')) {\n\t\tvar getter = Obj.get;\n\t\tif (typeof getter !== 'undefined' && !IsCallable(getter)) {\n\t\t\tthrow new $TypeError('getter must be a function');\n\t\t}\n\t\tdesc['[[Get]]'] = getter;\n\t}\n\tif (has(Obj, 'set')) {\n\t\tvar setter = Obj.set;\n\t\tif (typeof setter !== 'undefined' && !IsCallable(setter)) {\n\t\t\tthrow new $TypeError('setter must be a function');\n\t\t}\n\t\tdesc['[[Set]]'] = setter;\n\t}\n\n\tif ((has(desc, '[[Get]]') || has(desc, '[[Set]]')) && (has(desc, '[[Value]]') || has(desc, '[[Writable]]'))) {\n\t\tthrow new $TypeError('Invalid property descriptor. Cannot both specify accessors and a value or writable attribute');\n\t}\n\treturn desc;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkxNi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixVQUFVLG1CQUFPLENBQUMsSUFBSzs7QUFFdkIsbUJBQW1CLG1CQUFPLENBQUMsR0FBZTs7QUFFMUM7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLElBQVE7QUFDM0IsZ0JBQWdCLG1CQUFPLENBQUMsSUFBYTtBQUNyQyxpQkFBaUIsbUJBQU8sQ0FBQyxJQUFjOztBQUV2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1Byb3BlcnR5RGVzY3JpcHRvci5qcz9jZjY4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IHJlcXVpcmUoJ2hhcycpO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuL1R5cGUnKTtcbnZhciBUb0Jvb2xlYW4gPSByZXF1aXJlKCcuL1RvQm9vbGVhbicpO1xudmFyIElzQ2FsbGFibGUgPSByZXF1aXJlKCcuL0lzQ2FsbGFibGUnKTtcblxuLy8gaHR0cHM6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy04LjEwLjVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb1Byb3BlcnR5RGVzY3JpcHRvcihPYmopIHtcblx0aWYgKFR5cGUoT2JqKSAhPT0gJ09iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignVG9Qcm9wZXJ0eURlc2NyaXB0b3IgcmVxdWlyZXMgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHR2YXIgZGVzYyA9IHt9O1xuXHRpZiAoaGFzKE9iaiwgJ2VudW1lcmFibGUnKSkge1xuXHRcdGRlc2NbJ1tbRW51bWVyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmVudW1lcmFibGUpO1xuXHR9XG5cdGlmIChoYXMoT2JqLCAnY29uZmlndXJhYmxlJykpIHtcblx0XHRkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLmNvbmZpZ3VyYWJsZSk7XG5cdH1cblx0aWYgKGhhcyhPYmosICd2YWx1ZScpKSB7XG5cdFx0ZGVzY1snW1tWYWx1ZV1dJ10gPSBPYmoudmFsdWU7XG5cdH1cblx0aWYgKGhhcyhPYmosICd3cml0YWJsZScpKSB7XG5cdFx0ZGVzY1snW1tXcml0YWJsZV1dJ10gPSBUb0Jvb2xlYW4oT2JqLndyaXRhYmxlKTtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ2dldCcpKSB7XG5cdFx0dmFyIGdldHRlciA9IE9iai5nZXQ7XG5cdFx0aWYgKHR5cGVvZiBnZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKGdldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdnZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbR2V0XV0nXSA9IGdldHRlcjtcblx0fVxuXHRpZiAoaGFzKE9iaiwgJ3NldCcpKSB7XG5cdFx0dmFyIHNldHRlciA9IE9iai5zZXQ7XG5cdFx0aWYgKHR5cGVvZiBzZXR0ZXIgIT09ICd1bmRlZmluZWQnICYmICFJc0NhbGxhYmxlKHNldHRlcikpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdzZXR0ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHRcdGRlc2NbJ1tbU2V0XV0nXSA9IHNldHRlcjtcblx0fVxuXG5cdGlmICgoaGFzKGRlc2MsICdbW0dldF1dJykgfHwgaGFzKGRlc2MsICdbW1NldF1dJykpICYmIChoYXMoZGVzYywgJ1tbVmFsdWVdXScpIHx8IGhhcyhkZXNjLCAnW1tXcml0YWJsZV1dJykpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ0ludmFsaWQgcHJvcGVydHkgZGVzY3JpcHRvci4gQ2Fubm90IGJvdGggc3BlY2lmeSBhY2Nlc3NvcnMgYW5kIGEgdmFsdWUgb3Igd3JpdGFibGUgYXR0cmlidXRlJyk7XG5cdH1cblx0cmV0dXJuIGRlc2M7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9916\n")},6846:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $String = GetIntrinsic('%String%');\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// https://ecma-international.org/ecma-262/6.0/#sec-tostring\n\nmodule.exports = function ToString(argument) {\n\tif (typeof argument === 'symbol') {\n\t\tthrow new $TypeError('Cannot convert a Symbol value to a string');\n\t}\n\treturn $String(argument);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjg0Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9Ub1N0cmluZy5qcz8wZjA5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRTdHJpbmcgPSBHZXRJbnRyaW5zaWMoJyVTdHJpbmclJyk7XG52YXIgJFR5cGVFcnJvciA9IEdldEludHJpbnNpYygnJVR5cGVFcnJvciUnKTtcblxuLy8gaHR0cHM6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvc3RyaW5nXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcblx0aWYgKHR5cGVvZiBhcmd1bWVudCA9PT0gJ3N5bWJvbCcpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgYSBTeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcnKTtcblx0fVxuXHRyZXR1cm4gJFN0cmluZyhhcmd1bWVudCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6846\n")},3633:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ES5Type = __webpack_require__(3951);\n\n// https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values\n\nmodule.exports = function Type(x) {\n\tif (typeof x === 'symbol') {\n\t\treturn 'Symbol';\n\t}\n\tif (typeof x === 'bigint') {\n\t\treturn 'BigInt';\n\t}\n\treturn ES5Type(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixjQUFjLG1CQUFPLENBQUMsSUFBVzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC8yMDIxL1R5cGUuanM/ZTQyYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBFUzVUeXBlID0gcmVxdWlyZSgnLi4vNS9UeXBlJyk7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvMTEuMC8jc2VjLWVjbWFzY3JpcHQtZGF0YS10eXBlcy1hbmQtdmFsdWVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gVHlwZSh4KSB7XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N5bWJvbCcpIHtcblx0XHRyZXR1cm4gJ1N5bWJvbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYmlnaW50Jykge1xuXHRcdHJldHVybiAnQmlnSW50Jztcblx0fVxuXHRyZXR1cm4gRVM1VHlwZSh4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3633\n")},4857:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $fromCharCode = GetIntrinsic('%String.fromCharCode%');\n\nvar isLeadingSurrogate = __webpack_require__(9544);\nvar isTrailingSurrogate = __webpack_require__(5424);\n\n// https://tc39.es/ecma262/2020/#sec-utf16decodesurrogatepair\n\nmodule.exports = function UTF16DecodeSurrogatePair(lead, trail) {\n\tif (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {\n\t\tthrow new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');\n\t}\n\t// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\treturn $fromCharCode(lead) + $fromCharCode(trail);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDg1Ny5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLHlCQUF5QixtQkFBTyxDQUFDLElBQStCO0FBQ2hFLDBCQUEwQixtQkFBTyxDQUFDLElBQWdDOztBQUVsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvMjAyMS9VVEYxNlN1cnJvZ2F0ZVBhaXJUb0NvZGVQb2ludC5qcz8zMmFlIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyICRUeXBlRXJyb3IgPSBHZXRJbnRyaW5zaWMoJyVUeXBlRXJyb3IlJyk7XG52YXIgJGZyb21DaGFyQ29kZSA9IEdldEludHJpbnNpYygnJVN0cmluZy5mcm9tQ2hhckNvZGUlJyk7XG5cbnZhciBpc0xlYWRpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTGVhZGluZ1N1cnJvZ2F0ZScpO1xudmFyIGlzVHJhaWxpbmdTdXJyb2dhdGUgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzVHJhaWxpbmdTdXJyb2dhdGUnKTtcblxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvMjAyMC8jc2VjLXV0ZjE2ZGVjb2Rlc3Vycm9nYXRlcGFpclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFVURjE2RGVjb2RlU3Vycm9nYXRlUGFpcihsZWFkLCB0cmFpbCkge1xuXHRpZiAoIWlzTGVhZGluZ1N1cnJvZ2F0ZShsZWFkKSB8fCAhaXNUcmFpbGluZ1N1cnJvZ2F0ZSh0cmFpbCkpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignQXNzZXJ0aW9uIGZhaWxlZDogYGxlYWRgIG11c3QgYmUgYSBsZWFkaW5nIHN1cnJvZ2F0ZSBjaGFyIGNvZGUsIGFuZCBgdHJhaWxgIG11c3QgYmUgYSB0cmFpbGluZyBzdXJyb2dhdGUgY2hhciBjb2RlJyk7XG5cdH1cblx0Ly8gdmFyIGNwID0gKGxlYWQgLSAweEQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweERDMDApICsgMHgxMDAwMDtcblx0cmV0dXJuICRmcm9tQ2hhckNvZGUobGVhZCkgKyAkZnJvbUNoYXJDb2RlKHRyYWlsKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4857\n")},4908:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkwOC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvYWJzLmpzPzJjNTMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4908\n")},375:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzIwMjEvZmxvb3IuanM/ZThjZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIHZhciBtb2R1bG8gPSByZXF1aXJlKCcuL21vZHVsbycpO1xudmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy01LjJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmbG9vcih4KSB7XG5cdC8vIHJldHVybiB4IC0gbW9kdWxvKHgsIDEpO1xuXHRyZXR1cm4gJGZsb29yKHgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///375\n")},4559:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\n\n// http://262.ecma-international.org/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n\tif (value == null) {\n\t\tthrow new $TypeError(optMessage || ('Cannot call method on ' + value));\n\t}\n\treturn value;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU1OS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvQ2hlY2tPYmplY3RDb2VyY2libGUuanM/M2Q3NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOS4xMFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIENoZWNrT2JqZWN0Q29lcmNpYmxlKHZhbHVlLCBvcHRNZXNzYWdlKSB7XG5cdGlmICh2YWx1ZSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3Iob3B0TWVzc2FnZSB8fCAoJ0Nhbm5vdCBjYWxsIG1ldGhvZCBvbiAnICsgdmFsdWUpKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4559\n")},775:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar abs = __webpack_require__(7890);\nvar floor = __webpack_require__(2748);\nvar ToNumber = __webpack_require__(7709);\n\nvar $isNaN = __webpack_require__(9086);\nvar $isFinite = __webpack_require__(2633);\nvar $sign = __webpack_require__(8111);\n\n// http://262.ecma-international.org/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n\tvar number = ToNumber(value);\n\tif ($isNaN(number)) { return 0; }\n\tif (number === 0 || !$isFinite(number)) { return number; }\n\treturn $sign(number) * floor(abs(number));\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzc1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFVBQVUsbUJBQU8sQ0FBQyxJQUFPO0FBQ3pCLFlBQVksbUJBQU8sQ0FBQyxJQUFTO0FBQzdCLGVBQWUsbUJBQU8sQ0FBQyxJQUFZOztBQUVuQyxhQUFhLG1CQUFPLENBQUMsSUFBa0I7QUFDdkMsZ0JBQWdCLG1CQUFPLENBQUMsSUFBcUI7QUFDN0MsWUFBWSxtQkFBTyxDQUFDLElBQWlCOztBQUVyQzs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLDJDQUEyQztBQUMzQztBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1RvSW50ZWdlci5qcz9jNmVmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGFicyA9IHJlcXVpcmUoJy4vYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCcuL2Zsb29yJyk7XG52YXIgVG9OdW1iZXIgPSByZXF1aXJlKCcuL1RvTnVtYmVyJyk7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzTmFOJyk7XG52YXIgJGlzRmluaXRlID0gcmVxdWlyZSgnLi4vaGVscGVycy9pc0Zpbml0ZScpO1xudmFyICRzaWduID0gcmVxdWlyZSgnLi4vaGVscGVycy9zaWduJyk7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjRcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBUb0ludGVnZXIodmFsdWUpIHtcblx0dmFyIG51bWJlciA9IFRvTnVtYmVyKHZhbHVlKTtcblx0aWYgKCRpc05hTihudW1iZXIpKSB7IHJldHVybiAwOyB9XG5cdGlmIChudW1iZXIgPT09IDAgfHwgISRpc0Zpbml0ZShudW1iZXIpKSB7IHJldHVybiBudW1iZXI7IH1cblx0cmV0dXJuICRzaWduKG51bWJlcikgKiBmbG9vcihhYnMobnVtYmVyKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///775\n")},7709:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar ToPrimitive = __webpack_require__(1950);\n\n// http://262.ecma-international.org/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n\tvar prim = ToPrimitive(value, Number);\n\tif (typeof prim !== 'string') {\n\t\treturn +prim; // eslint-disable-line no-implicit-coercion\n\t}\n\n\t// eslint-disable-next-line no-control-regex\n\tvar trimmed = prim.replace(/^[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+|[ \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u0085]+$/g, '');\n\tif ((/^0[ob]|^[+-]0x/).test(trimmed)) {\n\t\treturn NaN;\n\t}\n\n\treturn +trimmed; // eslint-disable-line no-implicit-coercion\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcwOS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixrQkFBa0IsbUJBQU8sQ0FBQyxJQUFlOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9OdW1iZXIuanM/MGFlMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBUb1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vVG9QcmltaXRpdmUnKTtcblxuLy8gaHR0cDovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzUuMS8jc2VjLTkuM1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFRvTnVtYmVyKHZhbHVlKSB7XG5cdHZhciBwcmltID0gVG9QcmltaXRpdmUodmFsdWUsIE51bWJlcik7XG5cdGlmICh0eXBlb2YgcHJpbSAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gK3ByaW07IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cblx0fVxuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4XG5cdHZhciB0cmltbWVkID0gcHJpbS5yZXBsYWNlKC9eWyBcXHRcXHgwYlxcZlxceGEwXFx1ZmVmZlxcblxcclxcdTIwMjhcXHUyMDI5XFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTAwODVdK3xbIFxcdFxceDBiXFxmXFx4YTBcXHVmZWZmXFxuXFxyXFx1MjAyOFxcdTIwMjlcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MDA4NV0rJC9nLCAnJyk7XG5cdGlmICgoL14wW29iXXxeWystXTB4LykudGVzdCh0cmltbWVkKSkge1xuXHRcdHJldHVybiBOYU47XG5cdH1cblxuXHRyZXR1cm4gK3RyaW1tZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW1wbGljaXQtY29lcmNpb25cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7709\n")},1950:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// http://262.ecma-international.org/5.1/#sec-9.1\n\nmodule.exports = __webpack_require__(2116);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTk1MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSwwQ0FBK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvVG9QcmltaXRpdmUuanM/MmI4ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHA6Ly8yNjIuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy81LjEvI3NlYy05LjFcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdlcy10by1wcmltaXRpdmUvZXM1Jyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1950\n")},3951:function(module){"use strict";eval("\n\n// https://262.ecma-international.org/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n\tif (x === null) {\n\t\treturn 'Null';\n\t}\n\tif (typeof x === 'undefined') {\n\t\treturn 'Undefined';\n\t}\n\tif (typeof x === 'function' || typeof x === 'object') {\n\t\treturn 'Object';\n\t}\n\tif (typeof x === 'number') {\n\t\treturn 'Number';\n\t}\n\tif (typeof x === 'boolean') {\n\t\treturn 'Boolean';\n\t}\n\tif (typeof x === 'string') {\n\t\treturn 'String';\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzk1MS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L1R5cGUuanM/NzczNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8vIGh0dHBzOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtOFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFR5cGUoeCkge1xuXHRpZiAoeCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAnTnVsbCc7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybiAnVW5kZWZpbmVkJztcblx0fVxuXHRpZiAodHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuICdPYmplY3QnO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ251bWJlcicpIHtcblx0XHRyZXR1cm4gJ051bWJlcic7XG5cdH1cblx0aWYgKHR5cGVvZiB4ID09PSAnYm9vbGVhbicpIHtcblx0XHRyZXR1cm4gJ0Jvb2xlYW4nO1xuXHR9XG5cdGlmICh0eXBlb2YgeCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gJ1N0cmluZyc7XG5cdH1cbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3951\n")},7890:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $abs = GetIntrinsic('%Math.abs%');\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function abs(x) {\n\treturn $abs(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzg5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0LzUvYWJzLmpzPzViNGEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGFicyA9IEdldEludHJpbnNpYygnJU1hdGguYWJzJScpO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYWJzKHgpIHtcblx0cmV0dXJuICRhYnMoeCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7890\n")},2748:function(module){"use strict";eval("\n\n// var modulo = require('./modulo');\nvar $floor = Math.floor;\n\n// http://262.ecma-international.org/5.1/#sec-5.2\n\nmodule.exports = function floor(x) {\n\t// return x - modulo(x, 1);\n\treturn $floor(x);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc0OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC81L2Zsb29yLmpzPzY4MWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyB2YXIgbW9kdWxvID0gcmVxdWlyZSgnLi9tb2R1bG8nKTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vLyBodHRwOi8vMjYyLmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvNS4xLyNzZWMtNS4yXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmxvb3IoeCkge1xuXHQvLyByZXR1cm4geCAtIG1vZHVsbyh4LCAxKTtcblx0cmV0dXJuICRmbG9vcih4KTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2748\n")},4445:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\n// TODO: remove, semver-major\n\nmodule.exports = __webpack_require__(210);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSx5Q0FBeUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L0dldEludHJpbnNpYy5qcz81NmI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLy8gVE9ETzogcmVtb3ZlLCBzZW12ZXItbWFqb3JcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4445\n")},3682:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\n// node v0.6 has a bug where array lengths can be Set but not Defined\nvar hasArrayLengthDefineBug = Object.defineProperty && Object.defineProperty([], 'length', { value: 1 }).length === 0;\n\n// eslint-disable-next-line global-require\nvar isArray = hasArrayLengthDefineBug && __webpack_require__(7912); // this does not depend on any other AOs.\n\nvar callBound = __webpack_require__(1924);\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\n// eslint-disable-next-line max-params\nmodule.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {\n\tif (!$defineProperty) {\n\t\tif (!IsDataDescriptor(desc)) {\n\t\t\t// ES3 does not support getters/setters\n\t\t\treturn false;\n\t\t}\n\t\tif (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// fallback for ES3\n\t\tif (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {\n\t\t\t// a non-enumerable existing property\n\t\t\treturn false;\n\t\t}\n\n\t\t// property does not exist at all, or exists but is enumerable\n\t\tvar V = desc['[[Value]]'];\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO[P] = V; // will use [[Define]]\n\t\treturn SameValue(O[P], V);\n\t}\n\tif (\n\t\thasArrayLengthDefineBug\n\t\t&& P === 'length'\n\t\t&& '[[Value]]' in desc\n\t\t&& isArray(O)\n\t\t&& O.length !== desc['[[Value]]']\n\t) {\n\t\t// eslint-disable-next-line no-param-reassign\n\t\tO.length = desc['[[Value]]'];\n\t\treturn O.length === desc['[[Value]]'];\n\t}\n\n\t$defineProperty(O, P, FromPropertyDescriptor(desc));\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzY4Mi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQzs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVMsVUFBVTtBQUN2QyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsVUFBVTs7QUFFdkc7QUFDQSx5Q0FBeUMsbUJBQU8sQ0FBQyxJQUFpQixHQUFHOztBQUVyRSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL0RlZmluZU93blByb3BlcnR5LmpzPzUxYTAiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gR2V0SW50cmluc2ljKCclT2JqZWN0LmRlZmluZVByb3BlcnR5JScsIHRydWUpO1xuXG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IG51bGw7XG5cdH1cbn1cblxuLy8gbm9kZSB2MC42IGhhcyBhIGJ1ZyB3aGVyZSBhcnJheSBsZW5ndGhzIGNhbiBiZSBTZXQgYnV0IG5vdCBEZWZpbmVkXG52YXIgaGFzQXJyYXlMZW5ndGhEZWZpbmVCdWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KFtdLCAnbGVuZ3RoJywgeyB2YWx1ZTogMSB9KS5sZW5ndGggPT09IDA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxudmFyIGlzQXJyYXkgPSBoYXNBcnJheUxlbmd0aERlZmluZUJ1ZyAmJiByZXF1aXJlKCcuLi8yMDIwL0lzQXJyYXknKTsgLy8gdGhpcyBkb2VzIG5vdCBkZXBlbmQgb24gYW55IG90aGVyIEFPcy5cblxudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC9jYWxsQm91bmQnKTtcblxudmFyICRpc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1wYXJhbXNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gRGVmaW5lT3duUHJvcGVydHkoSXNEYXRhRGVzY3JpcHRvciwgU2FtZVZhbHVlLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yLCBPLCBQLCBkZXNjKSB7XG5cdGlmICghJGRlZmluZVByb3BlcnR5KSB7XG5cdFx0aWYgKCFJc0RhdGFEZXNjcmlwdG9yKGRlc2MpKSB7XG5cdFx0XHQvLyBFUzMgZG9lcyBub3Qgc3VwcG9ydCBnZXR0ZXJzL3NldHRlcnNcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFkZXNjWydbW0NvbmZpZ3VyYWJsZV1dJ10gfHwgIWRlc2NbJ1tbV3JpdGFibGVdXSddKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gZmFsbGJhY2sgZm9yIEVTM1xuXHRcdGlmIChQIGluIE8gJiYgJGlzRW51bWVyYWJsZShPLCBQKSAhPT0gISFkZXNjWydbW0VudW1lcmFibGVdXSddKSB7XG5cdFx0XHQvLyBhIG5vbi1lbnVtZXJhYmxlIGV4aXN0aW5nIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgYXQgYWxsLCBvciBleGlzdHMgYnV0IGlzIGVudW1lcmFibGVcblx0XHR2YXIgViA9IGRlc2NbJ1tbVmFsdWVdXSddO1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE9bUF0gPSBWOyAvLyB3aWxsIHVzZSBbW0RlZmluZV1dXG5cdFx0cmV0dXJuIFNhbWVWYWx1ZShPW1BdLCBWKTtcblx0fVxuXHRpZiAoXG5cdFx0aGFzQXJyYXlMZW5ndGhEZWZpbmVCdWdcblx0XHQmJiBQID09PSAnbGVuZ3RoJ1xuXHRcdCYmICdbW1ZhbHVlXV0nIGluIGRlc2Ncblx0XHQmJiBpc0FycmF5KE8pXG5cdFx0JiYgTy5sZW5ndGggIT09IGRlc2NbJ1tbVmFsdWVdXSddXG5cdCkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHRcdE8ubGVuZ3RoID0gZGVzY1snW1tWYWx1ZV1dJ107XG5cdFx0cmV0dXJuIE8ubGVuZ3RoID09PSBkZXNjWydbW1ZhbHVlXV0nXTtcblx0fVxuXG5cdCRkZWZpbmVQcm9wZXJ0eShPLCBQLCBGcm9tUHJvcGVydHlEZXNjcmlwdG9yKGRlc2MpKTtcblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3682\n")},2188:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $SyntaxError = GetIntrinsic('%SyntaxError%');\n\nvar has = __webpack_require__(7642);\n\nvar predicates = {\n\t// https://262.ecma-international.org/6.0/#sec-property-descriptor-specification-type\n\t'Property Descriptor': function isPropertyDescriptor(Type, Desc) {\n\t\tif (Type(Desc) !== 'Object') {\n\t\t\treturn false;\n\t\t}\n\t\tvar allowed = {\n\t\t\t'[[Configurable]]': true,\n\t\t\t'[[Enumerable]]': true,\n\t\t\t'[[Get]]': true,\n\t\t\t'[[Set]]': true,\n\t\t\t'[[Value]]': true,\n\t\t\t'[[Writable]]': true\n\t\t};\n\n\t\tfor (var key in Desc) { // eslint-disable-line\n\t\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvar isData = has(Desc, '[[Value]]');\n\t\tvar IsAccessor = has(Desc, '[[Get]]') || has(Desc, '[[Set]]');\n\t\tif (isData && IsAccessor) {\n\t\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t\t}\n\t\treturn true;\n\t}\n};\n\nmodule.exports = function assertRecord(Type, recordType, argumentName, value) {\n\tvar predicate = predicates[recordType];\n\tif (typeof predicate !== 'function') {\n\t\tthrow new $SyntaxError('unknown record type: ' + recordType);\n\t}\n\tif (!predicate(Type, value)) {\n\t\tthrow new $TypeError(argumentName + ' must be a ' + recordType);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4OC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBLFVBQVUsbUJBQU8sQ0FBQyxJQUFLOztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9hc3NlcnRSZWNvcmQuanM/M2JkYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xudmFyICRTeW50YXhFcnJvciA9IEdldEludHJpbnNpYygnJVN5bnRheEVycm9yJScpO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnaGFzJyk7XG5cbnZhciBwcmVkaWNhdGVzID0ge1xuXHQvLyBodHRwczovLzI2Mi5lY21hLWludGVybmF0aW9uYWwub3JnLzYuMC8jc2VjLXByb3BlcnR5LWRlc2NyaXB0b3Itc3BlY2lmaWNhdGlvbi10eXBlXG5cdCdQcm9wZXJ0eSBEZXNjcmlwdG9yJzogZnVuY3Rpb24gaXNQcm9wZXJ0eURlc2NyaXB0b3IoVHlwZSwgRGVzYykge1xuXHRcdGlmIChUeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHR2YXIgYWxsb3dlZCA9IHtcblx0XHRcdCdbW0NvbmZpZ3VyYWJsZV1dJzogdHJ1ZSxcblx0XHRcdCdbW0VudW1lcmFibGVdXSc6IHRydWUsXG5cdFx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tTZXRdXSc6IHRydWUsXG5cdFx0XHQnW1tWYWx1ZV1dJzogdHJ1ZSxcblx0XHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdFx0fTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBEZXNjKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaXNEYXRhID0gaGFzKERlc2MsICdbW1ZhbHVlXV0nKTtcblx0XHR2YXIgSXNBY2Nlc3NvciA9IGhhcyhEZXNjLCAnW1tHZXRdXScpIHx8IGhhcyhEZXNjLCAnW1tTZXRdXScpO1xuXHRcdGlmIChpc0RhdGEgJiYgSXNBY2Nlc3Nvcikge1xuXHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1Byb3BlcnR5IERlc2NyaXB0b3JzIG1heSBub3QgYmUgYm90aCBhY2Nlc3NvciBhbmQgZGF0YSBkZXNjcmlwdG9ycycpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NlcnRSZWNvcmQoVHlwZSwgcmVjb3JkVHlwZSwgYXJndW1lbnROYW1lLCB2YWx1ZSkge1xuXHR2YXIgcHJlZGljYXRlID0gcHJlZGljYXRlc1tyZWNvcmRUeXBlXTtcblx0aWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCd1bmtub3duIHJlY29yZCB0eXBlOiAnICsgcmVjb3JkVHlwZSk7XG5cdH1cblx0aWYgKCFwcmVkaWNhdGUoVHlwZSwgdmFsdWUpKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoYXJndW1lbnROYW1lICsgJyBtdXN0IGJlIGEgJyArIHJlY29yZFR5cGUpO1xuXHR9XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2188\n")},2633:function(module){"use strict";eval("\n\nvar $isNaN = Number.isNaN || function (a) { return a !== a; };\n\nmodule.exports = Number.isFinite || function (x) { return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity; };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzMy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw0Q0FBNEM7O0FBRTVDLG1EQUFtRCIsInNvdXJjZXMiOlsid2VicGFjazovL3JlYWRpdW0tanMvLi9ub2RlX21vZHVsZXMvZXMtYWJzdHJhY3QvaGVscGVycy9pc0Zpbml0ZS5qcz9iN2UzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoYSkgeyByZXR1cm4gYSAhPT0gYTsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiAhJGlzTmFOKHgpICYmIHggIT09IEluZmluaXR5ICYmIHggIT09IC1JbmZpbml0eTsgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2633\n")},9544:function(module){"use strict";eval("\n\nmodule.exports = function isLeadingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xD800 && charCode <= 0xDBFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU0NC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNMZWFkaW5nU3Vycm9nYXRlLmpzPzA5YmMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzTGVhZGluZ1N1cnJvZ2F0ZShjaGFyQ29kZSkge1xuXHRyZXR1cm4gdHlwZW9mIGNoYXJDb2RlID09PSAnbnVtYmVyJyAmJiBjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9544\n")},9086:function(module){"use strict";eval("\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4Ni5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNOYU4uanM/ZThlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzTmFOKGEpIHtcblx0cmV0dXJuIGEgIT09IGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9086\n")},4790:function(module){"use strict";eval("\n\nmodule.exports = function isPrimitive(value) {\n\treturn value === null || (typeof value !== 'function' && typeof value !== 'object');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDc5MC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcmltaXRpdmUuanM/MDY5OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0Jyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4790\n")},2435:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar has = __webpack_require__(7642);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nmodule.exports = function IsPropertyDescriptor(ES, Desc) {\n\tif (ES.Type(Desc) !== 'Object') {\n\t\treturn false;\n\t}\n\tvar allowed = {\n\t\t'[[Configurable]]': true,\n\t\t'[[Enumerable]]': true,\n\t\t'[[Get]]': true,\n\t\t'[[Set]]': true,\n\t\t'[[Value]]': true,\n\t\t'[[Writable]]': true\n\t};\n\n\tfor (var key in Desc) { // eslint-disable-line no-restricted-syntax\n\t\tif (has(Desc, key) && !allowed[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (ES.IsDataDescriptor(Desc) && ES.IsAccessorDescriptor(Desc)) {\n\t\tthrow new $TypeError('Property Descriptors may not be both accessor and data descriptors');\n\t}\n\treturn true;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQzNS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQyxVQUFVLG1CQUFPLENBQUMsSUFBSztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNQcm9wZXJ0eURlc2NyaXB0b3IuanM/ZjhkMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBoYXMgPSByZXF1aXJlKCdoYXMnKTtcbnZhciAkVHlwZUVycm9yID0gR2V0SW50cmluc2ljKCclVHlwZUVycm9yJScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIElzUHJvcGVydHlEZXNjcmlwdG9yKEVTLCBEZXNjKSB7XG5cdGlmIChFUy5UeXBlKERlc2MpICE9PSAnT2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHR2YXIgYWxsb3dlZCA9IHtcblx0XHQnW1tDb25maWd1cmFibGVdXSc6IHRydWUsXG5cdFx0J1tbRW51bWVyYWJsZV1dJzogdHJ1ZSxcblx0XHQnW1tHZXRdXSc6IHRydWUsXG5cdFx0J1tbU2V0XV0nOiB0cnVlLFxuXHRcdCdbW1ZhbHVlXV0nOiB0cnVlLFxuXHRcdCdbW1dyaXRhYmxlXV0nOiB0cnVlXG5cdH07XG5cblx0Zm9yICh2YXIga2V5IGluIERlc2MpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuXHRcdGlmIChoYXMoRGVzYywga2V5KSAmJiAhYWxsb3dlZFtrZXldKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0aWYgKEVTLklzRGF0YURlc2NyaXB0b3IoRGVzYykgJiYgRVMuSXNBY2Nlc3NvckRlc2NyaXB0b3IoRGVzYykpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignUHJvcGVydHkgRGVzY3JpcHRvcnMgbWF5IG5vdCBiZSBib3RoIGFjY2Vzc29yIGFuZCBkYXRhIGRlc2NyaXB0b3JzJyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2435\n")},5424:function(module){"use strict";eval("\n\nmodule.exports = function isTrailingSurrogate(charCode) {\n\treturn typeof charCode === 'number' && charCode >= 0xDC00 && charCode <= 0xDFFF;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQyNC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvaXNUcmFpbGluZ1N1cnJvZ2F0ZS5qcz9lNGZjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc1RyYWlsaW5nU3Vycm9nYXRlKGNoYXJDb2RlKSB7XG5cdHJldHVybiB0eXBlb2YgY2hhckNvZGUgPT09ICdudW1iZXInICYmIGNoYXJDb2RlID49IDB4REMwMCAmJiBjaGFyQ29kZSA8PSAweERGRkY7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5424\n")},1645:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\n\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTY0NS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixtQkFBbUIsbUJBQU8sQ0FBQyxHQUFlOztBQUUxQztBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVhZGl1bS1qcy8uL25vZGVfbW9kdWxlcy9lcy1hYnN0cmFjdC9oZWxwZXJzL21heFNhZmVJbnRlZ2VyLmpzPzJhMmYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgJE1hdGggPSBHZXRJbnRyaW5zaWMoJyVNYXRoJScpO1xudmFyICROdW1iZXIgPSBHZXRJbnRyaW5zaWMoJyVOdW1iZXIlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gJE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8ICRNYXRoLnBvdygyLCA1MykgLSAxO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1645\n")},823:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nvar GetIntrinsic = __webpack_require__(210);\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = __webpack_require__(5559);\n\nmodule.exports = function regexTester(regex) {\n\treturn callBind($test, regex);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLG1CQUFtQixtQkFBTyxDQUFDLEdBQWU7O0FBRTFDOztBQUVBLGVBQWUsbUJBQU8sQ0FBQyxJQUFXOztBQUVsQztBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvcmVnZXhUZXN0ZXIuanM/MTNkNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciAkdGVzdCA9IEdldEludHJpbnNpYygnUmVnRXhwLnByb3RvdHlwZS50ZXN0Jyk7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlZ2V4VGVzdGVyKHJlZ2V4KSB7XG5cdHJldHVybiBjYWxsQmluZCgkdGVzdCwgcmVnZXgpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///823\n")},8111:function(module){"use strict";eval("\n\nmodule.exports = function sign(number) {\n\treturn number >= 0 ? 1 : -1;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODExMS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWFkaXVtLWpzLy4vbm9kZV9tb2R1bGVzL2VzLWFic3RyYWN0L2hlbHBlcnMvc2lnbi5qcz9jNjA0Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRyZXR1cm4gbnVtYmVyID49IDAgPyAxIDogLTE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8111\n")}},__webpack_module_cache__={};function __webpack_require__(t){var n=__webpack_module_cache__[t];if(void 0!==n)return n.exports;var e=__webpack_module_cache__[t]={exports:{}};return __webpack_modules__[t](e,e.exports,__webpack_require__),e.exports}__webpack_require__.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return __webpack_require__.d(n,{a:n}),n},__webpack_require__.d=function(t,n){for(var e in n)__webpack_require__.o(n,e)&&!__webpack_require__.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:n[e]})},__webpack_require__.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)};var __webpack_exports__=__webpack_require__(8501)})(); \ No newline at end of file diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/IR2Activity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/Deprecated.kt similarity index 91% rename from readium/navigator/src/main/java/org/readium/r2/navigator/IR2Activity.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/Deprecated.kt index 9304103cf8..2b2b39551e 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/IR2Activity.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/Deprecated.kt @@ -14,6 +14,7 @@ import android.view.View import org.readium.r2.navigator.pager.R2ViewPager import org.readium.r2.shared.publication.Publication +@Deprecated("Use navigator fragments.", level = DeprecationLevel.ERROR) interface IR2Activity { val publication: Publication @@ -38,6 +39,7 @@ interface IR2Activity { fun highlightAnnotationMarkActivated(id: String) {} } +@Deprecated("Use TtsNavigator.", level = DeprecationLevel.ERROR) interface IR2TTS { fun playTextChanged(text: String) {} fun playStateChanged(playing: Boolean) {} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt index 3e0c93b107..5f482b273e 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt @@ -171,7 +171,7 @@ interface VisualNavigator : Navigator { /** * Current reading progression direction. */ - @Deprecated("Use `presentation.value.readingProgression` instead", ReplaceWith("presentation.value.readingProgression")) + @Deprecated("Use `presentation.value.readingProgression` instead", ReplaceWith("presentation.value.readingProgression"), level = DeprecationLevel.ERROR) val readingProgression: PublicationReadingProgression } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt index 760a4eecb1..42bc4b07d4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt @@ -38,6 +38,8 @@ import org.readium.r2.navigator.extensions.optRectF import org.readium.r2.navigator.input.InputModifier import org.readium.r2.navigator.input.Key import org.readium.r2.navigator.input.KeyEvent +import org.readium.r2.navigator.preferences.ReadingProgression +import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.optNullableString @@ -46,31 +48,27 @@ import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.ReadingProgression import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.use import timber.log.Timber -@OptIn(ExperimentalDecorator::class) +@OptIn(ExperimentalDecorator::class, ExperimentalReadiumApi::class) open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(context, attrs) { interface Listener { val readingProgression: ReadingProgression fun onResourceLoaded(link: Link?, webView: R2BasicWebView, url: String?) {} - fun onPageLoaded() - fun onPageChanged(pageIndex: Int, totalPages: Int, url: String) - fun onPageEnded(end: Boolean) - fun onScroll() - fun onTap(point: PointF): Boolean - fun onDragStart(event: DragEvent): Boolean - fun onDragMove(event: DragEvent): Boolean - fun onDragEnd(event: DragEvent): Boolean + fun onPageLoaded() {} + fun onPageChanged(pageIndex: Int, totalPages: Int, url: String) {} + fun onPageEnded(end: Boolean) {} + fun onTap(point: PointF): Boolean = false + fun onDragStart(event: DragEvent): Boolean = false + fun onDragMove(event: DragEvent): Boolean = false + fun onDragEnd(event: DragEvent): Boolean = false fun onKey(event: KeyEvent): Boolean = false fun onDecorationActivated(id: DecorationId, group: String, rect: RectF, point: PointF): Boolean = false - fun onProgressionChanged() - fun onHighlightActivated(id: String) - fun onHighlightAnnotationMarkActivated(id: String) + fun onProgressionChanged() {} fun goForward(animated: Boolean = false, completion: () -> Unit = {}): Boolean = false fun goBackward(animated: Boolean = false, completion: () -> Unit = {}): Boolean = false @@ -98,11 +96,17 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte fun goToNextResource(jump: Boolean, animated: Boolean): Boolean = false @InternalReadiumApi fun goToPreviousResource(jump: Boolean, animated: Boolean): Boolean = false + + @Deprecated("Not available anymore", level = DeprecationLevel.ERROR) + fun onScroll() {} + @Deprecated("Not available anymore", level = DeprecationLevel.ERROR) + fun onHighlightActivated(id: String) {} + @Deprecated("Not available anymore", level = DeprecationLevel.ERROR) + fun onHighlightAnnotationMarkActivated(id: String) {} } var listener: Listener? = null internal var preferences: SharedPreferences? = null - internal var useLegacySettings: Boolean = false var resourceUrl: String? = null @@ -187,13 +191,9 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte super.destroy() } - @android.webkit.JavascriptInterface open fun scrollRight(animated: Boolean = false) { uiScope.launch { val listener = listener ?: return@launch - listener.onScroll() - - val isRtl = (listener.readingProgression == ReadingProgression.RTL) fun goRight(jump: Boolean) { if (listener.readingProgression == ReadingProgression.RTL) { @@ -222,11 +222,9 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte } } - @android.webkit.JavascriptInterface open fun scrollLeft(animated: Boolean = false) { uiScope.launch { val listener = listener ?: return@launch - listener.onScroll() fun goLeft(jump: Boolean) { if (listener.readingProgression == ReadingProgression.RTL) { @@ -255,10 +253,7 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte } } - /** - * Called from the JS code when a tap is detected. - * If the JS indicates the tap is being handled within the web view, don't take action, - * + /* * Returns whether the web view should prevent the default behavior for this tap. */ @android.webkit.JavascriptInterface @@ -283,23 +278,7 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte return handleFootnote(event.targetElement) } - // Skips to previous/next pages if the tap is on the content edges. - val clientWidth = computeHorizontalScrollExtent() - val thresholdRange = 0.0..(0.2 * clientWidth) - - // FIXME: Call listener.onTap if scrollLeft|Right fails - return when { - useLegacySettings && thresholdRange.contains(event.point.x) -> { - scrollLeft(false) - true - } - useLegacySettings && thresholdRange.contains(clientWidth - event.point.x) -> { - scrollRight(false) - true - } - else -> - runBlocking(uiScope.coroutineContext) { listener?.onTap(event.point) ?: false } - } + return runBlocking(uiScope.coroutineContext) { listener?.onTap(event.point) ?: false } } /** @@ -381,7 +360,7 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater // Inflate the custom layout/view - val customView = inflater.inflate(R.layout.popup_footnote, null) + val customView = inflater.inflate(R.layout.readium_navigator_popup_footnote, null) // Initialize a new instance of popup window val mPopupWindow = PopupWindow( @@ -487,9 +466,6 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte fun fromJSONObject(obj: JSONObject?): DragEvent? { obj ?: return null - val x = obj.optDouble("x").toFloat() - val y = obj.optDouble("y").toFloat() - return DragEvent( defaultPrevented = obj.optBoolean("defaultPrevented"), startPoint = PointF( @@ -526,20 +502,6 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte Timber.d("JavaScript: $message") } - @android.webkit.JavascriptInterface - fun highlightActivated(id: String) { - uiScope.launch { - listener?.onHighlightActivated(id) - } - } - - @android.webkit.JavascriptInterface - fun highlightAnnotationMarkActivated(id: String) { - uiScope.launch { - listener?.onHighlightAnnotationMarkActivated(id) - } - } - fun Boolean.toInt() = if (this) 1 else 0 fun scrollToStart() { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt index 0434afe439..21936910d3 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt @@ -40,7 +40,6 @@ class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView(context, private val uiScope = CoroutineScope(Dispatchers.Main) - @android.webkit.JavascriptInterface override fun scrollRight(animated: Boolean) { super.scrollRight(animated) uiScope.launch { @@ -53,7 +52,6 @@ class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView(context, } } - @android.webkit.JavascriptInterface override fun scrollLeft(animated: Boolean) { super.scrollLeft(animated) uiScope.launch { @@ -557,7 +555,7 @@ class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView(context, } override fun computeScroll() { - if (!useLegacySettings && scrollMode) { + if (scrollMode) { return super.computeScroll() } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/Deprecated.kt new file mode 100644 index 0000000000..bc807c3806 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/Deprecated.kt @@ -0,0 +1,21 @@ +package org.readium.r2.navigator.audiobook + +import android.media.MediaPlayer +import org.readium.r2.shared.publication.Link + +@Deprecated("Build your own UI upon AudiobookNavigator instead.", level = DeprecationLevel.ERROR) +open class R2AudiobookActivity + +@Deprecated("Use the new MediaNavigator API.", level = DeprecationLevel.ERROR) +class R2MediaPlayer(private var items: List) : + MediaPlayer.OnPreparedListener { + + override fun onPrepared(mp: MediaPlayer?) { + } +} + +@Deprecated("Use the new MediaNavigator API.", level = DeprecationLevel.ERROR) +interface MediaPlayerCallback { + fun onPrepared() + fun onComplete(index: Int, currentPosition: Int, duration: Int) +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2AudiobookActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2AudiobookActivity.kt deleted file mode 100644 index 617aadf557..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2AudiobookActivity.kt +++ /dev/null @@ -1,440 +0,0 @@ -package org.readium.r2.navigator.audiobook - -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.content.SharedPreferences -import android.net.Uri -import android.os.Bundle -import android.os.Handler -import android.widget.SeekBar -import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContextCompat -import androidx.lifecycle.Lifecycle -import java.util.concurrent.TimeUnit -import kotlin.coroutines.CoroutineContext -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import org.readium.r2.navigator.BuildConfig.DEBUG -import org.readium.r2.navigator.IR2Activity -import org.readium.r2.navigator.Navigator -import org.readium.r2.navigator.NavigatorDelegate -import org.readium.r2.navigator.R -import org.readium.r2.navigator.databinding.ActivityR2AudiobookBinding -import org.readium.r2.shared.extensions.getPublication -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.indexOfFirstWithHref -import org.readium.r2.shared.publication.services.isRestricted -import timber.log.Timber - -open class R2AudiobookActivity : AppCompatActivity(), CoroutineScope, IR2Activity, MediaPlayerCallback, Navigator { - - override val currentLocator: StateFlow get() = _currentLocator - private val _currentLocator = MutableStateFlow(Locator(href = "#", type = "")) - private lateinit var binding: ActivityR2AudiobookBinding - - private fun notifyCurrentLocation() { - val locator = publication.readingOrder[currentResource].let { resource -> - val progression = mediaPlayer - .takeIf { it.duration > 0 } - ?.let { it.currentPosition / it.duration } - ?: 0.0 - - // FIXME: Add totalProgression - Locator( - href = resource.href, - type = resource.type ?: "audio/*", - title = resource.title, - locations = Locator.Locations( - fragments = listOf( - "t=${TimeUnit.MILLISECONDS.toSeconds(mediaPlayer.currentPosition.toLong())}" - ), - progression = progression - ) - ) - } - - if (locator == _currentLocator.value) { - return - } - - _currentLocator.value = locator - navigatorDelegate?.locationDidChange(navigator = this, locator = locator) - } - - override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { - loadedInitialLocator = true - currentResource = publication.readingOrder.indexOfFirstWithHref(locator.href) ?: return false - mediaPlayer.goTo(currentResource) - seek(locator.locations) - - binding.playPause.callOnClick() - notifyCurrentLocation() - - return true - } - - override fun go(link: Link, animated: Boolean, completion: () -> Unit): Boolean { - val locator = publication.locatorFromLink(link) ?: return false - return go(locator) - } - - override fun goForward(animated: Boolean, completion: () -> Unit): Boolean { - if (currentResource < publication.readingOrder.size - 1) { - currentResource++ - } - - mediaPlayer.next() - binding.playPause.callOnClick() - return true - } - - override fun goBackward(animated: Boolean, completion: () -> Unit): Boolean { - if (currentResource > 0) { - currentResource-- - } - - mediaPlayer.previous() - binding.playPause.callOnClick() - return true - } - - /** - * Context of this scope. - */ - override val coroutineContext: CoroutineContext - get() = Dispatchers.Main - - override lateinit var preferences: SharedPreferences - override lateinit var publication: Publication - override lateinit var publicationIdentifier: String - override lateinit var publicationFileName: String - override lateinit var publicationPath: String - override var bookId: Long = -1 - - var currentResource = 0 - - var startTime = 0.0 - private var finalTime = 0.0 - - private val forwardTime = 10000 - private val backwardTime = 10000 - - lateinit var mediaPlayer: R2MediaPlayer - private var loadedInitialLocator = false - - protected var navigatorDelegate: NavigatorDelegate? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityR2AudiobookBinding.inflate(layoutInflater) - setContentView(binding.root) - - preferences = getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) - - publicationPath = intent.getStringExtra("publicationPath") ?: throw Exception("publicationPath required") - publicationFileName = intent.getStringExtra("publicationFileName") ?: throw Exception("publicationFileName required") - val baseUrl = intent.getStringExtra("baseUrl") ?: throw Exception("Intent extra `baseUrl` is required. Provide the URL returned by Server.addPublication()") - - publication = intent.getPublication(this) - publicationIdentifier = publication.metadata.identifier ?: publication.metadata.title - - require(!publication.isRestricted) { "The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection." } - - title = null - - val readingOrderOverHttp = publication.readingOrder.map { it.withBaseUrl(baseUrl) } - mediaPlayer = R2MediaPlayer(readingOrderOverHttp, this) - - Handler(mainLooper).postDelayed({ - - if (this.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) { - - if (!loadedInitialLocator) { - go(publication.readingOrder.first()) - } - - binding.seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { - /** - * Notification that the progress level has changed. Clients can use the fromUser parameter - * to distinguish user-initiated changes from those that occurred programmatically. - * - * @param seekBar The SeekBar whose progress has changed - * @param progress The current progress level. This will be in the range min..max where min - * @param fromUser True if the progress change was initiated by the user. - */ - override fun onProgressChanged( - seekBar: SeekBar?, - progress: Int, - fromUser: Boolean - ) { - if (!fromUser) { - return - } - mediaPlayer.seekTo(progress) - if (DEBUG) Timber.d("progress $progress") - } - - /** - * Notification that the user has started a touch gesture. Clients may want to use this - * to disable advancing the seekbar. - * @param seekBar The SeekBar in which the touch gesture began - */ - override fun onStartTrackingTouch(seekBar: SeekBar?) { - // do nothing - isSeekTracking = true - if (DEBUG) Timber.d("start tracking") - } - - /** - * Notification that the user has finished a touch gesture. Clients may want to use this - * to re-enable advancing the seekbar. - * @param seekBar The SeekBar in which the touch gesture began - */ - override fun onStopTrackingTouch(seekBar: SeekBar?) { - // do nothing - isSeekTracking = false - if (DEBUG) Timber.d("stop tracking") - } - }) - - binding.playPause.setOnClickListener { - mediaPlayer.let { - if (it.isPlaying) { - it.pause() - } else { - if (it.isPaused) { - it.resume() - } else { - it.startPlayer() - } - Handler(mainLooper).postDelayed(updateSeekTime, 100) - } - this.updateUI() - } - } - - binding.playPause.callOnClick() - - binding.fastForward.setOnClickListener { - if (startTime.toInt() + forwardTime <= finalTime) { - startTime += forwardTime - mediaPlayer.seekTo(startTime) - } - } - - binding.fastBack.setOnClickListener { - if (startTime.toInt() - backwardTime > 0) { - startTime -= backwardTime - mediaPlayer.seekTo(startTime) - } - } - - binding.nextChapter.setOnClickListener { - goForward(false) {} - } - - binding.prevChapter.setOnClickListener { - goBackward(false) {} - } - } - }, 100) - } - - private fun updateUI() { - - if (currentResource == publication.readingOrder.size - 1) { - binding.nextChapter.isEnabled = false - binding.nextChapter.alpha = .5f - } else { - binding.nextChapter.isEnabled = true - binding.nextChapter.alpha = 1.0f - } - if (currentResource == 0) { - binding.prevChapter.isEnabled = false - binding.prevChapter.alpha = .5f - } else { - binding.prevChapter.isEnabled = true - binding.prevChapter.alpha = 1.0f - } - - val current = publication.readingOrder[currentResource] - binding.chapterView.text = current.title - - if (mediaPlayer.isPlaying) { - binding.playPause.setImageDrawable(ContextCompat.getDrawable(this@R2AudiobookActivity, R.drawable.ic_pause_white_24dp)) - } else { - binding.playPause.setImageDrawable(ContextCompat.getDrawable(this@R2AudiobookActivity, R.drawable.ic_play_arrow_white_24dp)) - } - - finalTime = mediaPlayer.duration - startTime = mediaPlayer.currentPosition - - binding.seekBar.max = finalTime.toInt() - - binding.chapterTime.text = String.format( - "%d:%d", - TimeUnit.MILLISECONDS.toMinutes(finalTime.toLong()), - TimeUnit.MILLISECONDS.toSeconds(finalTime.toLong()) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(finalTime.toLong())) - ) - - binding.progressTime.text = String.format( - "%d:%d", - TimeUnit.MILLISECONDS.toMinutes(startTime.toLong()), - TimeUnit.MILLISECONDS.toSeconds(startTime.toLong()) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(startTime.toLong())) - ) - - binding.seekBar.progress = startTime.toInt() - - notifyCurrentLocation() - } - - private fun seek(locations: Locator.Locations) { - if (!mediaPlayer.isPrepared) { - pendingSeekLocation = locations - return - } - - pendingSeekLocation = null - - val time = locations.fragments.firstOrNull()?.let { - var time = it - if (time.startsWith("#t=") || time.startsWith("t=")) { - time = time.substring(time.indexOf('=') + 1) - } - time - } - time?.let { - mediaPlayer.seekTo(TimeUnit.SECONDS.toMillis(it.toLong()).toInt()) - } ?: run { - val progression = locations.progression - val duration = mediaPlayer.duration - Timber.d("progression used") - if (progression != null) { - Timber.d("ready to seek") - mediaPlayer.seekTo(progression * duration) - } - } - } - - private var pendingSeekLocation: Locator.Locations? = null - var isSeekTracking = false - - private fun seekIfNeeded() { - pendingSeekLocation?.let { locations -> - seek(locations) - } - } - - override fun onPrepared() { - seekIfNeeded() - Handler(mainLooper).postDelayed(updateSeekTime, 100) - updateUI() - } - - override fun onComplete(index: Int, currentPosition: Int, duration: Int) { - if (currentResource == index && currentPosition > 0 && currentResource < publication.readingOrder.size - 1 && currentPosition >= duration - 200 && !isSeekTracking) { - Handler(mainLooper).postDelayed({ - if (currentResource < publication.readingOrder.size - 1) { - currentResource++ - } - mediaPlayer.next() - binding.playPause.callOnClick() - }, 100) - } else if (currentPosition > 0 && currentResource == publication.readingOrder.size - 1) { - mediaPlayer.pause() - binding.playPause.setImageDrawable(ContextCompat.getDrawable(this@R2AudiobookActivity, R.drawable.ic_play_arrow_white_24dp)) - } else { - mediaPlayer.pause() - binding.playPause.setImageDrawable(ContextCompat.getDrawable(this@R2AudiobookActivity, R.drawable.ic_play_arrow_white_24dp)) - } - } - - private val updateSeekTime = object : Runnable { - override fun run() { - if (mediaPlayer.isPrepared) { - mediaPlayer.let { - startTime = it.mediaPlayer.currentPosition.toDouble() - } - binding.progressTime.text = String.format( - "%d:%d", - TimeUnit.MILLISECONDS.toMinutes(startTime.toLong()), - TimeUnit.MILLISECONDS.toSeconds(startTime.toLong()) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(startTime.toLong())) - ) - binding.seekBar.progress = startTime.toInt() - - notifyCurrentLocation() - - Handler(mainLooper).postDelayed(this, 100) - } - } - } - - override fun finish() { - setResult(Activity.RESULT_OK, intent) - super.finish() - } - - override fun onResume() { - super.onResume() - mediaPlayer.resume() - } - - override fun onPause() { - super.onPause() - mediaPlayer.pause() - } - - override fun onStop() { - super.onStop() - mediaPlayer.stop() - } - - override fun onDestroy() { - super.onDestroy() - mediaPlayer.stop() - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - if (requestCode == 2 && resultCode == Activity.RESULT_OK) { - if (data != null) { - val locator = data.getParcelableExtra("locator") as? Locator - - locator?.let { - // href is the link to the page in the toc - var href = locator.href - - if (href.indexOf("#") > 0) { - href = href.substring(0, href.indexOf("#")) - } - - var index = 0 - for (resource in publication.readingOrder) { - if (resource.href.endsWith(href)) { - currentResource = index - break - } - index++ - } - go(locator) - } - } - } - } -} - -internal fun Link.withBaseUrl(baseUrl: String): Link { - // Already an absolute URL? - if (Uri.parse(href).scheme != null) { - return this - } - - check(!baseUrl.endsWith("/")) - check(href.startsWith("/")) - return copy(href = baseUrl + href) -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2MediaPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2MediaPlayer.kt deleted file mode 100644 index 1347a278b4..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/audiobook/R2MediaPlayer.kt +++ /dev/null @@ -1,153 +0,0 @@ -package org.readium.r2.navigator.audiobook - -import android.app.ProgressDialog -import android.media.MediaPlayer -import android.media.MediaPlayer.OnPreparedListener -import android.net.Uri -import java.io.IOException -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import org.readium.r2.shared.publication.Link - -class R2MediaPlayer(private var items: List, private var callback: MediaPlayerCallback) : OnPreparedListener { - - private val uiScope = CoroutineScope(Dispatchers.Main) - - var progress: ProgressDialog? = null - - var mediaPlayer: MediaPlayer = MediaPlayer() - - val isPlaying: Boolean - get() = mediaPlayer.isPlaying - - val duration: Double - get() = mediaPlayer.duration.toDouble() // if (isPrepared) {mediaPlayer.duration.toDouble()}else {0.0} - - val currentPosition: Double - get() = mediaPlayer.currentPosition.toDouble() // if (isPrepared) {mediaPlayer.currentPosition.toDouble()}else {0.0} - - var isPaused: Boolean - var isPrepared: Boolean - - private var index: Int - - init { - isPaused = false - isPrepared = false - index = 0 - if (mediaPlayer.isPlaying) { - mediaPlayer.stop() - mediaPlayer.release() - } - toggleProgress(true) - } - - /** - * Called when the media file is ready for playback. - * - * @param mp the MediaPlayer that is ready for playback - */ - override fun onPrepared(mp: MediaPlayer?) { - toggleProgress(false) - this.start() - isPrepared = true - callback.onPrepared() - } - - fun startPlayer() { - mediaPlayer.reset() - try { - mediaPlayer.setDataSource(Uri.parse(items[index].href).toString()) - mediaPlayer.setOnPreparedListener(this) - mediaPlayer.prepareAsync() - toggleProgress(true) - } catch (e: IllegalArgumentException) { - e.printStackTrace() - } catch (e: IllegalStateException) { - e.printStackTrace() - } catch (e: IOException) { - e.printStackTrace() - } - } - - private fun toggleProgress(show: Boolean) { - uiScope.launch { - if (show) progress?.show() - else progress?.hide() - } - } - - fun seekTo(progression: Any) { - when (progression) { - is Double -> mediaPlayer.seekTo(progression.toInt()) - is Int -> mediaPlayer.seekTo(progression) - else -> mediaPlayer.seekTo(progression.toString().toInt()) - } - } - - fun stop() { - if (isPrepared) { - mediaPlayer.stop() - isPrepared = false - } - } - - fun pause() { - if (isPrepared) { - mediaPlayer.pause() - isPaused = true - } - } - - fun start() { - mediaPlayer.start() - isPaused = false - isPrepared = false - mediaPlayer.setOnCompletionListener { - callback.onComplete(index, it.currentPosition, it.duration) - } - } - - fun resume() { - if (isPrepared) { - mediaPlayer.start() - isPaused = false - } - } - - fun goTo(index: Int) { - this.index = index - isPaused = false - isPrepared = false - if (mediaPlayer.isPlaying) { - mediaPlayer.stop() - } - toggleProgress(true) - } - - fun previous() { - index -= 1 - isPaused = false - isPrepared = false - if (mediaPlayer.isPlaying) { - mediaPlayer.stop() - } - toggleProgress(true) - } - - fun next() { - index += 1 - isPaused = false - isPrepared = false - if (mediaPlayer.isPlaying) { - mediaPlayer.stop() - } - toggleProgress(true) - } -} - -interface MediaPlayerCallback { - fun onPrepared() - fun onComplete(index: Int, currentPosition: Int, duration: Int) -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/Deprecated.kt new file mode 100644 index 0000000000..7d963b4eb2 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/Deprecated.kt @@ -0,0 +1,16 @@ +/* + * Module: r2-navigator-kotlin + * Developers: Aferdita Muriqi, Mostapha Idoubihi + * + * Copyright (c) 2018. Readium Foundation. All rights reserved. + * Use of this source code is governed by a BSD-style license which is detailed in the + * LICENSE file present in the project repository where this source code is maintained. + */ + +package org.readium.r2.navigator.cbz + +@Deprecated("Use ImageNavigatorFragment in your own activity instead.", level = DeprecationLevel.ERROR) +open class R2CbzActivity + +// This is for lint to pass. +private val fake = null diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt deleted file mode 100644 index 8a3abda440..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Module: r2-navigator-kotlin - * Developers: Aferdita Muriqi, Mostapha Idoubihi - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.navigator.cbz - -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.content.SharedPreferences -import android.graphics.PointF -import android.os.Build -import android.os.Bundle -import android.view.View -import android.view.WindowManager -import androidx.appcompat.app.AppCompatActivity -import androidx.lifecycle.Observer -import androidx.lifecycle.asLiveData -import kotlin.coroutines.CoroutineContext -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch -import org.readium.r2.navigator.IR2Activity -import org.readium.r2.navigator.NavigatorDelegate -import org.readium.r2.navigator.R -import org.readium.r2.navigator.VisualNavigator -import org.readium.r2.navigator.image.ImageNavigatorFragment -import org.readium.r2.navigator.input.InputListener -import org.readium.r2.navigator.pager.R2PagerAdapter -import org.readium.r2.navigator.pager.R2ViewPager -import org.readium.r2.navigator.util.CompositeFragmentFactory -import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.extensions.getPublication -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.ReadingProgression - -open class R2CbzActivity : AppCompatActivity(), CoroutineScope, IR2Activity, VisualNavigator, ImageNavigatorFragment.Listener { - - private val navigatorFragment: ImageNavigatorFragment - get() = supportFragmentManager.findFragmentById(R.id.image_navigator) as ImageNavigatorFragment - - protected var navigatorDelegate: NavigatorDelegate? = null - - protected val positions: List get() = navigatorFragment.positions - - val currentPagerPosition: Int get() = navigatorFragment.currentPagerPosition - - override val currentLocator: StateFlow - get() = navigatorFragment.currentLocator - - override val publicationView: View - get() = navigatorFragment.publicationView - - @ExperimentalReadiumApi - override val presentation: StateFlow - get() = navigatorFragment.presentation - - @ExperimentalReadiumApi - override fun addInputListener(listener: InputListener) { - navigatorFragment.addInputListener(listener) - } - - @ExperimentalReadiumApi - override fun removeInputListener(listener: InputListener) { - navigatorFragment.removeInputListener(listener) - } - - override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { - return navigatorFragment.go(locator, animated, completion) - } - - override fun go(link: Link, animated: Boolean, completion: () -> Unit): Boolean { - return navigatorFragment.go(link, animated, completion) - } - - override fun goForward(animated: Boolean, completion: () -> Unit): Boolean { - return navigatorFragment.goForward(animated, completion) - } - - override fun goBackward(animated: Boolean, completion: () -> Unit): Boolean { - return navigatorFragment.goBackward(animated, completion) - } - - @Deprecated("Use `presentation.value.readingProgression` instead", replaceWith = ReplaceWith("presentation.value.readingProgression")) - override val readingProgression: ReadingProgression - get() = navigatorFragment.readingProgression - - /** - * Context of this scope. - */ - override val coroutineContext: CoroutineContext - get() = Dispatchers.Main - - override lateinit var preferences: SharedPreferences - override lateinit var resourcePager: R2ViewPager - override lateinit var publicationPath: String - override lateinit var publication: Publication - override lateinit var publicationIdentifier: String - override lateinit var publicationFileName: String - - override var bookId: Long = -1 - - var resources: List = emptyList() - lateinit var adapter: R2PagerAdapter - - override fun onCreate(savedInstanceState: Bundle?) { - preferences = getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) - - publicationPath = intent.getStringExtra("publicationPath") ?: throw Exception("publicationPath required") - publicationFileName = intent.getStringExtra("publicationFileName") ?: throw Exception("publicationFileName required") - publication = intent.getPublication(this) - - publicationIdentifier = publication.metadata.identifier ?: publication.metadata.title - title = publication.metadata.title - - val initialLocator = intent.getParcelableExtra("locator") as? Locator - - // This must be done before the call to super.onCreate, including by reading apps. - // Because they may want to set their own factories, let's use a CompositeFragmentFactory that retains - // previously set factories. - supportFragmentManager.fragmentFactory = CompositeFragmentFactory( - supportFragmentManager.fragmentFactory, - ImageNavigatorFragment.createFactory(publication, initialLocator = initialLocator, listener = this) - ) - - super.onCreate(savedInstanceState) - - setContentView(R.layout.activity_r2_image) - - resourcePager = navigatorFragment.resourcePager - - navigatorFragment.currentLocator.asLiveData().observe( - this, - Observer { locator -> - locator ?: return@Observer - @Suppress("DEPRECATION") - navigatorDelegate?.locationDidChange(this, locator) - } - ) - - // Add support for display cutout. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES - } - } - - override fun finish() { - setResult(Activity.RESULT_OK, intent) - super.finish() - } - - @Deprecated("Use goForward instead", replaceWith = ReplaceWith("goForward()"), level = DeprecationLevel.ERROR) - override fun nextResource(v: View?) { - navigatorFragment.goForward() - } - - @Deprecated("Use goBackward instead", replaceWith = ReplaceWith("goBackward()"), level = DeprecationLevel.ERROR) - override fun previousResource(v: View?) { - navigatorFragment.goBackward() - } - - @Suppress("DEPRECATION") - override fun toggleActionBar() { - if (allowToggleActionBar) { - launch { - if (supportActionBar!!.isShowing) { - resourcePager.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - or View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar - or View.SYSTEM_UI_FLAG_IMMERSIVE - ) - } else { - resourcePager.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - ) - } - } - } - } - - override fun toggleActionBar(v: View?) { - toggleActionBar() - } - - override fun onTap(point: PointF): Boolean { - val viewWidth = navigatorFragment.requireView().width - val leftRange = 0.0..(0.2 * viewWidth) - - when { - leftRange.contains(point.x) -> navigatorFragment.goBackward(animated = true) - leftRange.contains(viewWidth - point.x) -> navigatorFragment.goForward(animated = true) - else -> toggleActionBar() - } - - return true - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == 2 && resultCode == Activity.RESULT_OK) { - if (data != null) { - - val locator = data.getParcelableExtra("locator") as? Locator - - locator?.let { - fun setCurrent(resources: List) { - for (index in 0 until resources.count()) { - val resource = resources[index] - if (resource.endsWith(locator.href)) { - resourcePager.currentItem = index - break - } - } - } - - go(locator) - - setCurrent(resources) - } - - @Suppress("DEPRECATION") - if (supportActionBar!!.isShowing && allowToggleActionBar) { - resourcePager.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - or View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar - or View.SYSTEM_UI_FLAG_IMMERSIVE - ) - } - } - } - super.onActivityResult(requestCode, resultCode, data) - } -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/divina/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/divina/Deprecated.kt new file mode 100755 index 0000000000..b322ff5208 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/divina/Deprecated.kt @@ -0,0 +1,19 @@ +/* + * Module: r2-navigator-kotlin + * Developers: Aferdita Muriqi + * + * Copyright (c) 2018. Readium Foundation. All rights reserved. + * Use of this source code is governed by a BSD-style license which is detailed in the + * LICENSE file present in the project repository where this source code is maintained. + */ + +package org.readium.r2.navigator.divina + +@Deprecated( + "Use ImageNavigatorFragment in your own activity to get a basic support for DiViNa.", + level = DeprecationLevel.ERROR +) +open class R2DiViNaActivity + +// This is for lint to pass. +private val fake = null diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/divina/R2DiViNaActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/divina/R2DiViNaActivity.kt deleted file mode 100755 index 5bc5237657..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/divina/R2DiViNaActivity.kt +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Module: r2-navigator-kotlin - * Developers: Aferdita Muriqi - * - * Copyright (c) 2018. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.navigator.divina - -import android.annotation.SuppressLint -import android.app.Activity -import android.content.Context -import android.content.SharedPreferences -import android.os.Bundle -import android.view.View -import android.webkit.WebView -import androidx.appcompat.app.AppCompatActivity -import androidx.webkit.WebViewClientCompat -import kotlin.coroutines.CoroutineContext -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import org.readium.r2.navigator.IR2Activity -import org.readium.r2.navigator.R2BasicWebView -import org.readium.r2.navigator.VisualNavigator -import org.readium.r2.navigator.databinding.ActivityR2DivinaBinding -import org.readium.r2.shared.extensions.getPublication -import org.readium.r2.shared.publication.Publication - -open class R2DiViNaActivity : AppCompatActivity(), CoroutineScope, IR2Activity, VisualNavigator.Listener { - - /** - * Context of this scope. - */ - override val coroutineContext: CoroutineContext - get() = Dispatchers.Main - - override lateinit var preferences: SharedPreferences - override lateinit var publication: Publication - override lateinit var publicationIdentifier: String - override lateinit var publicationPath: String - override lateinit var publicationFileName: String - override var bookId: Long = -1 - - lateinit var divinaWebView: R2BasicWebView - - private lateinit var binding: ActivityR2DivinaBinding - - @SuppressLint("SetJavaScriptEnabled") - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityR2DivinaBinding.inflate(layoutInflater) - setContentView(binding.root) - - preferences = getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) - divinaWebView = binding.divinaWebView - // divinaWebView.listener = this - - publication = intent.getPublication(this) - publicationPath = intent.getStringExtra("publicationPath") ?: throw Exception("publicationPath required") - publicationFileName = intent.getStringExtra("publicationFileName") ?: throw Exception("publicationFileName required") - - publicationIdentifier = publication.metadata.identifier ?: "" - title = publication.metadata.title - - // Set up divinaWebView to enable JavaScript and access to local URLs - divinaWebView.settings.javaScriptEnabled = true - divinaWebView.settings.allowFileAccess = true - divinaWebView.settings.allowFileAccessFromFileURLs = true - divinaWebView.webViewClient = object : WebViewClientCompat() { - - override fun onPageFinished(view: WebView?, url: String?) { - super.onPageFinished(view, url) - // Define the JS toggleMenu function that will call Android's toggleActionBar -// divinaWebView.evaluateJavascript("window.androidObj = function AndroidClass(){};", null) -// divinaWebView.evaluateJavascript("window.androidObj.toggleMenu = function() { Android.toggleMenu() };", null) - - // Now launch the DiViNa player for the folderPath = publicationPath - divinaWebView.evaluateJavascript("if (player) { player.openDiViNaFromPath('$publicationPath'); };", null) - } - } - divinaWebView.loadUrl("file:///android_asset/readium/divina/divinaPlayer.html") - } - - @Suppress("DEPRECATION") - override fun toggleActionBar() { - launch { - if (supportActionBar!!.isShowing) { - divinaWebView.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - or View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar - or View.SYSTEM_UI_FLAG_IMMERSIVE - ) - } else { - divinaWebView.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - ) - } - } - } - - override fun finish() { - setResult(Activity.RESULT_OK, intent) - super.finish() - } - - override fun onDestroy() { - super.onDestroy() - divinaWebView.evaluateJavascript("if (player) { player.destroy(); };", null) - } -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/Deprecated.kt new file mode 100644 index 0000000000..2809060147 --- /dev/null +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/Deprecated.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.navigator.epub + +import org.readium.r2.shared.publication.Locator + +@Deprecated("Use EpubNavigatorFragment in your own activity instead.", level = DeprecationLevel.ERROR) +open class R2EpubActivity + +@Deprecated("Use Decorator API instead.", level = DeprecationLevel.ERROR) +interface IR2Highlightable + +@Deprecated("Use Decorator API instead.", level = DeprecationLevel.ERROR) +data class Highlight( + val id: String +) + +@Deprecated("Use Decorator API instead.", level = DeprecationLevel.ERROR) +enum class Style { + highlight, underline, strikethrough +} + +@Deprecated("Use navigator fragments.", level = DeprecationLevel.ERROR) +interface IR2Selectable { + fun currentSelection(callback: (Locator?) -> Unit) +} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt index e02a03b13c..53b0021676 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt @@ -6,6 +6,8 @@ package org.readium.r2.navigator.epub +import androidx.fragment.app.FragmentFactory +import org.readium.r2.navigator.ExperimentalDecorator import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication @@ -36,16 +38,16 @@ class EpubNavigatorFactory( private val layout: EpubLayout = publication.metadata.presentation.layout ?: EpubLayout.REFLOWABLE + @OptIn(ExperimentalDecorator::class) fun createFragmentFactory( initialLocator: Locator?, initialPreferences: EpubPreferences = EpubPreferences(), listener: EpubNavigatorFragment.Listener? = null, paginationListener: EpubNavigatorFragment.PaginationListener? = null, configuration: EpubNavigatorFragment.Configuration = EpubNavigatorFragment.Configuration(), - ) = org.readium.r2.navigator.util.createFragmentFactory { + ): FragmentFactory = org.readium.r2.navigator.util.createFragmentFactory { EpubNavigatorFragment( publication = publication, - baseUrl = null, initialLocator = initialLocator, initialPreferences = initialPreferences, listener = listener, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt index 26e8b54811..83bd34d315 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt @@ -42,7 +42,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.json.JSONObject import org.readium.r2.navigator.* -import org.readium.r2.navigator.databinding.ActivityR2ViewpagerBinding +import org.readium.r2.navigator.databinding.ReadiumNavigatorViewpagerBinding import org.readium.r2.navigator.epub.EpubNavigatorViewModel.RunScriptCommand import org.readium.r2.navigator.epub.css.FontFamilyDeclaration import org.readium.r2.navigator.epub.css.MutableFontFamilyDeclaration @@ -64,7 +64,6 @@ import org.readium.r2.navigator.pager.R2ViewPager import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.navigator.preferences.FontFamily import org.readium.r2.navigator.preferences.ReadingProgression -import org.readium.r2.navigator.util.createFragmentFactory import org.readium.r2.shared.DelicateReadiumApi import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.extensions.tryOrLog @@ -95,7 +94,6 @@ typealias JavascriptInterfaceFactory = (resource: Link) -> Any? @OptIn(ExperimentalDecorator::class, ExperimentalReadiumApi::class, DelicateReadiumApi::class) class EpubNavigatorFragment internal constructor( override val publication: Publication, - private val baseUrl: String?, private val initialLocator: Locator?, private val initialPreferences: EpubPreferences, internal val listener: Listener?, @@ -271,7 +269,7 @@ class EpubNavigatorFragment internal constructor( private val viewModel: EpubNavigatorViewModel by viewModels { EpubNavigatorViewModel.createFactory( requireActivity().application, publication, - baseUrl = baseUrl, config = this.config, + config = this.config, initialPreferences = initialPreferences, layout = epubLayout, defaults = defaults @@ -285,8 +283,8 @@ class EpubNavigatorFragment internal constructor( private lateinit var resourcesSingle: List private lateinit var resourcesDouble: List - @Deprecated("Migrate to the new Settings API (see migration guide)") - val preferences: SharedPreferences get() = viewModel.preferences + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) + val preferences: SharedPreferences get() = throw NotImplementedError() internal lateinit var publicationIdentifier: String @@ -296,9 +294,7 @@ class EpubNavigatorFragment internal constructor( internal var navigatorDelegate: NavigatorDelegate? = null - private val r2Activity: R2EpubActivity? get() = activity as? R2EpubActivity - - private var _binding: ActivityR2ViewpagerBinding? = null + private var _binding: ReadiumNavigatorViewpagerBinding? = null private val binding get() = _binding!! override fun onCreateView( @@ -307,7 +303,7 @@ class EpubNavigatorFragment internal constructor( savedInstanceState: Bundle? ): View { currentActivity = requireActivity() - _binding = ActivityR2ViewpagerBinding.inflate(inflater, container, false) + _binding = ReadiumNavigatorViewpagerBinding.inflate(inflater, container, false) var view: View = binding.root positionsByReadingOrder = runBlocking { publication.positionsByReadingOrder() } @@ -331,7 +327,7 @@ class EpubNavigatorFragment internal constructor( // TODO needs work, currently showing two resources for fxl, needs to understand which two resources, left & right, or only right etc. var doublePageLeft: Link? = null - var doublePageRight: Link? = null + var doublePageRight: Link? for ((index, link) in publication.readingOrder.withIndex()) { val url = viewModel.urlTo(link) @@ -360,7 +356,12 @@ class EpubNavigatorFragment internal constructor( } // add last page if there is only a left page remaining if (doublePageLeft != null) { - resourcesDouble.add(PageResource.EpubFxl(leftLink = doublePageLeft, leftUrl = viewModel.urlTo(doublePageLeft))) + resourcesDouble.add( + PageResource.EpubFxl( + leftLink = doublePageLeft, + leftUrl = viewModel.urlTo(doublePageLeft) + ) + ) } this.resourcesSingle = resourcesSingle @@ -371,11 +372,6 @@ class EpubNavigatorFragment internal constructor( resourcePager = binding.resourcePager resetResourcePager() - @Suppress("DEPRECATION") - if (viewModel.useLegacySettings && publication.cssStyle == ReadingProgression.RTL.value) { - resourcePager.direction = PublicationReadingProgression.RTL - } - resourcePager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() { override fun onPageSelected(position: Int) { @@ -425,9 +421,9 @@ class EpubNavigatorFragment internal constructor( resourcePager = R2ViewPager(requireContext()) resourcePager.id = R.id.resourcePager - resourcePager.type = when (publication.metadata.presentation.layout) { - EpubLayout.REFLOWABLE, null -> Publication.TYPE.EPUB - EpubLayout.FIXED -> Publication.TYPE.FXL + resourcePager.publicationType = when (publication.metadata.presentation.layout) { + EpubLayout.REFLOWABLE, null -> R2ViewPager.PublicationType.EPUB + EpubLayout.FIXED -> R2ViewPager.PublicationType.FXL } resourcePager.setBackgroundColor(viewModel.settings.value.effectiveBackgroundColor) // Let the page views handle the keyboard events. @@ -457,7 +453,7 @@ class EpubNavigatorFragment internal constructor( } adapter.listener = PagerAdapterListener() resourcePager.adapter = adapter - resourcePager.direction = readingProgression + resourcePager.direction = presentation.value.readingProgression resourcePager.layoutDirection = when (settings.value.readingProgression) { ReadingProgression.RTL -> LayoutDirection.RTL ReadingProgression.LTR -> LayoutDirection.LTR @@ -568,8 +564,10 @@ class EpubNavigatorFragment internal constructor( fun setCurrent(resources: List) { val page = resources.withIndex().firstOrNull { (_, res) -> when (res) { - is PageResource.EpubReflowable -> res.link.href == href - is PageResource.EpubFxl -> res.leftUrl?.endsWith(href) == true || res.rightUrl?.endsWith(href) == true + is PageResource.EpubReflowable -> + res.link.href == href + is PageResource.EpubFxl -> + res.leftUrl?.endsWith(href) == true || res.rightUrl?.endsWith(href) == true else -> false } } ?: return @@ -635,10 +633,16 @@ class EpubNavigatorFragment internal constructor( override val publicationView: View get() = requireView() - override val presentation: StateFlow get() = viewModel.presentation + override val presentation: StateFlow + get() = viewModel.presentation + @Deprecated( + "Use `presentation.value.readingProgression` instead", + replaceWith = ReplaceWith("presentation.value.readingProgression"), + level = DeprecationLevel.ERROR + ) override val readingProgression: PublicationReadingProgression - get() = viewModel.readingProgression + get() = throw NotImplementedError() private val inputListener = CompositeInputListener() @@ -706,10 +710,9 @@ class EpubNavigatorFragment internal constructor( internal val webViewListener: R2BasicWebView.Listener = WebViewListener() - @OptIn(ExperimentalDragGesture::class) private inner class WebViewListener : R2BasicWebView.Listener { - override val readingProgression: PublicationReadingProgression + override val readingProgression: ReadingProgression get() = viewModel.readingProgression override fun onResourceLoaded(link: Link?, webView: R2BasicWebView, url: String?) { @@ -717,37 +720,13 @@ class EpubNavigatorFragment internal constructor( } override fun onPageLoaded() { - r2Activity?.onPageLoaded() paginationListener?.onPageLoaded() notifyCurrentLocation() } - override fun onPageChanged(pageIndex: Int, totalPages: Int, url: String) { - r2Activity?.onPageChanged(pageIndex = pageIndex, totalPages = totalPages, url = url) - } - - override fun onPageEnded(end: Boolean) { - r2Activity?.onPageEnded(end) - } - override fun javascriptInterfacesForResource(link: Link): Map = config.javascriptInterfaces.mapValues { (_, factory) -> factory(link) } - @Suppress("DEPRECATION") - override fun onScroll() { - val activity = r2Activity ?: return - if (activity.supportActionBar?.isShowing == true && activity.allowToggleActionBar) { - resourcePager.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - or View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar - or View.SYSTEM_UI_FLAG_IMMERSIVE - ) - } - } - override fun onTap(point: PointF): Boolean = inputListener.onTap(this@EpubNavigatorFragment, TapEvent(point)) @@ -790,14 +769,6 @@ class EpubNavigatorFragment internal constructor( notifyCurrentLocation() } - override fun onHighlightActivated(id: String) { - r2Activity?.highlightActivated(id) - } - - override fun onHighlightAnnotationMarkActivated(id: String) { - r2Activity?.highlightAnnotationMarkActivated(id) - } - override fun goToPreviousResource(jump: Boolean, animated: Boolean): Boolean { return this@EpubNavigatorFragment.goToPreviousResource(jump = jump, animated = animated) } @@ -1070,6 +1041,7 @@ class EpubNavigatorFragment internal constructor( * @param listener Optional listener to implement to observe events, such as user taps. * @param config Additional configuration. */ + @Deprecated("Use `EpubNavigatorFactory().createFragmentFactory()` instead", level = DeprecationLevel.ERROR) fun createFactory( publication: Publication, baseUrl: String? = null, @@ -1078,16 +1050,7 @@ class EpubNavigatorFragment internal constructor( paginationListener: PaginationListener? = null, config: Configuration = Configuration(), initialPreferences: EpubPreferences = EpubPreferences() - ): FragmentFactory = - createFragmentFactory { - EpubNavigatorFragment( - publication, baseUrl, initialLocator, initialPreferences, - listener, paginationListener, - epubLayout = publication.metadata.presentation.layout ?: EpubLayout.REFLOWABLE, - defaults = EpubDefaults(), - configuration = config, - ) - } + ): FragmentFactory { throw NotImplementedError() } /** * Returns a URL to the application asset at [path], served in the web views. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt index 9ce65e2f86..5e3335797e 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt @@ -9,8 +9,6 @@ package org.readium.r2.navigator.epub import android.app.Application -import android.content.Context -import android.content.SharedPreferences import android.graphics.PointF import android.graphics.RectF import android.net.Uri @@ -29,15 +27,12 @@ import org.readium.r2.navigator.epub.extensions.javascriptForGroup import org.readium.r2.navigator.html.HtmlDecorationTemplates import org.readium.r2.navigator.preferences.* import org.readium.r2.navigator.util.createViewModelFactory -import org.readium.r2.shared.COLUMN_COUNT_REF import org.readium.r2.shared.DelicateReadiumApi import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.SCROLL_REF import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.extensions.mapStateIn import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.ReadingProgression as PublicationReadingProgression import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.util.Href @@ -53,15 +48,9 @@ internal class EpubNavigatorViewModel( initialPreferences: EpubPreferences, val layout: EpubLayout, private val defaults: EpubDefaults, - baseUrl: String?, - private val server: WebViewServer?, + private val server: WebViewServer ) : AndroidViewModel(application) { - val useLegacySettings: Boolean = (server == null) - - val preferences: SharedPreferences = - application.getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) - // Make a copy to prevent new decoration templates from being registered after initializing // the navigator. private val decorationTemplates: HtmlDecorationTemplates = config.decorationTemplates.copy() @@ -104,20 +93,10 @@ internal class EpubNavigatorViewModel( ) } - private val googleFonts: List = - if (useLegacySettings) - listOf( - FontFamily.LITERATA, FontFamily.PT_SERIF, FontFamily.ROBOTO, - FontFamily.SOURCE_SANS_PRO, FontFamily.VOLLKORN - ) - else - emptyList() - private val css = MutableStateFlow( ReadiumCss( rsProperties = config.readiumCssRsProperties, fontFamilyDeclarations = config.fontFamilyDeclarations, - googleFonts = googleFonts, assetsBaseHref = WebViewServer.assetsBaseHref ).update(settings.value, useReadiumCssFontSize = config.useReadiumCssFontSize) ) @@ -178,8 +157,7 @@ internal class EpubNavigatorViewModel( // Serving resources val baseUrl: String = - baseUrl?.let { it.removeSuffix("/") + "/" } - ?: publication.linkWithRel("self")?.href + publication.linkWithRel("self")?.href ?: WebViewServer.publicationBaseHref /** @@ -224,7 +202,7 @@ internal class EpubNavigatorViewModel( } fun shouldInterceptRequest(request: WebResourceRequest): WebResourceResponse? = - server?.shouldInterceptRequest(request, css.value) + server.shouldInterceptRequest(request, css.value) fun submitPreferences(preferences: EpubPreferences) = viewModelScope.launch { val oldSettings = settings.value @@ -252,37 +230,23 @@ internal class EpubNavigatorViewModel( /** * Effective reading progression. */ - val readingProgression: PublicationReadingProgression get() = - if (useLegacySettings) { - publication.metadata.effectiveReadingProgression - } else when (settings.value.readingProgression) { - ReadingProgression.LTR -> PublicationReadingProgression.LTR - ReadingProgression.RTL -> PublicationReadingProgression.RTL - } + val readingProgression: ReadingProgression get() = + settings.value.readingProgression /** * Indicates whether the dual page mode is enabled. */ val dualPageMode: DualPage get() = - if (useLegacySettings) { - @Suppress("DEPRECATION") - when (preferences.getInt(COLUMN_COUNT_REF, 0)) { - 1 -> DualPage.OFF - 2 -> DualPage.ON - else -> DualPage.AUTO + when (layout) { + EpubLayout.FIXED -> when (settings.value.spread) { + Spread.AUTO -> DualPage.AUTO + Spread.ALWAYS -> DualPage.ON + Spread.NEVER -> DualPage.OFF } - } else { - when (layout) { - EpubLayout.FIXED -> when (settings.value.spread) { - Spread.AUTO -> DualPage.AUTO - Spread.ALWAYS -> DualPage.ON - Spread.NEVER -> DualPage.OFF - } - EpubLayout.REFLOWABLE -> when (settings.value.columnCount) { - ColumnCount.ONE -> DualPage.OFF - ColumnCount.TWO -> DualPage.ON - ColumnCount.AUTO -> DualPage.AUTO - } + EpubLayout.REFLOWABLE -> when (settings.value.columnCount) { + ColumnCount.ONE -> DualPage.OFF + ColumnCount.TWO -> DualPage.ON + ColumnCount.AUTO -> DualPage.AUTO } } @@ -290,14 +254,8 @@ internal class EpubNavigatorViewModel( * Indicates whether the navigator is scrollable instead of paginated. */ val isScrollEnabled: StateFlow get() = - if (useLegacySettings) { - @Suppress("DEPRECATION") - val scroll = preferences.getBoolean(SCROLL_REF, false) - MutableStateFlow(scroll) - } else { - settings.mapStateIn(viewModelScope) { - if (layout == EpubLayout.REFLOWABLE) it.scroll else false - } + settings.mapStateIn(viewModelScope) { + if (layout == EpubLayout.REFLOWABLE) it.scroll else false } // Selection @@ -382,7 +340,6 @@ internal class EpubNavigatorViewModel( fun createFactory( application: Application, publication: Publication, - baseUrl: String?, layout: EpubLayout, defaults: EpubDefaults, config: EpubNavigatorFragment.Configuration, @@ -391,9 +348,7 @@ internal class EpubNavigatorViewModel( EpubNavigatorViewModel( application, publication, config, initialPreferences, layout, defaults = defaults, - baseUrl = baseUrl, - server = if (baseUrl != null) null - else WebViewServer( + server = WebViewServer( application, publication, servedAssets = config.servedAssets, disableSelectionWhenProtected = config.disableSelectionWhenProtected @@ -402,9 +357,3 @@ internal class EpubNavigatorViewModel( } } } - -private val FontFamily.Companion.LITERATA: FontFamily get() = FontFamily("Literata") -private val FontFamily.Companion.PT_SERIF: FontFamily get() = FontFamily("PT Serif") -private val FontFamily.Companion.ROBOTO: FontFamily get() = FontFamily("Roboto") -private val FontFamily.Companion.SOURCE_SANS_PRO: FontFamily get() = FontFamily("Source Sans Pro") -private val FontFamily.Companion.VOLLKORN: FontFamily get() = FontFamily("Vollkorn") diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt index dd18f81ca4..9d764431ac 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt @@ -64,6 +64,7 @@ internal class EpubSettingsResolver( val rpPref = preferences.readingProgression val langPref = preferences.language val metadataLanguage = metadata.language + val metadataReadingProgression = metadata.readingProgression // Compute language according to the following rule: // preference value > metadata value > default value > null @@ -80,10 +81,10 @@ internal class EpubSettingsResolver( rpPref langPref != null -> if (langPref.isRtl) ReadingProgression.RTL else ReadingProgression.LTR - metadata.readingProgression.isHorizontal == true -> - when (metadata.readingProgression) { + metadataReadingProgression != null -> + when (metadataReadingProgression) { PublicationReadingProgression.RTL -> ReadingProgression.RTL - else -> ReadingProgression.LTR + PublicationReadingProgression.LTR -> ReadingProgression.LTR } metadataLanguage != null -> if (metadataLanguage.isRtl) ReadingProgression.RTL else ReadingProgression.LTR diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/IR2Highlightable.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/IR2Highlightable.kt deleted file mode 100644 index 09f1c3ed42..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/IR2Highlightable.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.navigator.epub - -import android.graphics.Rect -import org.readium.r2.shared.publication.Locator - -interface IR2Highlightable { - fun showHighlight(highlight: Highlight) - - fun showHighlights(highlights: Array) - - fun hideHighlightWithID(id: String) - - fun hideAllHighlights() - - fun rectangleForHighlightWithID(id: String, callback: (Rect?) -> Unit) - - fun rectangleForHighlightAnnotationMarkWithID(id: String): Rect? - - fun registerHighlightAnnotationMarkStyle(name: String, css: String) - - fun highlightActivated(id: String) - - fun highlightAnnotationMarkActivated(id: String) -} - -data class Highlight( - val id: String, - val locator: Locator, - val color: Int, - val style: Style, - val annotationMarkStyle: String? = null -) - -enum class Style { - highlight, underline, strikethrough -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/IR2Selectable.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/IR2Selectable.kt deleted file mode 100644 index b91ee3454c..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/IR2Selectable.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.navigator.epub - -import org.readium.r2.shared.publication.Locator - -interface IR2Selectable { - fun currentSelection(callback: (Locator?) -> Unit) -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/R2EpubActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/R2EpubActivity.kt deleted file mode 100644 index 0805aa64c6..0000000000 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/R2EpubActivity.kt +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.navigator.epub - -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.content.SharedPreferences -import android.graphics.Color -import android.graphics.Rect -import android.os.Bundle -import android.util.DisplayMetrics -import android.view.ActionMode -import android.view.View -import android.view.WindowManager -import androidx.appcompat.app.AppCompatActivity -import kotlin.coroutines.CoroutineContext -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.StateFlow -import org.json.JSONException -import org.json.JSONObject -import org.readium.r2.navigator.* -import org.readium.r2.navigator.input.InputListener -import org.readium.r2.navigator.pager.R2EpubPageFragment -import org.readium.r2.navigator.pager.R2PagerAdapter -import org.readium.r2.navigator.pager.R2ViewPager -import org.readium.r2.navigator.util.CompositeFragmentFactory -import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.extensions.getPublication -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.ReadingProgression - -open class R2EpubActivity : AppCompatActivity(), IR2Activity, IR2Selectable, IR2Highlightable, IR2TTS, CoroutineScope, VisualNavigator, EpubNavigatorFragment.Listener { - - /** - * Context of this scope. - */ - override val coroutineContext: CoroutineContext - get() = Dispatchers.Main - - override lateinit var preferences: SharedPreferences - override lateinit var publicationPath: String - override lateinit var publicationFileName: String - override lateinit var publication: Publication - override lateinit var publicationIdentifier: String - override var bookId: Long = -1 - protected lateinit var baseUrl: String - - override var allowToggleActionBar = true - - protected var navigatorDelegate: NavigatorDelegate? = null - - val adapter: R2PagerAdapter get() = - resourcePager.adapter as R2PagerAdapter - - override val resourcePager: R2ViewPager get() = - navigatorFragment().resourcePager - - private val currentFragment: R2EpubPageFragment? get() = - adapter.mFragments.get(adapter.getItemId(resourcePager.currentItem)) as? R2EpubPageFragment - - // For backward compatibility, we expose these properties only through the `R2EpubActivity`. - val positions: List get() = navigatorFragment().positions - val currentPagerPosition: Int get() = navigatorFragment().currentPagerPosition - - override val currentLocator: StateFlow - get() = navigatorFragment().currentLocator - - /** - * Locates the [EpubNavigatorFragment] instance. - * - * Reading apps may override this method to provide their own path to the navigator fragment. - */ - open fun navigatorFragment(): EpubNavigatorFragment = - supportFragmentManager.findFragmentByTag(getString(R.string.epub_navigator_tag)) as EpubNavigatorFragment - - override fun onCreate(savedInstanceState: Bundle?) { - preferences = getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) - - publication = intent.getPublication(this) - publicationPath = intent.getStringExtra("publicationPath") ?: throw Exception("publicationPath required") - publicationFileName = intent.getStringExtra("publicationFileName") ?: throw Exception("publicationFileName required") - publicationIdentifier = publication.metadata.identifier ?: publication.metadata.title - baseUrl = intent.getStringExtra("baseUrl") ?: throw Exception("Intent extra `baseUrl` is required. Provide the URL returned by Server.addPublication()") - - val initialLocator = intent.getParcelableExtra("locator") as? Locator - - // This must be done before the call to super.onCreate, including by reading apps. - // Because they may want to set their own factories, let's use a CompositeFragmentFactory that retains - // previously set factories. - supportFragmentManager.fragmentFactory = CompositeFragmentFactory( - supportFragmentManager.fragmentFactory, - EpubNavigatorFragment.createFactory(publication, baseUrl = baseUrl, initialLocator = initialLocator, listener = this) - ) - - super.onCreate(savedInstanceState) - - setContentView(R.layout.activity_r2_epub) - - title = null - - // Add support for display cutout. - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) { - window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES - } - } - - override fun finish() { - setResult(Activity.RESULT_OK, intent) - super.finish() - } - - override fun onActionModeStarted(mode: ActionMode?) { - mode?.menu?.clear() - super.onActionModeStarted(mode) - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == 2 && resultCode == Activity.RESULT_OK) { - val locator = data?.getParcelableExtra("locator") as? Locator - if (locator != null) { - go(locator) - } - } - super.onActivityResult(requestCode, resultCode, data) - } - - @Suppress("DEPRECATION") - override fun toggleActionBar() { - if (allowToggleActionBar) { - if (supportActionBar!!.isShowing) { - resourcePager.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - or View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar - or View.SYSTEM_UI_FLAG_IMMERSIVE - ) - } else { - resourcePager.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - ) - } - } - } - - override val publicationView: View - get() = navigatorFragment().publicationView - - @Deprecated("Use `presentation.value.readingProgression` instead", replaceWith = ReplaceWith("presentation.value.readingProgression")) - override val readingProgression: ReadingProgression - get() = navigatorFragment().readingProgression - - @ExperimentalReadiumApi - override val presentation: StateFlow - get() = navigatorFragment().presentation - - @ExperimentalReadiumApi - override fun addInputListener(listener: InputListener) { - navigatorFragment().addInputListener(listener) - } - - @ExperimentalReadiumApi - override fun removeInputListener(listener: InputListener) { - navigatorFragment().removeInputListener(listener) - } - - @Suppress("DEPRECATION") - override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean { - navigatorFragment().go(locator, animated, completion) - - if (allowToggleActionBar && supportActionBar!!.isShowing) { - resourcePager.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - or View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar - or View.SYSTEM_UI_FLAG_IMMERSIVE - ) - } - - return true - } - - override fun go(link: Link, animated: Boolean, completion: () -> Unit): Boolean { - return navigatorFragment().go(link, animated, completion) - } - - override fun goForward(animated: Boolean, completion: () -> Unit): Boolean { - return navigatorFragment().goForward(animated, completion) - } - - override fun goBackward(animated: Boolean, completion: () -> Unit): Boolean { - return navigatorFragment().goBackward(animated, completion) - } - - override fun currentSelection(callback: (Locator?) -> Unit) { - currentFragment?.webView?.getCurrentSelectionInfo { - val selection = JSONObject(it) - val resource = publication.readingOrder[resourcePager.currentItem] - val resourceHref = resource.href - val resourceType = resource.type ?: "" - val locations = Locator.Locations.fromJSON(selection.getJSONObject("locations")) - val text = Locator.Text.fromJSON(selection.getJSONObject("text")) - - val locator = Locator( - href = resourceHref, - type = resourceType, - locations = locations, - text = text - ) - callback(locator) - } - } - - override fun showHighlight(highlight: Highlight) { - currentFragment?.webView?.run { - val colorJson = JSONObject().apply { - put("red", Color.red(highlight.color)) - put("green", Color.green(highlight.color)) - put("blue", Color.blue(highlight.color)) - } - createHighlight(highlight.locator.toJSON().toString(), colorJson.toString()) { - if (highlight.annotationMarkStyle.isNullOrEmpty().not()) - createAnnotation(highlight.id) - } - } - } - - override fun showHighlights(highlights: Array) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun hideHighlightWithID(id: String) { - currentFragment?.webView?.destroyHighlight(id) - currentFragment?.webView?.destroyHighlight(id.replace("HIGHLIGHT", "ANNOTATION")) - } - - override fun hideAllHighlights() { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun rectangleForHighlightWithID(id: String, callback: (Rect?) -> Unit) { - currentFragment?.webView?.rectangleForHighlightWithID(id) { - val rect = - try { - with(JSONObject(it)) { - val display = windowManager.defaultDisplay - val metrics = DisplayMetrics() - display.getMetrics(metrics) - val left = getDouble("left") - val width = getDouble("width") - val top = getDouble("top") * metrics.density - val height = getDouble("height") * metrics.density - Rect(left.toInt(), top.toInt(), width.toInt() + left.toInt(), top.toInt() + height.toInt()) - } - } catch (e: JSONException) { - null - } - callback(rect) - } - } - - override fun rectangleForHighlightAnnotationMarkWithID(id: String): Rect? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun registerHighlightAnnotationMarkStyle(name: String, css: String) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun highlightActivated(id: String) { - } - - override fun highlightAnnotationMarkActivated(id: String) { - } - - fun createHighlight(color: Int, callback: (Highlight) -> Unit) { - currentSelection { locator -> - val colorJson = JSONObject().apply { - put("red", Color.red(color)) - put("green", Color.green(color)) - put("blue", Color.blue(color)) - } - - currentFragment?.webView?.createHighlight(locator?.toJSON().toString(), colorJson.toString()) { - val json = JSONObject(it) - val id = json.getString("id") - callback( - Highlight( - id, - locator!!, - color, - Style.highlight - ) - ) - } - } - } - - fun createAnnotation(highlight: Highlight?, callback: (Highlight) -> Unit) { - if (highlight != null) { - currentFragment?.webView?.createAnnotation(highlight.id) - callback(highlight) - } else { - createHighlight(Color.rgb(150, 150, 150)) { - createAnnotation(it) { highlight -> - callback(highlight) - } - } - } - } -} diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt index 4ca319438e..194c2fc562 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt @@ -9,24 +9,11 @@ package org.readium.r2.navigator.extensions -import java.net.URL import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.positions -/** Computes an absolute URL to the given HREF. */ -internal fun Publication.urlToHref(href: String): URL? { - val baseUrl = this.baseUrl?.toString()?.removeSuffix("/") - val urlString = if (baseUrl != null && href.startsWith("/")) { - "$baseUrl$href" - } else { - href - } - return tryOrNull { URL(urlString) } -} - // These extensions will be removed in the next release, with `PositionsService`. internal val Publication.positionsSync: List diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt index 0eb3d48fd8..16a2470287 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt @@ -25,7 +25,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.runBlocking import org.readium.r2.navigator.SimplePresentation import org.readium.r2.navigator.VisualNavigator -import org.readium.r2.navigator.databinding.ActivityR2ViewpagerBinding +import org.readium.r2.navigator.databinding.ReadiumNavigatorViewpagerBinding import org.readium.r2.navigator.extensions.layoutDirectionIsRTL import org.readium.r2.navigator.input.CompositeInputListener import org.readium.r2.navigator.input.InputListener @@ -79,7 +79,7 @@ class ImageNavigatorFragment private constructor( internal var currentPagerPosition: Int = 0 internal var resources: List = emptyList() - private var _binding: ActivityR2ViewpagerBinding? = null + private var _binding: ReadiumNavigatorViewpagerBinding? = null private val binding get() = _binding!! override fun onCreate(savedInstanceState: Bundle?) { @@ -95,12 +95,12 @@ class ImageNavigatorFragment private constructor( savedInstanceState: Bundle? ): View { currentActivity = requireActivity() - _binding = ActivityR2ViewpagerBinding.inflate(inflater, container, false) + _binding = ReadiumNavigatorViewpagerBinding.inflate(inflater, container, false) val view = binding.root preferences = requireContext().getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) resourcePager = binding.resourcePager - resourcePager.type = Publication.TYPE.CBZ + resourcePager.publicationType = R2ViewPager.PublicationType.CBZ positions = runBlocking { publication.positions() } @@ -217,6 +217,11 @@ class ImageNavigatorFragment private constructor( override val publicationView: View get() = requireView() + @Deprecated( + "Use `presentation.value.readingProgression` instead", + replaceWith = ReplaceWith("presentation.value.readingProgression"), + level = DeprecationLevel.ERROR + ) override val readingProgression: PublicationReadingProgression = publication.metadata.effectiveReadingProgression @@ -224,7 +229,7 @@ class ImageNavigatorFragment private constructor( override val presentation: StateFlow = MutableStateFlow( SimplePresentation( - readingProgression = when (readingProgression) { + readingProgression = when (publication.metadata.effectiveReadingProgression) { PublicationReadingProgression.RTL -> ReadingProgression.RTL else -> ReadingProgression.LTR }, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt index b117efd2cf..223ecc2486 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt @@ -119,12 +119,12 @@ class ExoMediaPlayer( MEDIA_NOTIFICATION_ID, MEDIA_CHANNEL_ID ) - .setChannelNameResourceId(R.string.r2_media_notification_channel_name) - .setChannelDescriptionResourceId(R.string.r2_media_notification_channel_description) + .setChannelNameResourceId(R.string.readium_media_notification_channel_name) + .setChannelDescriptionResourceId(R.string.readium_media_notification_channel_description) .setMediaDescriptionAdapter(DescriptionAdapter(mediaSession.controller, media)) .setNotificationListener(NotificationListener()) - .setRewindActionIconResourceId(R.drawable.r2_media_notification_rewind) - .setFastForwardActionIconResourceId(R.drawable.r2_media_notification_fastforward) + .setRewindActionIconResourceId(R.drawable.readium_media_notification_rewind) + .setFastForwardActionIconResourceId(R.drawable.readium_media_notification_fastforward) .build() .apply { setMediaSessionToken(mediaSession.sessionToken) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt index fbf95e41a7..c2ab1c5459 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt @@ -46,8 +46,8 @@ class AudioNavigator> publication: Publication, audioEngineProvider: AudioEngineProvider, readingOrder: List = publication.readingOrder, - initialPreferences: P? = null, initialLocator: Locator? = null, + initialPreferences: P? = null, ): AudioNavigator? { if (readingOrder.isEmpty()) { return null diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt index 0774d7956f..a4b21cfb89 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigatorFactory.kt @@ -42,14 +42,14 @@ class AudioNavigatorFactory? { return AudioNavigator( publication = publication, audioEngineProvider = audioEngineProvider, + initialLocator = initialLocator, initialPreferences = initialPreferences, - initialLocator = initialLocator ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt index a0b9953998..0c0dc5264d 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt @@ -56,8 +56,8 @@ class TtsNavigator, tokenizerFactory: (language: Language?) -> TextTokenizer, metadataProvider: MediaMetadataProvider, listener: Listener, - initialPreferences: P? = null, initialLocator: Locator? = null, + initialPreferences: P? = null, ): TtsNavigator? { if (publication.findService(ContentService::class) == null) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt index 8cc477d0b8..7005a748fe 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt @@ -115,8 +115,8 @@ class TtsNavigatorFactory, suspend fun createNavigator( listener: TtsNavigator.Listener, + initialLocator: Locator? = null, initialPreferences: P? = null, - initialLocator: Locator? = null ): TtsNavigator? { return TtsNavigator( application, @@ -125,8 +125,8 @@ class TtsNavigatorFactory, tokenizerFactory, metadataProvider, listener, + initialLocator, initialPreferences, - initialLocator ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt index 631dab30ce..e1528268f8 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt @@ -22,7 +22,7 @@ import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.readium.r2.navigator.databinding.ViewpagerFragmentCbzBinding +import org.readium.r2.navigator.databinding.ReadiumNavigatorViewpagerFragmentCbzBinding import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication @@ -41,7 +41,7 @@ class R2CbzPageFragment( private lateinit var containerView: View private lateinit var photoView: PhotoView - private var _binding: ViewpagerFragmentCbzBinding? = null + private var _binding: ReadiumNavigatorViewpagerFragmentCbzBinding? = null private val binding get() = _binding!! override fun onCreateView( @@ -50,7 +50,7 @@ class R2CbzPageFragment( savedInstanceState: Bundle? ): View? { - _binding = ViewpagerFragmentCbzBinding.inflate(inflater, container, false) + _binding = ReadiumNavigatorViewpagerFragmentCbzBinding.inflate(inflater, container, false) containerView = binding.root photoView = binding.imageView photoView.setOnViewTapListener { _, x, y -> onTapListener(x, y) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt index ab9166b00a..f348581219 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt @@ -7,8 +7,6 @@ * LICENSE file present in the project repository where this source code is maintained. */ -@file:OptIn(ExperimentalReadiumApi::class) - package org.readium.r2.navigator.pager import android.annotation.SuppressLint @@ -33,17 +31,17 @@ import kotlinx.coroutines.launch import org.readium.r2.navigator.R import org.readium.r2.navigator.R2BasicWebView import org.readium.r2.navigator.R2WebView -import org.readium.r2.navigator.databinding.ViewpagerFragmentEpubBinding +import org.readium.r2.navigator.databinding.ReadiumNavigatorViewpagerFragmentEpubBinding import org.readium.r2.navigator.epub.EpubNavigatorFragment import org.readium.r2.navigator.epub.EpubNavigatorViewModel import org.readium.r2.navigator.extensions.htmlId +import org.readium.r2.navigator.preferences.ReadingProgression import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.InternalReadiumApi -import org.readium.r2.shared.SCROLL_REF import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.ReadingProgression +@OptIn(ExperimentalReadiumApi::class) class R2EpubPageFragment : Fragment() { private val resourceUrl: String? @@ -64,7 +62,7 @@ class R2EpubPageFragment : Fragment() { private lateinit var preferences: SharedPreferences private val viewModel: EpubNavigatorViewModel by viewModels(ownerProducer = { requireParentFragment() }) - private var _binding: ViewpagerFragmentEpubBinding? = null + private var _binding: ReadiumNavigatorViewpagerFragmentEpubBinding? = null private val binding get() = _binding!! private var isLoading: Boolean = false @@ -127,7 +125,7 @@ class R2EpubPageFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = ViewpagerFragmentEpubBinding.inflate(inflater, container, false) + _binding = ReadiumNavigatorViewpagerFragmentEpubBinding.inflate(inflater, container, false) containerView = binding.root preferences = activity?.getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE)!! @@ -149,11 +147,6 @@ class R2EpubPageFragment : Fragment() { } webView.preferences = preferences - if (viewModel.useLegacySettings) { - @Suppress("DEPRECATION") - webView.setScrollMode(preferences.getBoolean(SCROLL_REF, false)) - } - webView.useLegacySettings = viewModel.useLegacySettings webView.settings.javaScriptEnabled = true webView.isVerticalScrollBarEnabled = false webView.isHorizontalScrollBarEnabled = false @@ -251,13 +244,11 @@ class R2EpubPageFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - if (!viewModel.useLegacySettings) { - val lifecycleOwner = viewLifecycleOwner - lifecycleOwner.lifecycleScope.launch { - viewModel.isScrollEnabled - .flowWithLifecycle(lifecycleOwner.lifecycle) - .collectLatest { webView?.scrollModeFlow?.value = it } - } + val lifecycleOwner = viewLifecycleOwner + lifecycleOwner.lifecycleScope.launch { + viewModel.isScrollEnabled + .flowWithLifecycle(lifecycleOwner.lifecycle) + .collectLatest { webView?.scrollModeFlow?.value = it } } } @@ -323,7 +314,7 @@ class R2EpubPageFragment : Fragment() { } if (!viewModel.isScrollEnabled.value) { - val margin = resources.getDimension(R.dimen.r2_navigator_epub_vertical_padding).toInt() + val margin = resources.getDimension(R.dimen.readium_navigator_epub_vertical_padding).toInt() top += margin bottom += margin } @@ -354,7 +345,7 @@ class R2EpubPageFragment : Fragment() { pendingLocator ?.let { locator -> - loadLocator(webView, requireNotNull(navigator).readingProgression, locator) + loadLocator(webView, requireNotNull(navigator).presentation.value.readingProgression, locator) } .also { pendingLocator = null } @@ -371,7 +362,7 @@ class R2EpubPageFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launchWhenCreated { val webView = requireNotNull(webView) val epubNavigator = requireNotNull(navigator) - loadLocator(webView, epubNavigator.readingProgression, locator) + loadLocator(webView, epubNavigator.presentation.value.readingProgression, locator) webView.listener?.onProgressionChanged() } } @@ -440,7 +431,7 @@ class R2EpubPageFragment : Fragment() { private fun View.setOnClickListenerWithPoint(action: (View, PointF) -> Unit) { var point = PointF() - setOnTouchListener { v, event -> + setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { point = PointF(event.x, event.y) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt index 8bd6da3d12..48843a275d 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt @@ -22,8 +22,8 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.webkit.WebViewClientCompat import org.readium.r2.navigator.R2BasicWebView -import org.readium.r2.navigator.databinding.FragmentFxllayoutDoubleBinding -import org.readium.r2.navigator.databinding.FragmentFxllayoutSingleBinding +import org.readium.r2.navigator.databinding.ReadiumNavigatorFragmentFxllayoutDoubleBinding +import org.readium.r2.navigator.databinding.ReadiumNavigatorFragmentFxllayoutSingleBinding import org.readium.r2.navigator.epub.EpubNavigatorFragment import org.readium.r2.navigator.epub.EpubNavigatorViewModel import org.readium.r2.navigator.epub.fxl.R2FXLLayout @@ -39,10 +39,10 @@ class R2FXLPageFragment : Fragment() { private var webViews = mutableListOf() - private var _doubleBinding: FragmentFxllayoutDoubleBinding? = null + private var _doubleBinding: ReadiumNavigatorFragmentFxllayoutDoubleBinding? = null private val doubleBinding get() = _doubleBinding!! - private var _singleBinding: FragmentFxllayoutSingleBinding? = null + private var _singleBinding: ReadiumNavigatorFragmentFxllayoutSingleBinding? = null private val singleBinding get() = _singleBinding!! private val navigator: EpubNavigatorFragment? @@ -55,10 +55,10 @@ class R2FXLPageFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { secondResourceUrl?.let { - _doubleBinding = FragmentFxllayoutDoubleBinding.inflate(inflater, container, false) + _doubleBinding = ReadiumNavigatorFragmentFxllayoutDoubleBinding.inflate(inflater, container, false) val view: View = doubleBinding.root view.setPadding(0, 0, 0, 0) @@ -80,7 +80,7 @@ class R2FXLPageFragment : Fragment() { return view } ?: run { - _singleBinding = FragmentFxllayoutSingleBinding.inflate(inflater, container, false) + _singleBinding = ReadiumNavigatorFragmentFxllayoutSingleBinding.inflate(inflater, container, false) val view: View = singleBinding.root view.setPadding(0, 0, 0, 0) @@ -131,7 +131,6 @@ class R2FXLPageFragment : Fragment() { webView.listener = it.webViewListener } - webView.useLegacySettings = viewModel.useLegacySettings webView.settings.javaScriptEnabled = true webView.isVerticalScrollBarEnabled = false webView.isHorizontalScrollBarEnabled = false diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2RTLViewPager.java b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2RTLViewPager.java index 77deed1d49..cb0f7a91db 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2RTLViewPager.java +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2RTLViewPager.java @@ -30,11 +30,12 @@ import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; -import org.readium.r2.shared.publication.ReadingProgression; +import org.readium.r2.navigator.preferences.ReadingProgression; +import org.readium.r2.shared.ExperimentalReadiumApi; import java.util.HashMap; -/** + /** * RtlViewPager is an API-compatible implementation of ViewPager which * orders paged views according to the layout direction of the view. In left to right mode, the * first view is at the left side of the carousel, and in right to left mode it is at the right @@ -44,6 +45,7 @@ * OnPageChangeListeners so that clients can be agnostic to layout direction and * modifications are kept internal to RtlViewPager. */ +@ExperimentalReadiumApi public class R2RTLViewPager extends ViewPager { public ReadingProgression direction = ReadingProgression.LTR; private int mLayoutDirection = ViewCompat.LAYOUT_DIRECTION_LTR; diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2ViewPager.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2ViewPager.kt index 17ab0f6079..d380f20550 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2ViewPager.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2ViewPager.kt @@ -18,6 +18,13 @@ import timber.log.Timber class R2ViewPager : R2RTLViewPager { + internal enum class PublicationType { + EPUB, CBZ, FXL, WEBPUB, AUDIO, DiViNa + } + + internal lateinit var publicationType: PublicationType + + @Deprecated(message = "You shouldn't be using these internals.", level = DeprecationLevel.ERROR) lateinit var type: Publication.TYPE constructor(context: Context) : super(context) @@ -29,7 +36,7 @@ class R2ViewPager : R2RTLViewPager { override fun onTouchEvent(ev: MotionEvent): Boolean { if (DEBUG) Timber.d("ev.action ${ev.action}") - if (type == Publication.TYPE.EPUB) { + if (publicationType == PublicationType.EPUB) { when (ev.action and MotionEvent.ACTION_MASK) { MotionEvent.ACTION_DOWN -> { // prevent swipe from view pager directly @@ -51,7 +58,7 @@ class R2ViewPager : R2RTLViewPager { } override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { - if (type == Publication.TYPE.EPUB) { + if (publicationType == PublicationType.EPUB) { when (ev.action and MotionEvent.ACTION_MASK) { MotionEvent.ACTION_DOWN -> { // prevent swipe from view pager directly diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/R2PdfActivity.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/Deprecated.kt similarity index 91% rename from readium/navigator/src/main/java/org/readium/r2/navigator/pdf/R2PdfActivity.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/pdf/Deprecated.kt index c7ad30d3a4..f54bf22927 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/R2PdfActivity.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/Deprecated.kt @@ -13,3 +13,6 @@ import androidx.appcompat.app.AppCompatActivity @Deprecated("Use `PdfNavigatorFragment` in your own activity instead", level = DeprecationLevel.ERROR) abstract class R2PdfActivity : AppCompatActivity() + +// This is for lint to pass. +private val fake = null diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt index ac1a4e3144..f9ed8f1ac9 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt @@ -260,6 +260,11 @@ class PdfNavigatorFragment PublicationReadingProgression.LTR diff --git a/readium/navigator/src/main/res/drawable/baseline_forward_10_white_24.png b/readium/navigator/src/main/res/drawable/readium_baseline_forward_10_white_24.png similarity index 100% rename from readium/navigator/src/main/res/drawable/baseline_forward_10_white_24.png rename to readium/navigator/src/main/res/drawable/readium_baseline_forward_10_white_24.png diff --git a/readium/navigator/src/main/res/drawable/baseline_replay_10_white_24.png b/readium/navigator/src/main/res/drawable/readium_baseline_replay_10_white_24.png similarity index 100% rename from readium/navigator/src/main/res/drawable/baseline_replay_10_white_24.png rename to readium/navigator/src/main/res/drawable/readium_baseline_replay_10_white_24.png diff --git a/readium/navigator/src/main/res/drawable/ic_pause_white_24dp.png b/readium/navigator/src/main/res/drawable/readium_ic_pause_white_24dp.png similarity index 100% rename from readium/navigator/src/main/res/drawable/ic_pause_white_24dp.png rename to readium/navigator/src/main/res/drawable/readium_ic_pause_white_24dp.png diff --git a/readium/navigator/src/main/res/drawable/ic_play_arrow_white_24dp.png b/readium/navigator/src/main/res/drawable/readium_ic_play_arrow_white_24dp.png similarity index 100% rename from readium/navigator/src/main/res/drawable/ic_play_arrow_white_24dp.png rename to readium/navigator/src/main/res/drawable/readium_ic_play_arrow_white_24dp.png diff --git a/readium/navigator/src/main/res/drawable/ic_skip_next_white_24dp.png b/readium/navigator/src/main/res/drawable/readium_ic_skip_next_white_24dp.png similarity index 100% rename from readium/navigator/src/main/res/drawable/ic_skip_next_white_24dp.png rename to readium/navigator/src/main/res/drawable/readium_ic_skip_next_white_24dp.png diff --git a/readium/navigator/src/main/res/drawable/ic_skip_previous_white_24dp.png b/readium/navigator/src/main/res/drawable/readium_ic_skip_previous_white_24dp.png similarity index 100% rename from readium/navigator/src/main/res/drawable/ic_skip_previous_white_24dp.png rename to readium/navigator/src/main/res/drawable/readium_ic_skip_previous_white_24dp.png diff --git a/readium/navigator/src/main/res/drawable/r2_media_notification_fastforward.xml b/readium/navigator/src/main/res/drawable/readium_media_notification_fastforward.xml similarity index 100% rename from readium/navigator/src/main/res/drawable/r2_media_notification_fastforward.xml rename to readium/navigator/src/main/res/drawable/readium_media_notification_fastforward.xml diff --git a/readium/navigator/src/main/res/drawable/r2_media_notification_rewind.xml b/readium/navigator/src/main/res/drawable/readium_media_notification_rewind.xml similarity index 100% rename from readium/navigator/src/main/res/drawable/r2_media_notification_rewind.xml rename to readium/navigator/src/main/res/drawable/readium_media_notification_rewind.xml diff --git a/readium/navigator/src/main/res/layout/activity_r2_audiobook.xml b/readium/navigator/src/main/res/layout/activity_r2_audiobook.xml deleted file mode 100644 index 78aef62609..0000000000 --- a/readium/navigator/src/main/res/layout/activity_r2_audiobook.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/readium/navigator/src/main/res/layout/activity_r2_divina.xml b/readium/navigator/src/main/res/layout/activity_r2_divina.xml deleted file mode 100644 index b4c2533157..0000000000 --- a/readium/navigator/src/main/res/layout/activity_r2_divina.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - diff --git a/readium/navigator/src/main/res/layout/activity_r2_epub.xml b/readium/navigator/src/main/res/layout/activity_r2_epub.xml deleted file mode 100644 index dbb9666632..0000000000 --- a/readium/navigator/src/main/res/layout/activity_r2_epub.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/readium/navigator/src/main/res/layout/activity_r2_image.xml b/readium/navigator/src/main/res/layout/activity_r2_image.xml deleted file mode 100644 index dd2fd71bee..0000000000 --- a/readium/navigator/src/main/res/layout/activity_r2_image.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/readium/navigator/src/main/res/layout/item_spinner_font.xml b/readium/navigator/src/main/res/layout/item_spinner_font.xml deleted file mode 100644 index 33ab3f29ae..0000000000 --- a/readium/navigator/src/main/res/layout/item_spinner_font.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - \ No newline at end of file diff --git a/readium/navigator/src/main/res/layout/fragment_fxllayout_double.xml b/readium/navigator/src/main/res/layout/readium_navigator_fragment_fxllayout_double.xml similarity index 84% rename from readium/navigator/src/main/res/layout/fragment_fxllayout_double.xml rename to readium/navigator/src/main/res/layout/readium_navigator_fragment_fxllayout_double.xml index d063422717..88209a3e56 100644 --- a/readium/navigator/src/main/res/layout/fragment_fxllayout_double.xml +++ b/readium/navigator/src/main/res/layout/readium_navigator_fragment_fxllayout_double.xml @@ -1,11 +1,9 @@ - + + + + + + + \ No newline at end of file diff --git a/readium/navigator/src/main/res/layout/popup_footnote.xml b/readium/navigator/src/main/res/layout/readium_navigator_popup_footnote.xml similarity index 100% rename from readium/navigator/src/main/res/layout/popup_footnote.xml rename to readium/navigator/src/main/res/layout/readium_navigator_popup_footnote.xml diff --git a/readium/navigator/src/main/res/layout/activity_r2_viewpager.xml b/readium/navigator/src/main/res/layout/readium_navigator_viewpager.xml similarity index 69% rename from readium/navigator/src/main/res/layout/activity_r2_viewpager.xml rename to readium/navigator/src/main/res/layout/readium_navigator_viewpager.xml index 056126cda9..b038e98b22 100644 --- a/readium/navigator/src/main/res/layout/activity_r2_viewpager.xml +++ b/readium/navigator/src/main/res/layout/readium_navigator_viewpager.xml @@ -1,12 +1,9 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - 20dp + 20dp \ No newline at end of file diff --git a/readium/navigator/src/main/res/values/colors.xml b/readium/navigator/src/main/res/values/colors.xml index 7e1964e6bb..1067c7ebf4 100644 --- a/readium/navigator/src/main/res/values/colors.xml +++ b/readium/navigator/src/main/res/values/colors.xml @@ -1,21 +1,18 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - #1f21b5 - #17188c - #eceaeb - #17188c + #1f21b5 + #17188c + #eceaeb + #17188c - @color/colorPrimaryDark - @color/colorAccent + @color/readium_colorPrimaryDark + @color/readium_colorAccent diff --git a/readium/navigator/src/main/res/values/dimens.xml b/readium/navigator/src/main/res/values/dimens.xml index 05b9b31048..00fcb80b64 100644 --- a/readium/navigator/src/main/res/values/dimens.xml +++ b/readium/navigator/src/main/res/values/dimens.xml @@ -1,4 +1,4 @@ - 40dp + 40dp \ No newline at end of file diff --git a/readium/navigator/src/main/res/values/strings.xml b/readium/navigator/src/main/res/values/strings.xml index 7c349f7021..f41448b3c8 100644 --- a/readium/navigator/src/main/res/values/strings.xml +++ b/readium/navigator/src/main/res/values/strings.xml @@ -1,20 +1,12 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - end of chapter - ~ ~ ~ - 00:00 - epub_navigator - image_navigator - Audiobook - Audiobook currently being played + Audiobook + Audiobook currently being played diff --git a/readium/navigator/src/main/res/values/styles.xml b/readium/navigator/src/main/res/values/styles.xml deleted file mode 100644 index 987aabf2d7..0000000000 --- a/readium/navigator/src/main/res/values/styles.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt index 580eb69ae6..1ef19eb77c 100644 --- a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt +++ b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt @@ -29,7 +29,7 @@ class EpubSettingsResolverTest { private fun resolveLayout( languages: List = emptyList(), - readingProgression: PublicationReadingProgression = PublicationReadingProgression.AUTO, + readingProgression: PublicationReadingProgression? = null, defaults: EpubDefaults = EpubDefaults(), preferences: EpubPreferences = EpubPreferences() ): Layout { diff --git a/readium/opds/build.gradle.kts b/readium/opds/build.gradle.kts index e0bd80f0e7..8658e084d0 100644 --- a/readium/opds/build.gradle.kts +++ b/readium/opds/build.gradle.kts @@ -11,6 +11,8 @@ plugins { } android { + resourcePrefix = "readium_" + compileSdk = 33 defaultConfig { minSdk = 21 diff --git a/readium/opds/src/main/AndroidManifest.xml b/readium/opds/src/main/AndroidManifest.xml index b37569aae9..eb475b4918 100644 --- a/readium/opds/src/main/AndroidManifest.xml +++ b/readium/opds/src/main/AndroidManifest.xml @@ -1,10 +1,7 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> diff --git a/readium/shared/build.gradle.kts b/readium/shared/build.gradle.kts index f856087046..22dff30ed8 100644 --- a/readium/shared/build.gradle.kts +++ b/readium/shared/build.gradle.kts @@ -12,6 +12,8 @@ plugins { } android { + resourcePrefix = "readium_" + compileSdk = 33 defaultConfig { minSdk = 21 diff --git a/readium/shared/src/main/AndroidManifest.xml b/readium/shared/src/main/AndroidManifest.xml index cd35c46d46..eb475b4918 100644 --- a/readium/shared/src/main/AndroidManifest.xml +++ b/readium/shared/src/main/AndroidManifest.xml @@ -1,10 +1,7 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt index 8bebc7d340..17096f2095 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt @@ -23,15 +23,18 @@ import timber.log.Timber private val extraKey = "publicationId" private val deprecationException = IllegalArgumentException("The [publication] intent extra is not supported anymore. Use the shared [PublicationRepository] instead.") +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Intent.putPublication(publication: Publication) { val id = PublicationRepository.add(publication) putExtra(extraKey, id) } +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Intent.putPublicationFrom(activity: Activity) { putExtra(extraKey, activity.intent.getStringExtra(extraKey)) } +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Intent.getPublication(activity: Activity?): Publication { if (hasExtra("publication")) { if (BuildConfig.DEBUG) { @@ -53,6 +56,7 @@ fun Intent.getPublication(activity: Activity?): Publication { return publication } +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Intent.getPublicationOrNull(): Publication? { if (hasExtra("publication")) { if (BuildConfig.DEBUG) { @@ -67,9 +71,11 @@ fun Intent.getPublicationOrNull(): Publication? { @Suppress("UNUSED_PARAMETER") @Deprecated("The `activity` parameter is not necessary", ReplaceWith("getPublicationOrNull()"), level = DeprecationLevel.WARNING) -fun Intent.getPublicationOrNull(activity: Activity): Publication? = - getPublicationOrNull() +fun Intent.getPublicationOrNull(activity: Activity): Publication? { + throw NotImplementedError() +} +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Intent.destroyPublication(activity: Activity?) { if (activity == null || activity.isFinishing) { getStringExtra(extraKey)?.let { @@ -78,15 +84,18 @@ fun Intent.destroyPublication(activity: Activity?) { } } +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Bundle.putPublication(publication: Publication) { val id = PublicationRepository.add(publication) putString(extraKey, id) } +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Bundle.putPublicationFrom(activity: Activity) { putString(extraKey, activity.intent.getStringExtra(extraKey)) } +@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) fun Bundle.getPublicationOrNull(): Publication? { return getString(extraKey)?.let { PublicationRepository.get(it) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt index b872994de2..184fd5567f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt @@ -9,8 +9,6 @@ package org.readium.r2.shared.publication -import android.os.Parcelable -import kotlinx.parcelize.Parcelize import org.json.JSONArray import org.json.JSONObject import org.readium.r2.shared.JSONable @@ -27,7 +25,6 @@ import org.readium.r2.shared.util.mediatype.MediaType /** * Holds the metadata of a Readium publication, as described in the Readium Web Publication Manifest. */ -@Parcelize data class Manifest( val context: List = emptyList(), val metadata: Metadata, @@ -39,7 +36,7 @@ data class Manifest( val tableOfContents: List = emptyList(), val subcollections: Map> = emptyMap() -) : JSONable, Parcelable { +) : JSONable { /** * Returns whether this manifest conforms to the given Readium Web Publication Profile. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt index 6a54f8d3c6..ec760314e9 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt @@ -54,7 +54,7 @@ data class Metadata( val contributors: List = emptyList(), val publishers: List = emptyList(), val imprints: List = emptyList(), - val readingProgression: ReadingProgression = ReadingProgression.AUTO, + val readingProgression: ReadingProgression? = null, val description: String? = null, val duration: Double? = null, val numberOfPages: Int? = null, @@ -87,7 +87,7 @@ data class Metadata( contributors: List = emptyList(), publishers: List = emptyList(), imprints: List = emptyList(), - readingProgression: ReadingProgression = ReadingProgression.AUTO, + readingProgression: ReadingProgression? = null, description: String? = null, duration: Double? = null, numberOfPages: Int? = null, @@ -171,7 +171,7 @@ data class Metadata( @Deprecated("You should resolve [ReadingProgression.AUTO] by yourself.", level = DeprecationLevel.WARNING) @IgnoredOnParcel val effectiveReadingProgression: ReadingProgression get() { - if (readingProgression != ReadingProgression.AUTO) { + if (readingProgression != null) { return readingProgression } @@ -222,7 +222,7 @@ data class Metadata( putIfNotEmpty("contributor", contributors) putIfNotEmpty("publisher", publishers) putIfNotEmpty("imprint", imprints) - put("readingProgression", readingProgression.value) + put("readingProgression", readingProgression?.value ?: "auto") put("description", description) put("duration", duration) put("numberOfPages", numberOfPages) @@ -333,22 +333,24 @@ data class Metadata( } } - @Deprecated("Use [type] instead", ReplaceWith("type")) + @Deprecated("Use [type] instead", ReplaceWith("type"), level = DeprecationLevel.ERROR) val rdfType: String? get() = type - @Deprecated("Use [localizeTitle] instead.", ReplaceWith("localizedTitle")) + @Deprecated("Use [localizeTitle] instead.", ReplaceWith("localizedTitle"), level = DeprecationLevel.ERROR) val multilanguageTitle: LocalizedString? get() = localizedTitle - @Deprecated("Use [localizedTitle.get] instead", ReplaceWith("localizedTitle.translationForLanguage(key)?.string")) + @Deprecated("Use [localizedTitle.get] instead", ReplaceWith("localizedTitle.translationForLanguage(key)?.string"), level = DeprecationLevel.ERROR) fun titleForLang(key: String): String? = localizedTitle.getOrFallback(key)?.string - @Deprecated("Use [readingProgression] instead.", ReplaceWith("readingProgression")) + @Deprecated("Use [readingProgression] instead.", ReplaceWith("readingProgression"), level = DeprecationLevel.ERROR) val direction: String - get() = readingProgression.value + get() { + throw NotImplementedError() + } - @Deprecated("Use [published] instead", ReplaceWith("published?.toIso8601String()")) + @Deprecated("Use [published] instead", ReplaceWith("published?.toIso8601String()"), level = DeprecationLevel.ERROR) val publicationDate: String? get() = published?.toIso8601String() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt index c80c036e5f..f97b90de75 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt @@ -12,11 +12,7 @@ package org.readium.r2.shared.publication import android.net.Uri import android.os.Parcelable import java.net.URL -import java.net.URLEncoder import kotlin.reflect.KClass -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import org.json.JSONObject import org.readium.r2.shared.* @@ -36,10 +32,11 @@ import org.readium.r2.shared.publication.services.CoverService import org.readium.r2.shared.publication.services.DefaultLocatorService import org.readium.r2.shared.publication.services.LocatorService import org.readium.r2.shared.publication.services.PositionsService +import org.readium.r2.shared.publication.services.WebPositionsService import org.readium.r2.shared.publication.services.content.ContentService import org.readium.r2.shared.publication.services.search.SearchService import org.readium.r2.shared.util.Closeable -import org.readium.r2.shared.util.Ref +import org.readium.r2.shared.util.SuspendingCloseable import org.readium.r2.shared.util.mediatype.MediaType internal typealias ServiceFactory = (Publication.Service.Context) -> Publication.Service? @@ -68,25 +65,19 @@ class Publication( manifest: Manifest, private val fetcher: Fetcher = EmptyFetcher(), private val servicesBuilder: ServicesBuilder = ServicesBuilder(), - // FIXME: To refactor after specifying the User and Rendition Settings API - @Deprecated("Migrate to the new Settings API (see migration guide)") + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) var userSettingsUIPreset: MutableMap = mutableMapOf(), - @Deprecated("Migrate to the new Settings API (see migration guide)") + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) var cssStyle: String? = null, ) : PublicationServicesHolder { private val _manifest: Manifest + private val services = ListPublicationServicesHolder() init { - // We use a Ref instead of passing directly `this` to the services to prevent - // them from using the Publication before it is fully initialized. - val pubRef = Ref() - - services.services = servicesBuilder.build(Service.Context(pubRef, manifest, fetcher, services)) + services.services = servicesBuilder.build(Service.Context(manifest, fetcher, services)) _manifest = manifest.copy(links = manifest.links + services.services.map(Service::links).flatten()) - - pubRef.ref = this } // Shortcuts to manifest properties @@ -106,12 +97,8 @@ class Publication( val subcollections: Map> get() = _manifest.subcollections - @Deprecated("Use conformsTo() to check the kind of a publication.", level = DeprecationLevel.WARNING) - var type: TYPE = when { - metadata.type == "http://schema.org/Audiobook" || readingOrder.allAreAudio -> TYPE.AUDIO - readingOrder.allAreBitmap -> TYPE.DiViNa - else -> TYPE.WEBPUB - } + @Deprecated("Use conformsTo() to check the kind of a publication.", level = DeprecationLevel.ERROR) + var type: TYPE = TYPE.EPUB @Deprecated("Version is not available any more.", level = DeprecationLevel.ERROR) var version: Double = 0.0 @@ -177,16 +164,9 @@ class Publication( /** * Closes any opened resource associated with the [Publication], including services. */ - @OptIn(DelicateCoroutinesApi::class) - // TODO Change this to be a suspend function - override fun close() { - GlobalScope.launch { - tryOrLog { - fetcher.close() - } - - services.close() - } + override suspend fun close() { + fetcher.close() + services.close() } // PublicationServicesHolder @@ -197,10 +177,20 @@ class Publication( override fun findServices(serviceType: KClass): List = services.findServices(serviceType) + @Deprecated( + "Use Publication.Profile ", + replaceWith = ReplaceWith("Publication.Profile"), + level = DeprecationLevel.WARNING + ) enum class TYPE { - EPUB, CBZ, FXL, WEBPUB, AUDIO, DiViNa + EPUB } + @Deprecated( + "Use Publication.Profile ", + replaceWith = ReplaceWith("Publication.Profile"), + level = DeprecationLevel.ERROR + ) enum class EXTENSION(var value: String) { EPUB(".epub"), CBZ(".cbz"), @@ -209,11 +199,6 @@ class Publication( AUDIO(".audiobook"), LCPL(".lcpl"), UNKNOWN(""); - - companion object { - fun fromString(type: String): EXTENSION? = - values().firstOrNull { it.value == type } - } } /** @@ -243,22 +228,20 @@ class Publication( * Server, and set in the self [Link]. Unfortunately, the self [Link] is not available * in the navigator at the moment without changing the code in reading apps. */ - @Deprecated("The HTTP server is not needed anymore (see migration guide)") + @Suppress("UNUSED_PARAMETER") + @Deprecated("The HTTP server is not needed anymore (see migration guide)", level = DeprecationLevel.ERROR) fun localBaseUrlOf(filename: String, port: Int): String { - val sanitizedFilename = filename - .removePrefix("/") - .hash(HashAlgorithm.MD5) - .let { URLEncoder.encode(it, "UTF-8") } - - return "http://127.0.0.1:$port/$sanitizedFilename" + throw NotImplementedError() } /** * Gets the absolute URL of a resource locally served through HTTP. */ - @Deprecated("The HTTP server is not needed anymore (see migration guide)") - fun localUrlOf(filename: String, port: Int, href: String): String = - localBaseUrlOf(filename, port) + href + @Suppress("UNUSED_PARAMETER") + @Deprecated("The HTTP server is not needed anymore (see migration guide)", level = DeprecationLevel.ERROR) + fun localUrlOf(filename: String, port: Int, href: String): String { + throw NotImplementedError() + } @Suppress("UNUSED_PARAMETER") @Deprecated( @@ -304,16 +287,8 @@ class Publication( /** * Container for the context from which a service is created. - * - * @param publication Reference to the parent publication. - * Don't store directly the referenced publication, always access it through the - * [Ref] property. The publication won't be set when the service is created or when - * calling [Service.links], but you can use it during regular service operations. If - * you need to initialize your service differently depending on the publication, use - * `manifest`. */ class Context( - val publication: Ref, val manifest: Manifest, val fetcher: Fetcher, val services: PublicationServicesHolder @@ -377,7 +352,7 @@ class Publication( content: ServiceFactory? = null, contentProtection: ServiceFactory? = null, cover: ServiceFactory? = null, - locator: ServiceFactory? = { DefaultLocatorService(it.manifest.readingOrder, it.services) }, + locator: ServiceFactory? = null, positions: ServiceFactory? = null, search: ServiceFactory? = null, ) : this( @@ -393,7 +368,27 @@ class Publication( ) /** Builds the actual list of publication services to use in a Publication. */ - fun build(context: Service.Context): List = serviceFactories.values.mapNotNull { it(context) } + fun build(context: Service.Context): List { + val serviceFactories = + buildMap { + putAll(this@ServicesBuilder.serviceFactories) + + if (!containsKey(LocatorService::class.java.simpleName)) { + val factory: ServiceFactory = { + DefaultLocatorService(it.manifest.readingOrder, it.services) + } + put(LocatorService::class.java.simpleName, factory) + } + + if (!containsKey(PositionsService::class.java.simpleName)) { + val factory = WebPositionsService.createFactory() + put(PositionsService::class.java.simpleName, factory) + } + } + + return serviceFactories.values + .mapNotNull { it(context) } + } /** Gets the publication service factory for the given service type. */ operator fun get(serviceType: KClass): ServiceFactory? { @@ -530,7 +525,7 @@ class Publication( /** * Finds the first [Link] to the publication's cover (rel = cover). */ - @Deprecated("Use [Publication.cover] to get the cover as a [Bitmap]", ReplaceWith("cover")) + @Deprecated("Use [Publication.cover] to get the cover as a [Bitmap]", ReplaceWith("cover"), level = DeprecationLevel.ERROR) val coverLink: Link? get() = linkWithRel("cover") /** @@ -540,26 +535,26 @@ class Publication( */ @Suppress("DEPRECATION", "UNUSED_PARAMETER") @Deprecated("Use [Publication.copy(serviceFactories)] instead", ReplaceWith("Publication.copy(serviceFactories = listOf(positionsServiceFactory)"), level = DeprecationLevel.ERROR) - fun copyWithPositionsFactory(createFactory: Publication.() -> PositionListFactory): Publication { + fun copyWithPositionsFactory(): Publication { throw NotImplementedError() } - @Deprecated("Renamed to [listOfAudioClips]", ReplaceWith("listOfAudioClips")) + @Deprecated("Renamed to [listOfAudioClips]", ReplaceWith("listOfAudioClips"), level = DeprecationLevel.ERROR) val listOfAudioFiles: List = listOfAudioClips - @Deprecated("Renamed to [listOfVideoClips]", ReplaceWith("listOfVideoClips")) + @Deprecated("Renamed to [listOfVideoClips]", ReplaceWith("listOfVideoClips"), level = DeprecationLevel.ERROR) val listOfVideos: List = listOfVideoClips - @Deprecated("Renamed to [linkWithHref]", ReplaceWith("linkWithHref(href)")) + @Deprecated("Renamed to [linkWithHref]", ReplaceWith("linkWithHref(href)"), level = DeprecationLevel.ERROR) fun resource(href: String): Link? = linkWithHref(href) - @Deprecated("Refactored as a property", ReplaceWith("baseUrl")) + @Deprecated("Refactored as a property", ReplaceWith("baseUrl"), level = DeprecationLevel.ERROR) fun baseUrl(): URL? = baseUrl - @Deprecated("Renamed [subcollections]", ReplaceWith("subcollections")) + @Deprecated("Renamed [subcollections]", ReplaceWith("subcollections"), level = DeprecationLevel.ERROR) val otherCollections: Map> get() = subcollections - @Deprecated("Use [setSelfLink] instead", ReplaceWith("setSelfLink")) + @Deprecated("Use [setSelfLink] instead", ReplaceWith("setSelfLink"), level = DeprecationLevel.ERROR) fun addSelfLink(endPoint: String, baseURL: URL) { setSelfLink( Uri.parse(baseURL.toString()) @@ -573,7 +568,7 @@ class Publication( /** * Finds the first resource [Link] (asset or [readingOrder] item) at the given relative path. */ - @Deprecated("Use [linkWithHref] instead.", ReplaceWith("linkWithHref(href)")) + @Deprecated("Use [linkWithHref] instead.", ReplaceWith("linkWithHref(href)"), level = DeprecationLevel.ERROR) fun resourceWithHref(href: String): Link? = linkWithHref(href) /** @@ -583,7 +578,7 @@ class Publication( * might want to use a custom factory to implement, for example, a caching mechanism or use a * different calculation method. */ - @Deprecated("Use a [ServiceFactory] for a [PositionsService] instead.") + @Deprecated("Use a [ServiceFactory] for a [PositionsService] instead.", level = DeprecationLevel.ERROR) interface PositionListFactory { fun create(): List } @@ -614,7 +609,7 @@ class Publication( /** * Holds [Publication.Service] instances for a [Publication]. */ -interface PublicationServicesHolder { +interface PublicationServicesHolder : SuspendingCloseable { /** * Returns the first publication service that is an instance of [serviceType]. */ @@ -624,11 +619,6 @@ interface PublicationServicesHolder { * Returns all the publication services that are instances of [serviceType]. */ fun findServices(serviceType: KClass): List - - /** - * Closes the publication services. - */ - fun close() } internal class ListPublicationServicesHolder( @@ -640,7 +630,7 @@ internal class ListPublicationServicesHolder( override fun findServices(serviceType: KClass): List = services.filterIsInstance(serviceType.java) - override fun close() { + override suspend fun close() { for (service in services) { tryOrLog { service.close() } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt index 0cd5ab954c..38910ec267 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt @@ -14,7 +14,7 @@ import java.util.* import kotlinx.parcelize.Parcelize import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import org.readium.r2.shared.util.MapWithDefaultCompanion +import org.readium.r2.shared.util.MapCompanion @Serializable @Parcelize @@ -22,23 +22,9 @@ enum class ReadingProgression(val value: String) : Parcelable { /** Right to left */ @SerialName("rtl") RTL("rtl"), /** Left to right */ - @SerialName("ltr") LTR("ltr"), - /** Top to bottom */ - @SerialName("ttb") TTB("ttb"), - /** Bottom to top */ - @SerialName("btt") BTT("btt"), - @SerialName("auto") AUTO("auto"); + @SerialName("ltr") LTR("ltr"); - /** - * Indicates whether this reading progression is on the horizontal axis, or null if unknown. - */ - val isHorizontal: Boolean? get() = when (this) { - RTL, LTR -> true - TTB, BTT -> false - AUTO -> null - } - - companion object : MapWithDefaultCompanion(values(), ReadingProgression::value, AUTO) { + companion object : MapCompanion(values(), ReadingProgression::value) { override fun get(key: String?): ReadingProgression? = // For backward compatibility, we allow uppercase keys. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt index ea5feb1776..a1284d153f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt @@ -99,8 +99,8 @@ interface ContentProtection { * app. */ class SchemeNotSupported(val scheme: Scheme? = null, name: String?) : Exception( - if (name == null) R.string.r2_shared_publication_content_protection_exception_not_supported_unknown - else R.string.r2_shared_publication_content_protection_exception_not_supported, + if (name == null) R.string.readium_shared_publication_content_protection_exception_not_supported_unknown + else R.string.readium_shared_publication_content_protection_exception_not_supported, name ) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt index 45542e63f1..143585e2f0 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt @@ -55,34 +55,20 @@ interface PositionsService : Publication.Service { } } -private suspend fun Publication.positionsFromManifest(): List = - links.firstWithMediaType(positionsLink.mediaType) - ?.let { get(it) } - ?.readAsString() - ?.getOrNull() - ?.toJsonOrNull() - ?.optJSONArray("positions") - ?.mapNotNull { Locator.fromJSON(it as? JSONObject) } - .orEmpty() - /** * Returns the list of all the positions in the publication, grouped by the resource reading order index. */ -suspend fun Publication.positionsByReadingOrder(): List> { - findService(PositionsService::class)?.let { - return it.positionsByReadingOrder() - } - - val locators = positionsFromManifest().groupBy(Locator::href) - return readingOrder.map { locators[it.href].orEmpty() } +suspend fun PublicationServicesHolder.positionsByReadingOrder(): List> { + checkNotNull(findService(PositionsService::class)) { "No position service found." } + .let { return it.positionsByReadingOrder() } } /** * Returns the list of all the positions in the publication. */ -suspend fun Publication.positions(): List { - return findService(PositionsService::class)?.positions() - ?: positionsFromManifest() +suspend fun PublicationServicesHolder.positions(): List { + checkNotNull(findService(PositionsService::class)) { "No position service found." } + .let { return it.positions() } } /** @@ -137,3 +123,44 @@ class PerResourcePositionsService( } } } + +internal class WebPositionsService( + private val manifest: Manifest +) : PositionsService { + + private lateinit var _positions: List + + override val links: List = + listOfNotNull( + manifest.links.firstWithMediaType(positionsLink.mediaType) + ) + + override suspend fun positions(): List { + if (!::_positions.isInitialized) + _positions = computePositions() + + return _positions + } + + override suspend fun positionsByReadingOrder(): List> { + val locators = positions().groupBy(Locator::href) + return manifest.readingOrder.map { locators[it.href].orEmpty() } + } + + private suspend fun computePositions(): List = + links.firstOrNull() + ?.let { get(it) } + ?.readAsString() + ?.getOrNull() + ?.toJsonOrNull() + ?.optJSONArray("positions") + ?.mapNotNull { Locator.fromJSON(it as? JSONObject) } + .orEmpty() + + companion object { + + fun createFactory(): (Publication.Service.Context) -> WebPositionsService = { + WebPositionsService(it.manifest) + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt index 00cd125816..ee0cbc5836 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt @@ -7,12 +7,11 @@ package org.readium.r2.shared.publication.services.content import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.ServiceFactory import org.readium.r2.shared.publication.services.content.iterators.PublicationContentIterator import org.readium.r2.shared.publication.services.content.iterators.ResourceContentIteratorFactory -import org.readium.r2.shared.util.Ref /** * Provides a way to extract the raw [Content] of a [Publication]. @@ -52,7 +51,9 @@ var Publication.ServicesBuilder.contentServiceFactory: ServiceFactory? */ @ExperimentalReadiumApi class DefaultContentService( - private val publication: Ref, + private val manifest: Manifest, + private val fetcher: Fetcher, + private val services: PublicationServicesHolder, private val resourceContentIteratorFactories: List ) : ContentService { @@ -60,22 +61,25 @@ class DefaultContentService( fun createFactory( resourceContentIteratorFactories: List ): (Publication.Service.Context) -> DefaultContentService = { context -> - DefaultContentService(context.publication, resourceContentIteratorFactories) + DefaultContentService(context.manifest, context.fetcher, context.services, resourceContentIteratorFactories) } } override fun content(start: Locator?): Content { - val publication = publication() ?: throw IllegalStateException("No Publication object") - return ContentImpl(publication, start) + return ContentImpl(manifest, fetcher, services, start) } private inner class ContentImpl( - val publication: Publication, + val manifest: Manifest, + val fetcher: Fetcher, + val services: PublicationServicesHolder, val start: Locator?, ) : Content { override fun iterator(): Content.Iterator = PublicationContentIterator( - publication = publication, + manifest = manifest, + fetcher = fetcher, + services = services, startLocator = start, resourceContentIteratorFactories = resourceContentIteratorFactories ) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index a6918eaa3e..eecbdb4606 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -18,9 +18,7 @@ import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.html.cssSelector import org.readium.r2.shared.publication.services.content.Content import org.readium.r2.shared.publication.services.content.Content.* @@ -53,7 +51,8 @@ class HtmlResourceContentIterator internal constructor( class Factory : ResourceContentIteratorFactory { override suspend fun create( - publication: Publication, + manifest: Manifest, + servicesHolder: PublicationServicesHolder, readingOrderIndex: Int, resource: Fetcher.Resource, locator: Locator @@ -62,7 +61,7 @@ class HtmlResourceContentIterator internal constructor( return null } - val positions = publication.positionsByReadingOrder() + val positions = servicesHolder.positionsByReadingOrder() return HtmlResourceContentIterator( resource, totalProgressionRange = positions.getOrNull(readingOrderIndex) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt index f1626a9f39..691542f59a 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt @@ -8,15 +8,12 @@ package org.readium.r2.shared.publication.services.content.iterators import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.indexOfFirstWithHref +import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.services.content.Content import org.readium.r2.shared.util.Either /** - * Creates a [Content.Iterator] instance for the [Resource], starting from the given [Locator]. + * Creates a [Content.Iterator] instance for the [Fetcher.Resource], starting from the given [Locator]. * * Returns null if the resource media type is not supported. */ @@ -29,7 +26,8 @@ fun interface ResourceContentIteratorFactory { * Returns null if the resource media type is not supported. */ suspend fun create( - publication: Publication, + manifest: Manifest, + servicesHolder: PublicationServicesHolder, readingOrderIndex: Int, resource: Fetcher.Resource, locator: Locator @@ -48,7 +46,9 @@ fun interface ResourceContentIteratorFactory { */ @ExperimentalReadiumApi class PublicationContentIterator( - private val publication: Publication, + private val manifest: Manifest, + private val fetcher: Fetcher, + private val services: PublicationServicesHolder, private val startLocator: Locator?, private val resourceContentIteratorFactories: List ) : Content.Iterator { @@ -119,7 +119,7 @@ class PublicationContentIterator( */ private suspend fun initialIterator(): IndexedIterator? { val index: Int = - startLocator?.let { publication.readingOrder.indexOfFirstWithHref(it.href) } + startLocator?.let { manifest.readingOrder.indexOfFirstWithHref(it.href) } ?: 0 val locations = startLocator.orProgression(0.0) @@ -133,7 +133,7 @@ class PublicationContentIterator( */ private suspend fun nextIteratorIn(direction: Direction, fromIndex: Int): IndexedIterator? { val index = fromIndex + direction.delta - if (!publication.readingOrder.indices.contains(index)) { + if (!manifest.readingOrder.indices.contains(index)) { return null } @@ -152,13 +152,13 @@ class PublicationContentIterator( * The [location] will be used to compute the starting [Locator] for the iterator. */ private suspend fun loadIteratorAt(index: Int, location: LocatorOrProgression): IndexedIterator? { - val link = publication.readingOrder[index] + val link = manifest.readingOrder[index] val locator = location.toLocator(link) ?: return null - val resource = publication.get(link) + val resource = fetcher.get(link) return resourceContentIteratorFactories .firstNotNullOfOrNull { factory -> - factory.create(publication, index, resource, locator) + factory.create(manifest, services, index, resource, locator) } ?.let { IndexedIterator(index, it) } } @@ -175,7 +175,7 @@ class PublicationContentIterator( private fun LocatorOrProgression.toLocator(link: Link): Locator? = left - ?: publication.locatorFromLink(link)?.copyWithLocations(progression = right) + ?: manifest.locatorFromLink(link)?.copyWithLocations(progression = right) } /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt index 10b6ce41ec..5cc6ecf468 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt @@ -36,7 +36,7 @@ sealed class SearchException(content: Content, cause: Throwable? = null) : UserE /** * The publication is not searchable. */ - object PublicationNotSearchable : SearchException(R.string.r2_shared_search_exception_publication_not_searchable) + object PublicationNotSearchable : SearchException(R.string.readium_shared_search_exception_publication_not_searchable) /** * The provided search query cannot be handled by the service. @@ -58,10 +58,10 @@ sealed class SearchException(content: Content, cause: Throwable? = null) : UserE * * For example, when a coroutine or a network request is cancelled. */ - object Cancelled : SearchException(R.string.r2_shared_search_exception_cancelled) + object Cancelled : SearchException(R.string.readium_shared_search_exception_cancelled) /** For any other custom service error. */ - class Other(cause: Throwable) : SearchException(R.string.r2_shared_search_exception_other, cause = cause) + class Other(cause: Throwable) : SearchException(R.string.readium_shared_search_exception_other, cause = cause) companion object { fun wrap(e: Throwable): SearchException = diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt index 859af9eb1d..fce72879c2 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt @@ -20,14 +20,11 @@ import org.readium.r2.shared.Search import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.fetcher.DefaultResourceContentExtractorFactory +import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.ResourceContentExtractor -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.LocatorCollection -import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.services.positionsByReadingOrder import org.readium.r2.shared.publication.services.search.SearchService.Options -import org.readium.r2.shared.util.Ref import timber.log.Timber /** @@ -42,7 +39,9 @@ import timber.log.Timber */ @Search class StringSearchService( - private val publication: Ref, + private val manifest: Manifest, + private val fetcher: Fetcher, + private val services: PublicationServicesHolder, val language: String?, private val snippetLength: Int, private val searchAlgorithm: Algorithm, @@ -57,7 +56,9 @@ class StringSearchService( ): (Publication.Service.Context) -> StringSearchService = { context -> StringSearchService( - publication = context.publication, + manifest = context.manifest, + fetcher = context.fetcher, + services = context.services, language = context.manifest.metadata.languages.firstOrNull(), snippetLength = snippetLength, searchAlgorithm = searchAlgorithm @@ -76,7 +77,8 @@ class StringSearchService( try { Try.success( Iterator( - publication = publication() ?: throw IllegalStateException("No Publication object"), + manifest = manifest, + fetcher = fetcher, query = query, options = options ?: Options(), locale = options?.language?.let { Locale.forLanguageTag(it) } ?: locale, @@ -87,7 +89,8 @@ class StringSearchService( } private inner class Iterator( - val publication: Publication, + val manifest: Manifest, + val fetcher: Fetcher, val query: String, val options: Options, val locale: Locale @@ -103,14 +106,14 @@ class StringSearchService( override suspend fun next(): SearchTry { try { - if (index >= publication.readingOrder.count() - 1) { + if (index >= manifest.readingOrder.count() - 1) { return Try.success(null) } index += 1 - val link = publication.readingOrder[index] - val resource = publication.get(link) + val link = manifest.readingOrder[index] + val resource = fetcher.get(link) val text = extractorFactory.createExtractor(resource)?.extractText(resource)?.getOrThrow() if (text == null) { @@ -137,8 +140,8 @@ class StringSearchService( if (text == "") return emptyList() - val resourceTitle = publication.tableOfContents.titleMatching(link.href) - var resourceLocator = publication.locatorFromLink(link) ?: return emptyList() + val resourceTitle = manifest.tableOfContents.titleMatching(link.href) + var resourceLocator = manifest.locatorFromLink(link) ?: return emptyList() resourceLocator = resourceLocator.copy(title = resourceTitle ?: resourceLocator.title) val locators = mutableListOf() @@ -214,7 +217,7 @@ class StringSearchService( private lateinit var _positions: List> private suspend fun positions(): List> { if (!::_positions.isInitialized) { - _positions = publication.positionsByReadingOrder() + _positions = services.positionsByReadingOrder() } return _positions } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt index cfe7215657..98535ff0a9 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt @@ -71,11 +71,11 @@ interface Resource : SuspendingCloseable { /** Equivalent to a 400 HTTP error. */ class BadRequest(val parameters: Map = emptyMap(), cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_bad_request, cause) + Exception(R.string.readium_shared_resource_exception_bad_request, cause) /** Equivalent to a 404 HTTP error. */ class NotFound(cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_not_found, cause) + Exception(R.string.readium_shared_resource_exception_not_found, cause) /** * Equivalent to a 403 HTTP error. @@ -84,7 +84,7 @@ interface Resource : SuspendingCloseable { * unlocked. */ class Forbidden(cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_forbidden, cause) + Exception(R.string.readium_shared_resource_exception_forbidden, cause) /** * Equivalent to a 503 HTTP error. @@ -93,12 +93,12 @@ interface Resource : SuspendingCloseable { * file system. Usually this is a temporary error. */ class Unavailable(cause: Throwable? = null) : - Exception(R.string.r2_shared_resource_exception_unavailable, cause) + Exception(R.string.readium_shared_resource_exception_unavailable, cause) /** * The Internet connection appears to be offline. */ - object Offline : Exception(R.string.r2_shared_resource_exception_offline) + object Offline : Exception(R.string.readium_shared_resource_exception_offline) /** * Equivalent to a 507 HTTP error. @@ -106,10 +106,10 @@ interface Resource : SuspendingCloseable { * Used when the requested range is too large to be read in memory. */ class OutOfMemory(override val cause: OutOfMemoryError) : - Exception(R.string.r2_shared_resource_exception_out_of_memory) + Exception(R.string.readium_shared_resource_exception_out_of_memory) /** For any other error, such as HTTP 500. */ - class Other(cause: Throwable) : Exception(R.string.r2_shared_resource_exception_other, cause) + class Other(cause: Throwable) : Exception(R.string.readium_shared_resource_exception_other, cause) companion object { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt index 7a858d1860..07647ba435 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt @@ -38,7 +38,7 @@ open class MapCompanion(protected val map: Map) { /** * Returns the element matching the [key], or [null] if not found. * - * To be overriden in subclasses if custom retrieval is needed – for example, testing lowercase + * To be overridden in subclasses if custom retrieval is needed – for example, testing lowercase * keys. */ open fun get(key: K?): E? = @@ -49,7 +49,7 @@ open class MapCompanion(protected val map: Map) { */ open operator fun invoke(key: K?): E? = get(key) - @Deprecated("Use `Enum(\"value\")` instead", ReplaceWith("get(key)")) + @Deprecated("Use `Enum(\"value\")` instead", ReplaceWith("get(key)"), level = DeprecationLevel.ERROR) open fun from(key: K?): E? = get(key) } @@ -72,6 +72,6 @@ open class MapWithDefaultCompanion(map: Map, val default: E) : MapCo */ override operator fun invoke(key: K?): E = getOrDefault(key) - @Deprecated("Use `Enum(\"value\")` instead", ReplaceWith("getOrDefault(key)")) + @Deprecated("Use `Enum(\"value\")` instead", ReplaceWith("getOrDefault(key)"), level = DeprecationLevel.ERROR) override fun from(key: K?): E? = getOrDefault(key) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt index ffb7e715dd..ebb6ed6919 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt @@ -37,29 +37,29 @@ class HttpException( enum class Kind(@StringRes val userMessageId: Int) { /** The provided request was not valid. */ - MalformedRequest(R.string.r2_shared_http_exception_malformed_request), + MalformedRequest(R.string.readium_shared_http_exception_malformed_request), /** The received response couldn't be decoded. */ - MalformedResponse(R.string.r2_shared_http_exception_malformed_response), + MalformedResponse(R.string.readium_shared_http_exception_malformed_response), /** The client, server or gateways timed out. */ - Timeout(R.string.r2_shared_http_exception_timeout), + Timeout(R.string.readium_shared_http_exception_timeout), /** (400) The server cannot or will not process the request due to an apparent client error. */ - BadRequest(R.string.r2_shared_http_exception_bad_request), + BadRequest(R.string.readium_shared_http_exception_bad_request), /** (401) Authentication is required and has failed or has not yet been provided. */ - Unauthorized(R.string.r2_shared_http_exception_unauthorized), + Unauthorized(R.string.readium_shared_http_exception_unauthorized), /** (403) The server refuses the action, probably because we don't have the necessary permissions. */ - Forbidden(R.string.r2_shared_http_exception_forbidden), + Forbidden(R.string.readium_shared_http_exception_forbidden), /** (404) The requested resource could not be found. */ - NotFound(R.string.r2_shared_http_exception_not_found), + NotFound(R.string.readium_shared_http_exception_not_found), /** (4xx) Other client errors */ - ClientError(R.string.r2_shared_http_exception_client_error), + ClientError(R.string.readium_shared_http_exception_client_error), /** (5xx) Server errors */ - ServerError(R.string.r2_shared_http_exception_server_error), + ServerError(R.string.readium_shared_http_exception_server_error), /** The device is offline. */ - Offline(R.string.r2_shared_http_exception_offline), + Offline(R.string.readium_shared_http_exception_offline), /** The request was cancelled. */ - Cancelled(R.string.r2_shared_http_exception_cancelled), + Cancelled(R.string.readium_shared_http_exception_cancelled), /** An error whose kind is not recognized. */ - Other(R.string.r2_shared_http_exception_other); + Other(R.string.readium_shared_http_exception_other); companion object { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt index 217bc7acdd..3012ccf98f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt @@ -89,7 +89,7 @@ interface PdfDocument : SuspendingCloseable { /** * Default reading progression of the document. */ - val readingProgression: ReadingProgression get() = ReadingProgression.AUTO + val readingProgression: ReadingProgression? get() = null /** * The first page rendered as a cover. diff --git a/readium/shared/src/main/res/values/strings.xml b/readium/shared/src/main/res/values/strings.xml index 561be95fe9..8a9ab3d352 100644 --- a/readium/shared/src/main/res/values/strings.xml +++ b/readium/shared/src/main/res/values/strings.xml @@ -6,39 +6,39 @@ --> - Format not supported - File not found - The file is corrupted and can\'t be opened - You are not allowed to open this publication - Not available, please try again later - Provided credentials were incorrect + Format not supported + File not found + The file is corrupted and can\'t be opened + You are not allowed to open this publication + Not available, please try again later + Provided credentials were incorrect - This publication cannot be opened because it is protected with %1$s - This publication cannot be opened because it is protected with an unknown DRM + This publication cannot be opened because it is protected with %1$s + This publication cannot be opened because it is protected with an unknown DRM - Invalid request which can\'t be processed - Resource not found - You are not allowed to access the resource - The resource is currently unavailable, please try again later - The Internet connection appears to be offline - The resource is too large to be read on this device - An expected error occurred. - A service error occurred + Invalid request which can\'t be processed + Resource not found + You are not allowed to access the resource + The resource is currently unavailable, please try again later + The Internet connection appears to be offline + The resource is too large to be read on this device + An expected error occurred. + A service error occurred - The provided request was not valid - The received response could not be decoded - Request timed out - The provided request was not valid - Authentication required - You are not authorized - Page not found - A client error occurred - A server error occurred, please try again later - Your Internet connection appears to be offline - The request was cancelled - A networking error occurred + The provided request was not valid + The received response could not be decoded + Request timed out + The provided request was not valid + Authentication required + You are not authorized + Page not found + A client error occurred + A server error occurred, please try again later + Your Internet connection appears to be offline + The request was cancelled + A networking error occurred - This publication is not searchable - The search was cancelled - An error occurred while searching + This publication is not searchable + The search was cancelled + An error occurred while searching \ No newline at end of file diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt index 7d5d8e7f8d..9906ee0d09 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt @@ -325,7 +325,7 @@ class MetadataTest { } @Test fun `get primary language with no language`() { - assertNull(createMetadata(languages = listOf(), readingProgression = ReadingProgression.AUTO).language) + assertNull(createMetadata(languages = listOf(), readingProgression = null).language) assertNull(createMetadata(languages = listOf(), readingProgression = ReadingProgression.LTR).language) assertNull(createMetadata(languages = listOf(), readingProgression = ReadingProgression.RTL).language) } @@ -333,7 +333,7 @@ class MetadataTest { @Test fun `get primary language with a single language`() { assertEquals( Language("en"), - createMetadata(languages = listOf("en"), readingProgression = ReadingProgression.AUTO).language + createMetadata(languages = listOf("en"), readingProgression = null).language ) assertEquals( Language("en"), @@ -345,6 +345,6 @@ class MetadataTest { ) } - private fun createMetadata(languages: List, readingProgression: ReadingProgression): Metadata = + private fun createMetadata(languages: List, readingProgression: ReadingProgression?): Metadata = Metadata(localizedTitle = LocalizedString("Title"), languages = languages, readingProgression = readingProgression) } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt index 0d307774a9..754e38c6fa 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt @@ -11,21 +11,19 @@ package org.readium.r2.shared.publication import java.net.URL import kotlinx.coroutines.runBlocking -import org.json.JSONObject import org.junit.Assert.* import org.junit.Test import org.junit.runner.RunWith -import org.readium.r2.shared.Fixtures import org.readium.r2.shared.fetcher.EmptyFetcher import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.fetcher.StringResource import org.readium.r2.shared.publication.Publication.Profile import org.readium.r2.shared.publication.services.DefaultLocatorService import org.readium.r2.shared.publication.services.PositionsService +import org.readium.r2.shared.publication.services.WebPositionsService import org.readium.r2.shared.publication.services.positions import org.readium.r2.shared.publication.services.positionsByReadingOrder import org.readium.r2.shared.resource.readAsString -import org.readium.r2.shared.util.Ref import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -35,7 +33,7 @@ class PublicationTest { conformsTo: Set = emptySet(), title: String = "Title", language: String = "en", - readingProgression: ReadingProgression = ReadingProgression.AUTO, + readingProgression: ReadingProgression? = null, links: List = listOf(), readingOrder: List = emptyList(), resources: List = emptyList(), @@ -55,18 +53,6 @@ class PublicationTest { servicesBuilder = servicesBuilder ) - @Suppress("DEPRECATION") - @Test fun `get the type computed from the manifest content`() { - val fixtures = Fixtures("format") - fun parseAt(path: String): Publication = - Publication(manifest = Manifest.fromJSON(JSONObject(fixtures.fileAt(path).readText()))!!) - - assertEquals(Publication.TYPE.AUDIO, parseAt("audiobook.json").type) - assertEquals(Publication.TYPE.DiViNa, parseAt("divina.json").type) - assertEquals(Publication.TYPE.WEBPUB, parseAt("webpub.json").type) - assertEquals(Publication.TYPE.WEBPUB, parseAt("opds2-publication.json").type) - } - @Test fun `get the default empty {positions}`() { assertEquals(emptyList(), runBlocking { createPublication().positions() }) } @@ -444,29 +430,6 @@ class PublicationTest { @Test fun `find the first resource {Link} with the given {href} when missing`() { assertNull(createPublication().linkWithHref("foobar")) } - - @Suppress("DEPRECATION") - @Test fun `find the cover {Link}`() { - val coverLink = Link(href = "cover", rels = setOf("cover")) - val publication = createPublication( - links = listOf(Link(href = "other"), coverLink), - readingOrder = listOf(Link(href = "other")), - resources = listOf(Link(href = "other")) - ) - - assertEquals(coverLink, publication.coverLink) - } - - @Suppress("DEPRECATION") - @Test fun `find the cover {Link} when missing`() { - val publication = createPublication( - links = listOf(Link(href = "other")), - readingOrder = listOf(Link(href = "other")), - resources = listOf(Link(href = "other")) - ) - - assertNull(publication.coverLink) - } } class ServicesBuilderTest { @@ -480,7 +443,6 @@ class ServicesBuilderTest { class BarServiceA : BarService() private val context = Publication.Service.Context( - publication = Ref(), manifest = Manifest(metadata = Metadata(localizedTitle = LocalizedString())), fetcher = EmptyFetcher(), services = ListPublicationServicesHolder() @@ -503,8 +465,9 @@ class ServicesBuilderTest { fun testBuildEmpty() { val builder = Publication.ServicesBuilder(cover = null) val services = builder.build(context) - assertEquals(1, services.size) + assertEquals(2, services.size) assertNotNull(services.find()) + assertNotNull(services.find()) } @Test diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/ReadingProgressionTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/ReadingProgressionTest.kt index 2900af969a..dcc1c1c963 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/ReadingProgressionTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/ReadingProgressionTest.kt @@ -10,26 +10,13 @@ class ReadingProgressionTest { assertEquals(ReadingProgression.LTR, ReadingProgression("LTR")) assertEquals(ReadingProgression.LTR, ReadingProgression("ltr")) assertEquals(ReadingProgression.RTL, ReadingProgression("rtl")) - assertEquals(ReadingProgression.TTB, ReadingProgression("ttb")) - assertEquals(ReadingProgression.BTT, ReadingProgression("btt")) - assertEquals(ReadingProgression.AUTO, ReadingProgression("auto")) - assertEquals(ReadingProgression.AUTO, ReadingProgression("foobar")) - assertEquals(ReadingProgression.AUTO, ReadingProgression(null)) + assertEquals(null, ReadingProgression("auto")) + assertEquals(null, ReadingProgression("foobar")) + assertEquals(null, ReadingProgression(null)) } @Test fun `get reading progression value`() { assertEquals("ltr", ReadingProgression.LTR.value) assertEquals("rtl", ReadingProgression.RTL.value) - assertEquals("ttb", ReadingProgression.TTB.value) - assertEquals("btt", ReadingProgression.BTT.value) - assertEquals("auto", ReadingProgression.AUTO.value) - } - - @Test fun `is horizontal`() { - assertNull(ReadingProgression.AUTO.isHorizontal) - assertTrue(ReadingProgression.LTR.isHorizontal!!) - assertTrue(ReadingProgression.RTL.isHorizontal!!) - assertFalse(ReadingProgression.TTB.isHorizontal!!) - assertFalse(ReadingProgression.BTT.isHorizontal!!) } } diff --git a/readium/streamer/build.gradle.kts b/readium/streamer/build.gradle.kts index 0d30a46089..2d9a1df15b 100644 --- a/readium/streamer/build.gradle.kts +++ b/readium/streamer/build.gradle.kts @@ -11,6 +11,8 @@ plugins { } android { + resourcePrefix = "readium_" + compileSdk = 33 defaultConfig { minSdk = 21 diff --git a/readium/streamer/src/main/AndroidManifest.xml b/readium/streamer/src/main/AndroidManifest.xml index c2b1d5cfd6..eb475b4918 100644 --- a/readium/streamer/src/main/AndroidManifest.xml +++ b/readium/streamer/src/main/AndroidManifest.xml @@ -1,10 +1,7 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt index 9d59974ae4..b05c7245c2 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt @@ -20,13 +20,11 @@ import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.logging.WarningLogger -import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.shared.util.pdf.PdfDocumentFactory import org.readium.r2.streamer.parser.PublicationParser import org.readium.r2.streamer.parser.audio.AudioParser import org.readium.r2.streamer.parser.epub.EpubParser -import org.readium.r2.streamer.parser.epub.setLayoutStyle import org.readium.r2.streamer.parser.image.ImageParser import org.readium.r2.streamer.parser.pdf.PdfParser import org.readium.r2.streamer.parser.readium.ReadiumWebPubParser @@ -198,7 +196,6 @@ class PublicationFactory constructor( builder.apply(onCreatePublication) val publication = builder.build() - .apply { addLegacyProperties(publicationAsset.mediaType) } return Try.success(publication) } @@ -248,21 +245,4 @@ class PublicationFactory constructor( } return null } - - private fun Publication.addLegacyProperties(mediaType: MediaType?) { - @Suppress("DEPRECATION") - type = mediaType.toPublicationType() - - if (mediaType == MediaType.EPUB) - setLayoutStyle() - } } - -internal fun MediaType?.toPublicationType(): Publication.TYPE = - when (this) { - MediaType.READIUM_AUDIOBOOK, MediaType.READIUM_AUDIOBOOK_MANIFEST, MediaType.LCP_PROTECTED_AUDIOBOOK -> Publication.TYPE.AUDIO - MediaType.DIVINA, MediaType.DIVINA_MANIFEST -> Publication.TYPE.DiViNa - MediaType.CBZ -> Publication.TYPE.CBZ - MediaType.EPUB -> Publication.TYPE.EPUB - else -> Publication.TYPE.WEBPUB - } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt index c598e2f84a..eac71522fc 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt @@ -4,12 +4,9 @@ * available in the top-level LICENSE file of the project. */ -@file:Suppress("DEPRECATION") - package org.readium.r2.streamer.parser.epub import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.ReadiumCSSName import org.readium.r2.shared.Search import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.getOrElse @@ -30,48 +27,6 @@ import org.readium.r2.shared.util.use import org.readium.r2.streamer.extensions.readAsXmlOrNull import org.readium.r2.streamer.parser.PublicationParser -@Suppress("DEPRECATION") -object EPUBConstant { - - @Deprecated("Use [MediaType.EPUB.toString()] instead", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("MediaType.EPUB.toString()")) - val mimetype: String get() = MediaType.EPUB.toString() - - internal val ltrPreset: MutableMap = mutableMapOf( - ReadiumCSSName.ref("hyphens") to false, - ReadiumCSSName.ref("ligatures") to false - ) - - internal val rtlPreset: MutableMap = mutableMapOf( - ReadiumCSSName.ref("hyphens") to false, - ReadiumCSSName.ref("wordSpacing") to false, - ReadiumCSSName.ref("letterSpacing") to false, - ReadiumCSSName.ref("ligatures") to true - ) - - internal val cjkHorizontalPreset: MutableMap = mutableMapOf( - ReadiumCSSName.ref("textAlignment") to false, - ReadiumCSSName.ref("hyphens") to false, - ReadiumCSSName.ref("paraIndent") to false, - ReadiumCSSName.ref("wordSpacing") to false, - ReadiumCSSName.ref("letterSpacing") to false - ) - - internal val cjkVerticalPreset: MutableMap = mutableMapOf( - ReadiumCSSName.ref("scroll") to true, - ReadiumCSSName.ref("columnCount") to false, - ReadiumCSSName.ref("textAlignment") to false, - ReadiumCSSName.ref("hyphens") to false, - ReadiumCSSName.ref("paraIndent") to false, - ReadiumCSSName.ref("wordSpacing") to false, - ReadiumCSSName.ref("letterSpacing") to false - ) - - @Deprecated("Use the new Settings API", level = DeprecationLevel.ERROR) - val forceScrollPreset: MutableMap = mutableMapOf( - ReadiumCSSName.ref("scroll") to true - ) -} - /** * Parses a Publication from an EPUB publication. * @@ -119,7 +74,7 @@ class EpubParser( positions = EpubPositionsService.createFactory(reflowablePositionsStrategy), search = StringSearchService.createDefaultFactory(), content = DefaultContentService.createFactory( - listOf( + resourceContentIteratorFactories = listOf( HtmlResourceContentIterator.Factory() ) ), @@ -190,17 +145,3 @@ class EpubParser( ?.toMap().orEmpty() } } - -@Suppress("DEPRECATION") -internal fun Publication.setLayoutStyle() { - val layout = ReadiumCssLayout(metadata) - - cssStyle = layout.cssId - - userSettingsUIPreset = when (layout) { - ReadiumCssLayout.RTL -> EPUBConstant.rtlPreset - ReadiumCssLayout.LTR -> EPUBConstant.ltrPreset - ReadiumCssLayout.CJK_VERTICAL -> EPUBConstant.cjkVerticalPreset - ReadiumCssLayout.CJK_HORIZONTAL -> EPUBConstant.cjkHorizontalPreset - } -} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt index da18d18c2c..c4ff6a7a7d 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt @@ -16,7 +16,7 @@ internal class MetadataAdapter( private val epubVersion: Double, private val fallbackTitle: String, private val uniqueIdentifierId: String?, - private val readingProgression: ReadingProgression, + private val readingProgression: ReadingProgression?, private val displayOptions: Map ) { data class Result( diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt index 84b1bdfd2d..6b1baad4c4 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt @@ -57,7 +57,7 @@ internal data class Item( val href = element.getAttr("href")?.let { Href(it, baseHref = filePath).string } ?: return null val propAttr = element.getAttr("properties").orEmpty() - val properties = parseProperties(propAttr).mapNotNull { resolveProperty(it, prefixMap, DEFAULT_VOCAB.ITEM) } + val properties = parseProperties(propAttr).map { resolveProperty(it, prefixMap, DEFAULT_VOCAB.ITEM) } return Item( href = href, id = element.id, @@ -72,7 +72,7 @@ internal data class Item( internal data class Spine( val itemrefs: List, - val direction: ReadingProgression, + val direction: ReadingProgression?, val toc: String? = null ) { companion object { @@ -81,7 +81,7 @@ internal data class Spine( val pageProgressionDirection = when (element.getAttr("page-progression-direction")) { "rtl" -> ReadingProgression.RTL "ltr" -> ReadingProgression.LTR - else -> ReadingProgression.AUTO // null or "default" + else -> null // null or "default" } val ncx = if (epubVersion < 3.0) element.getAttr("toc") else null return Spine(itemrefs, pageProgressionDirection, ncx) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ReadiumCssLayout.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ReadiumCssLayout.kt deleted file mode 100644 index 1269827764..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ReadiumCssLayout.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.streamer.parser.epub - -import org.readium.r2.shared.publication.Metadata -import org.readium.r2.shared.publication.ReadingProgression - -internal enum class ReadiumCssLayout(val cssId: String) { - // Right to left - RTL("rtl"), - // Left to right - LTR("ltr"), - // Asian language, vertically laid out - CJK_VERTICAL("cjk-vertical"), - // Asian language, horizontally laid out - CJK_HORIZONTAL("cjk-horizontal"); - - val readiumCSSPath: String get() = when (this) { - LTR -> "" - RTL -> "rtl/" - CJK_VERTICAL -> "cjk-vertical/" - CJK_HORIZONTAL -> "cjk-horizontal/" - } - - companion object { - - operator fun invoke(metadata: Metadata): ReadiumCssLayout = - @Suppress("Deprecation") - invoke(languages = metadata.languages, readingProgression = metadata.effectiveReadingProgression) - - /** - * Determines the [ReadiumCssLayout] for the given BCP 47 language codes and - * [readingProgression]. - * Defaults to [LTR]. - */ - operator fun invoke(languages: List, readingProgression: ReadingProgression): ReadiumCssLayout { - val isCjk: Boolean = - if (languages.size == 1) { - val language = languages[0].split("-")[0] // Remove region - listOf("zh", "ja", "ko").contains(language) - } else { - false - } - - return when (readingProgression) { - ReadingProgression.RTL, ReadingProgression.BTT -> - if (isCjk) CJK_VERTICAL - else RTL - - ReadingProgression.LTR, ReadingProgression.TTB, ReadingProgression.AUTO -> - if (isCjk) CJK_HORIZONTAL - else LTR - } - } - } -} diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt index 2dc783a088..15d36b1fb0 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt @@ -39,13 +39,13 @@ class ReadingProgressionTest { @Test fun `No page progression direction is mapped to default`() { assertThat(parsePackageDocument("package/progression-none.opf").metadata.readingProgression) - .isEqualTo(ReadingProgression.AUTO) + .isEqualTo(null) } @Test fun `Default page progression direction is rightly parsed`() { assertThat(parsePackageDocument("package/progression-default.opf").metadata.readingProgression) - .isEqualTo(ReadingProgression.AUTO) + .isEqualTo(null) } @Test diff --git a/test-app/src/main/AndroidManifest.xml b/test-app/src/main/AndroidManifest.xml index 8962ce332f..4dcf647a17 100644 --- a/test-app/src/main/AndroidManifest.xml +++ b/test-app/src/main/AndroidManifest.xml @@ -1,13 +1,9 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> diff --git a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt b/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt index b6f362bb66..1599e23ed6 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt @@ -22,11 +22,11 @@ sealed class PublicationError(@StringRes userMessageId: Int) : UserException(use class SchemeNotSupported(val error: Error) : PublicationError(R.string.publication_error_scheme_not_supported) - class UnsupportedPublication(val error: Error? = null) : PublicationError(R.string.r2_shared_publication_opening_exception_unsupported_asset) + class UnsupportedPublication(val error: Error? = null) : PublicationError(R.string.publication_error_unsupported_asset) class InvalidPublication(val error: Error) : PublicationError(R.string.publication_error_invalid_publication) - class IncorrectCredentials(val error: Error) : PublicationError(R.string.r2_shared_publication_opening_exception_incorrect_credentials) + class IncorrectCredentials(val error: Error) : PublicationError(R.string.publication_error_incorrect_credentials) class Forbidden(val error: Error? = null) : PublicationError(R.string.publication_error_forbidden) diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt index a4b88809ca..86aff3c389 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt @@ -13,7 +13,7 @@ import android.view.View import android.view.ViewGroup import androidx.core.os.bundleOf import androidx.fragment.app.Fragment -import androidx.fragment.app.viewModels +import androidx.fragment.app.activityViewModels import androidx.navigation.Navigation import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar @@ -29,7 +29,7 @@ import org.readium.r2.testapp.utils.viewLifecycle class CatalogFragment : Fragment() { - private val catalogViewModel: CatalogViewModel by viewModels() + private val catalogViewModel: CatalogViewModel by activityViewModels() private lateinit var publicationAdapter: PublicationAdapter private lateinit var groupAdapter: GroupAdapter private lateinit var navigationAdapter: NavigationAdapter @@ -52,9 +52,9 @@ class CatalogFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - publicationAdapter = PublicationAdapter() + publicationAdapter = PublicationAdapter(catalogViewModel::publication::set) navigationAdapter = NavigationAdapter(catalog.type) - groupAdapter = GroupAdapter(catalog.type) + groupAdapter = GroupAdapter(catalog.type, catalogViewModel::publication::set) setHasOptionsMenu(true) binding.catalogNavigationList.apply { diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt index db10a1a4a4..997f9584cb 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt @@ -38,6 +38,7 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) val detailChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) val eventChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) val parseData = MutableLiveData() + lateinit var publication: Publication fun parseCatalog(catalog: Catalog) = viewModelScope.launch { var parseRequest: Try? = null diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt index 4e0f3fc378..c26c92594a 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt @@ -16,11 +16,15 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import org.readium.r2.shared.opds.Group +import org.readium.r2.shared.publication.Publication import org.readium.r2.testapp.R import org.readium.r2.testapp.databinding.ItemGroupViewBinding import org.readium.r2.testapp.domain.model.Catalog -class GroupAdapter(val type: Int) : +class GroupAdapter( + val type: Int, + private val setModelPublication: (Publication) -> Unit +) : ListAdapter(GroupDiff()) { override fun onCreateViewHolder( @@ -62,7 +66,7 @@ class GroupAdapter(val type: Int) : layoutManager = LinearLayoutManager(binding.root.context) (layoutManager as LinearLayoutManager).orientation = LinearLayoutManager.HORIZONTAL - adapter = PublicationAdapter().apply { + adapter = PublicationAdapter(setModelPublication).apply { submitList(group.publications) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt index 929b32f097..f4ae4e6bb0 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt @@ -6,7 +6,6 @@ package org.readium.r2.testapp.catalogs -import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import androidx.navigation.Navigation @@ -14,13 +13,14 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.squareup.picasso.Picasso -import org.readium.r2.shared.extensions.putPublication import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.opds.images import org.readium.r2.testapp.R import org.readium.r2.testapp.databinding.ItemRecycleCatalogBinding -class PublicationAdapter : +class PublicationAdapter( + private val setModelPublication: (Publication) -> Unit +) : ListAdapter(PublicationListDiff()) { override fun onCreateViewHolder( @@ -56,11 +56,9 @@ class PublicationAdapter : } binding.root.setOnClickListener { - val bundle = Bundle().apply { - putPublication(publication) - } + setModelPublication(publication) Navigation.findNavController(it) - .navigate(R.id.action_navigation_catalog_to_navigation_catalog_detail, bundle) + .navigate(R.id.action_navigation_catalog_to_navigation_catalog_detail) } } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt index 9365c223e4..9aba970547 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt @@ -11,10 +11,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import androidx.fragment.app.viewModels +import androidx.fragment.app.activityViewModels import com.google.android.material.snackbar.Snackbar import com.squareup.picasso.Picasso -import org.readium.r2.shared.extensions.getPublicationOrNull import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.opds.images import org.readium.r2.testapp.MainActivity @@ -24,7 +23,7 @@ import org.readium.r2.testapp.databinding.FragmentPublicationDetailBinding class PublicationDetailFragment : Fragment() { private var publication: Publication? = null - private val catalogViewModel: CatalogViewModel by viewModels() + private val catalogViewModel: CatalogViewModel by activityViewModels() private var _binding: FragmentPublicationDetailBinding? = null private val binding get() = _binding!! @@ -38,7 +37,7 @@ class PublicationDetailFragment : Fragment() { inflater, container, false ) catalogViewModel.detailChannel.receive(this) { handleEvent(it) } - publication = arguments?.getPublicationOrNull() + publication = catalogViewModel.publication return binding.root } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt index 545dc4c87a..4d25ff36c6 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt @@ -54,8 +54,8 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene childFragmentManager.fragmentFactory = readerData.navigatorFactory.createFragmentFactory( initialLocator = readerData.initialLocation, - listener = this, initialPreferences = readerData.preferencesManager.preferences.value, + listener = this, configuration = EpubNavigatorFragment.Configuration { // To customize the text selection menu. selectionActionModeCallback = customSelectionActionModeCallback @@ -113,14 +113,13 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene savedInstanceState: Bundle? ): View { val view = super.onCreateView(inflater, container, savedInstanceState) - val navigatorFragmentTag = getString(R.string.epub_navigator_tag) if (savedInstanceState == null) { childFragmentManager.commitNow { - add(R.id.fragment_reader_container, EpubNavigatorFragment::class.java, Bundle(), navigatorFragmentTag) + add(R.id.fragment_reader_container, EpubNavigatorFragment::class.java, Bundle(), NAVIGATOR_FRAGMENT_TAG) } } - navigator = childFragmentManager.findFragmentByTag(navigatorFragmentTag) as EpubNavigatorFragment + navigator = childFragmentManager.findFragmentByTag(NAVIGATOR_FRAGMENT_TAG) as EpubNavigatorFragment return view } @@ -246,6 +245,7 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene companion object { private const val SEARCH_FRAGMENT_TAG = "search" + private const val NAVIGATOR_FRAGMENT_TAG = "navigator" private const val IS_SEARCH_VIEW_ICONIFIED = "isSearchViewIconified" } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt index 7f61b3c1f3..4e3295baec 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt @@ -147,8 +147,8 @@ class ReaderRepository( ) ?: return Try.failure(OpeningError.PublicationError(PublicationError.UnsupportedPublication())) val navigator = navigatorFactory.createNavigator( - initialPreferences, - initialLocator + initialLocator, + initialPreferences ) ?: return Try.failure(OpeningError.PublicationError(PublicationError.UnsupportedPublication())) mediaServiceFacade.openSession(bookId, navigator) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt index 34d3db97c7..52e246fac0 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt @@ -173,8 +173,8 @@ class TtsViewModel private constructor( val ttsNavigator = ttsNavigatorFactory.createNavigator( this, - preferencesManager.preferences.value, - start + initialLocator = start, + initialPreferences = preferencesManager.preferences.value ) ?: run { val exception = UserException(R.string.tts_error_initialization) _events.send(Event.OnError(exception)) diff --git a/test-app/src/main/res/drawable/rbtn_selector.xml b/test-app/src/main/res/drawable/rbtn_selector.xml index f6f2850aa8..031741d0a4 100644 --- a/test-app/src/main/res/drawable/rbtn_selector.xml +++ b/test-app/src/main/res/drawable/rbtn_selector.xml @@ -1,25 +1,22 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - - + + - + \ No newline at end of file diff --git a/test-app/src/main/res/drawable/rbtn_textcolor_selector.xml b/test-app/src/main/res/drawable/rbtn_textcolor_selector.xml index c0c7414c16..372aa08b22 100644 --- a/test-app/src/main/res/drawable/rbtn_textcolor_selector.xml +++ b/test-app/src/main/res/drawable/rbtn_textcolor_selector.xml @@ -1,16 +1,13 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - + \ No newline at end of file diff --git a/test-app/src/main/res/layout/activity_epub.xml b/test-app/src/main/res/layout/activity_epub.xml deleted file mode 100644 index 7d5f6b89b9..0000000000 --- a/test-app/src/main/res/layout/activity_epub.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - diff --git a/test-app/src/main/res/layout/filter_row.xml b/test-app/src/main/res/layout/filter_row.xml index 8578df7254..b45d79e324 100644 --- a/test-app/src/main/res/layout/filter_row.xml +++ b/test-app/src/main/res/layout/filter_row.xml @@ -1,13 +1,9 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + + + + + + + android:background="@color/readium_colorAccent"> + + + android:background="@color/readium_colorAccent"> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> - + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +-->

diff --git a/test-app/src/main/res/menu/menu_filter.xml b/test-app/src/main/res/menu/menu_filter.xml index fa01b16d66..c9a57d8bfd 100644 --- a/test-app/src/main/res/menu/menu_filter.xml +++ b/test-app/src/main/res/menu/menu_filter.xml @@ -1,13 +1,9 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> diff --git a/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 81de1c3623..729f828c86 100644 --- a/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,13 +1,9 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> diff --git a/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 81de1c3623..729f828c86 100644 --- a/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/test-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,13 +1,9 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> diff --git a/test-app/src/main/res/values/colors.xml b/test-app/src/main/res/values/colors.xml index 04355ce52f..ba8d4c4cdd 100644 --- a/test-app/src/main/res/values/colors.xml +++ b/test-app/src/main/res/values/colors.xml @@ -1,13 +1,9 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> #ffffff diff --git a/test-app/src/main/res/values/refs.xml b/test-app/src/main/res/values/refs.xml index 8c9763314a..9651c081dc 100644 --- a/test-app/src/main/res/values/refs.xml +++ b/test-app/src/main/res/values/refs.xml @@ -1,5 +1,5 @@ - @layout/activity_reader - @layout/activity_reader + @layout/activity_reader + @layout/activity_reader \ No newline at end of file diff --git a/test-app/src/main/res/values/strings.xml b/test-app/src/main/res/values/strings.xml index 47daef7364..f2bb4a94a9 100644 --- a/test-app/src/main/res/values/strings.xml +++ b/test-app/src/main/res/values/strings.xml @@ -1,12 +1,8 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> R2 Reader @@ -183,6 +179,18 @@ Publication looks corrupted. An unexpected error occurred. + This publication cannot be opened because it is protected with %1$s + This publication cannot be opened because it is protected with an unknown DRM + + Invalid request which can\'t be processed + Resource not found + You are not allowed to access the resource + The resource is currently unavailable, please try again later + The Internet connection appears to be offline + The resource is too large to be read on this device + An expected error occurred. + A service error occurred + Failed parsing Catalog Next chapter Next sentence diff --git a/test-app/src/main/res/values/styles.xml b/test-app/src/main/res/values/styles.xml index 82d94d96a1..4a81b2a23f 100644 --- a/test-app/src/main/res/values/styles.xml +++ b/test-app/src/main/res/values/styles.xml @@ -1,12 +1,8 @@ + Copyright 2023 Readium Foundation. All rights reserved. + Use of this source code is governed by the BSD-style license + available in the top-level LICENSE file of the project. +--> @@ -15,6 +11,14 @@ + + + + - - - - - - - - \ No newline at end of file From 0ce0163000e14f76934bddb57ad8312bc0d75f7e Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Wed, 26 Jul 2023 11:36:33 +0200 Subject: [PATCH 17/65] Increase deprecation level on some methods (#369) --- .../java/org/readium/r2/shared/publication/Contributor.kt | 2 +- .../main/java/org/readium/r2/shared/publication/Link.kt | 4 ++-- .../org/readium/r2/shared/publication/LocalizedString.kt | 4 ++-- .../java/org/readium/r2/shared/publication/Metadata.kt | 8 ++++---- .../r2/shared/publication/PublicationCollection.kt | 4 ++-- .../r2/shared/publication/services/PositionsService.kt | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt index 39416255ec..2a4a573b98 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt @@ -131,7 +131,7 @@ public data class Contributor( } } - @Deprecated("Use [localizedName] instead.", ReplaceWith("localizedName")) + @Deprecated("Use [localizedName] instead.", ReplaceWith("localizedName"), level = DeprecationLevel.ERROR) val multilanguageName: LocalizedString get() = localizedName } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt index 5d73e851e3..7a17563351 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt @@ -183,11 +183,11 @@ public data class Link( } } - @Deprecated("Use [type] instead", ReplaceWith("type")) + @Deprecated("Use [type] instead", ReplaceWith("type"), level = DeprecationLevel.ERROR) val typeLink: String? get() = type - @Deprecated("Use [rels] instead.", ReplaceWith("rels")) + @Deprecated("Use [rels] instead.", ReplaceWith("rels"), level = DeprecationLevel.ERROR) val rel: List get() = rels.toList() } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt index e67de039c7..f44c5df215 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt @@ -160,11 +160,11 @@ public data class LocalizedString(val translations: Map = } } - @Deprecated("Use [string] instead.", ReplaceWith("string")) + @Deprecated("Use [string] instead.", ReplaceWith("string"), level = DeprecationLevel.ERROR) val singleString: String? get() = string.ifEmpty { null } - @Deprecated("Use [get] instead.", ReplaceWith("()")) + @Deprecated("Use [get] instead.", ReplaceWith("()"), level = DeprecationLevel.ERROR) val multiString: Map get() = translations.mapValues { (_, translation) -> translation.string } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt index 462e0694ae..731f2bcbdc 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt @@ -354,17 +354,17 @@ public data class Metadata( val publicationDate: String? get() = published?.toIso8601String() - @Deprecated("Use [presentation] instead", ReplaceWith("presentation", "org.readium.r2.shared.publication.presentation.presentation")) + @Deprecated("Use [presentation] instead", ReplaceWith("presentation", "org.readium.r2.shared.publication.presentation.presentation"), level = DeprecationLevel.ERROR) val rendition: Presentation get() = presentation - @Deprecated("Access from [otherMetadata] instead", ReplaceWith("otherMetadata[\"source\"] as? String")) + @Deprecated("Access from [otherMetadata] instead", ReplaceWith("otherMetadata[\"source\"] as? String"), level = DeprecationLevel.ERROR) val source: String? get() = otherMetadata["source"] as? String - @Deprecated("Not used anymore", ReplaceWith("null")) + @Deprecated("Not used anymore", ReplaceWith("null"), level = DeprecationLevel.ERROR) val rights: String? get() = null - @Deprecated("Renamed into [toJSON]", ReplaceWith("toJSON()")) + @Deprecated("Renamed into [toJSON]", ReplaceWith("toJSON()"), level = DeprecationLevel.ERROR) public fun writeJSON(): JSONObject = toJSON() } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt index 0831f93305..aa64532608 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt @@ -149,10 +149,10 @@ internal fun Map>.appendToJSONObject(jsonObj } } -@Deprecated("Use [subcollections[role].firstOrNull()] instead", ReplaceWith("subcollections[role].firstOrNull()")) +@Deprecated("Use [subcollections[role].firstOrNull()] instead", ReplaceWith("subcollections[role].firstOrNull()"), level = DeprecationLevel.ERROR) public fun Map>.firstWithRole(role: String): PublicationCollection? = get(role)?.firstOrNull() -@Deprecated("Use [subcollections[role]] instead", ReplaceWith("subcollections[role]")) +@Deprecated("Use [subcollections[role]] instead", ReplaceWith("subcollections[role]"), level = DeprecationLevel.ERROR) public fun Map>.findAllWithRole(role: String): List = get(role) ?: emptyList() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt index 8db28c716f..d21ffdc5ad 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt @@ -74,7 +74,7 @@ public suspend fun PublicationServicesHolder.positions(): List { /** * List of all the positions in each resource, indexed by their href. */ -@Deprecated("Use [positionsByReadingOrder] instead", ReplaceWith("positionsByReadingOrder")) +@Deprecated("Use [positionsByReadingOrder] instead", ReplaceWith("positionsByReadingOrder"), level = DeprecationLevel.ERROR) public val Publication.positionsByResource: Map> get() = runBlocking { positions().groupBy { it.href } } From ac9ff2bbd1a288f23c3bc0e19da38a3eadb8e409 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Wed, 26 Jul 2023 14:00:07 +0200 Subject: [PATCH 18/65] Simplify media type handling in LCP acquisitions (#370) --- .../main/java/org/readium/r2/lcp/LcpService.kt | 5 ++++- .../readium/r2/lcp/service/LicensesService.kt | 4 +++- .../r2/shared/publication/html/DomRange.kt | 2 +- .../r2/shared/publication/opds/Properties.kt | 2 +- .../r2/testapp/bookshelf/BookRepository.kt | 17 +++++++---------- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt index 9ed8491896..c5e758a669 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.readium.r2.lcp.auth.LcpDialogAuthentication +import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.lcp.persistence.LcpDatabase import org.readium.r2.lcp.service.CRLService import org.readium.r2.lcp.service.DeviceRepository @@ -137,7 +138,9 @@ public interface LcpService { */ public data class AcquiredPublication( val localFile: File, - val suggestedFilename: String + val suggestedFilename: String, + val mediaType: MediaType, + val licenseDocument: LicenseDocument ) { @Deprecated("Use `localFile` instead", replaceWith = ReplaceWith("localFile"), level = DeprecationLevel.ERROR) val localURL: String get() = localFile.path diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index d73b5bbfea..03e88852ad 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -237,7 +237,9 @@ internal class LicensesService( return LcpService.AcquiredPublication( localFile = destination, - suggestedFilename = "${license.id}.${mediaType.fileExtension}" + suggestedFilename = "${license.id}.${mediaType.fileExtension}", + mediaType = mediaType, + licenseDocument = license ) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt index 4ef0ef951d..80290f2fee 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt @@ -95,7 +95,7 @@ public data class DomRange( } } - @Deprecated("Renamed into [charOffset]", ReplaceWith("charOffset")) + @Deprecated("Renamed into [charOffset]", ReplaceWith("charOffset"), level = DeprecationLevel.ERROR) val offset: Long? get() = charOffset?.toLong() } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt index 55def66d7e..fea241ddab 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt @@ -46,7 +46,7 @@ public val Properties.indirectAcquisitions: List } ?: emptyList() -@Deprecated("Use [indirectAcquisitions] instead.", ReplaceWith("indirectAcquisitions")) +@Deprecated("Use [indirectAcquisitions] instead.", ReplaceWith("indirectAcquisitions"), level = DeprecationLevel.ERROR) public val Properties.indirectAcquisition: List get() = indirectAcquisitions diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt index d4abc22ca1..a57260ebed 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt @@ -244,7 +244,13 @@ class BookRepository( .fold( { val file = it.localFile - val asset = assetRetriever.retrieve(file, fileExtension = File(it.suggestedFilename).extension) + val asset = assetRetriever.retrieve( + file.toUrl(), + assetType = AssetType.Archive, + mediaType = it.mediaType + ).getOrElse { error -> + return Try.failure(ImportError.PublicationError(error)) + } file to asset }, { @@ -254,15 +260,6 @@ class BookRepository( ) } - if (publicationTempAsset == null) { - val exception = Publication.OpeningException.UnsupportedAsset("Unsupported media type") - return Try.failure( - ImportError.PublicationError( - PublicationError.UnsupportedPublication(exception) - ) - ) - } - val fileName = "${UUID.randomUUID()}.${publicationTempAsset.mediaType.fileExtension}" val libraryFile = File(storageDir, fileName) val libraryUrl = libraryFile.toUrl() From 0cb5961e40a8c3080a926aed76b910764e709b46 Mon Sep 17 00:00:00 2001 From: Steven Zeck <8315038+stevenzeck@users.noreply.github.com> Date: Wed, 26 Jul 2023 09:34:36 -0500 Subject: [PATCH 19/65] Updating dependencies, SDKs, Kotlin and Gradle (#368) --- .github/workflows/checks.yml | 18 +- .github/workflows/docs.yml | 8 +- .github/workflows/publish.yml | 8 +- .idea/kotlinc.xml | 2 +- README.md | 3 +- build.gradle.kts | 1 + docs/guides/media-navigator.md | 2 + docs/migration-guide.md | 7 + gradle.properties | 2 - gradle/libs.versions.toml | 64 ++--- gradle/wrapper/gradle-wrapper.properties | 2 +- readium/adapters/pdfium/build.gradle.kts | 10 +- .../pdfium/pdfium-document/build.gradle.kts | 10 +- .../pdfium/pdfium-navigator/build.gradle.kts | 10 +- readium/adapters/pspdfkit/build.gradle.kts | 10 +- .../pspdfkit-document/build.gradle.kts | 10 +- .../pspdfkit-navigator/build.gradle.kts | 10 +- .../navigator/PsPdfKitDocumentFragment.kt | 6 +- readium/lcp/build.gradle.kts | 18 +- .../readium/r2/lcp/persistence/LcpDatabase.kt | 16 +- .../org/readium/r2/lcp/service/LcpClient.kt | 2 +- readium/navigator-media2/build.gradle.kts | 10 +- readium/navigator/build.gradle.kts | 13 +- .../r2/navigator/epub/fxl/R2FXLLayout.kt | 5 +- .../media3/tts/session/TtsSessionAdapter.kt | 29 ++- readium/opds/build.gradle.kts | 10 +- readium/shared/build.gradle.kts | 11 +- readium/streamer/build.gradle.kts | 8 +- settings.gradle.kts | 13 +- test-app/build.gradle.kts | 15 +- test-app/src/main/AndroidManifest.xml | 2 + .../r2/testapp/reader/EpubReaderFragment.kt | 13 +- .../r2/testapp/reader/ReaderActivity.kt | 6 +- .../r2/testapp/reader/VisualReaderFragment.kt | 243 ++++++++++-------- .../utils/LifecycleMedia2SessionService.kt | 5 - 35 files changed, 328 insertions(+), 274 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 2b10348505..7ad1224ebd 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -13,11 +13,11 @@ jobs: if: ${{ !github.event.pull_request.draft }} steps: - name: Checkout - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 + uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'adopt' - name: Build run: ./gradlew clean build -x test -x ktlintMainSourceSetCheck @@ -30,11 +30,11 @@ jobs: if: ${{ !github.event.pull_request.draft }} steps: - name: Checkout - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 + uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'adopt' - name: Lint run: ./gradlew ktlintCheck @@ -50,7 +50,7 @@ jobs: scripts: ${{ 'src/main/assets/_scripts' }} steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install dependencies run: yarn --cwd "$scripts" install --frozen-lockfile - name: Lint diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1f26b6f284..a672e828d9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,13 +13,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Fetch tags run: git fetch --prune --unshallow - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.6 @@ -28,9 +28,9 @@ jobs: python -m pip install --upgrade pip pip install mkdocs mkdocs-material mike - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: - java-version: 11 + java-version: 17 distribution: 'adopt' - name: Get current Readium version diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 32bd05c089..1b8a9556a8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,14 +12,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: develop - - name: Set up JDK 11 - uses: actions/setup-java@v2 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: distribution: adopt - java-version: 11 + java-version: 17 # Builds the release artifacts of the library - name: Release build diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index e1eea1d6b9..fdf8d994a6 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/README.md b/README.md index 6a8195a0a3..fe8aa4fe8c 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ A [Test App](test-app) demonstrates how to integrate the Readium Kotlin toolkit | Readium | Android min SDK | Android compile SDK | Kotlin compiler | Gradle | |---------|-----------------|---------------------|-----------------|--------| -| latest | 21 | 33 | 1.7.10 | 6.9.3 | +| 3.0.0 | 21 | 34 | 1.9.0 | 8.0.0 | +| 2.3.0 | 21 | 33 | 1.7.10 | 6.9.3 | ## Setting Up Readium diff --git a/build.gradle.kts b/build.gradle.kts index f9774a5d8a..ef236c3079 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,7 @@ plugins { id("io.github.gradle-nexus.publish-plugin") apply true id("org.jetbrains.dokka") apply true id("org.jetbrains.kotlin.android") apply false + id("com.google.devtools.ksp") apply false id("org.jlleitschuh.gradle.ktlint") apply true } diff --git a/docs/guides/media-navigator.md b/docs/guides/media-navigator.md index e259b5dddd..254dd6f688 100644 --- a/docs/guides/media-navigator.md +++ b/docs/guides/media-navigator.md @@ -123,6 +123,8 @@ Don't forget to declare this new service in your `AndroidManifest.xml`. + + ... diff --git a/docs/migration-guide.md b/docs/migration-guide.md index d95b4a2a58..a6fb823fd3 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -138,6 +138,13 @@ Both the Fuel and Kovenant libraries have been completely removed from the toolk * `Response.sniffMediaType(...)` has been replaced with `org.readium.r2.shared.util.mediatype.sniffMediaType` +### Targeting Android SDK 34 + +The modules now target Android SDK 34. If your app also targets that, you will need the `FOREGROUND_SERVICE_MEDIA_PLAYBACK` permission in you AndroidManifest.xml file in order to use TTS and audiobook playback. + +### Gradle 8.0 + +The minimum required Gradle version is now 8.0. ## 2.3.0 diff --git a/gradle.properties b/gradle.properties index c064741c76..cac7c68c14 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,5 +19,3 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official - -android.disableAutomaticComponentCreation=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8118c15a0b..b83ae79e70 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,58 +1,58 @@ [versions] -androidx-activity = "1.6.1" -androidx-appcompat = "1.5.1" -androidx-browser = "1.4.0" +androidx-activity = "1.7.2" +androidx-appcompat = "1.6.1" +androidx-browser = "1.5.0" androidx-cardview = "1.0.0" -androidx-compose-compiler = "1.3.2" -androidx-compose-animation = "1.3.0-beta03" -androidx-compose-foundation = "1.3.0-beta03" -androidx-compose-material = "1.3.0-beta03" -androidx-compose-material3 = "1.0.0-beta03" -androidx-compose-runtime = "1.3.0-beta03" +androidx-compose-compiler = "1.5.0" +androidx-compose-animation = "1.4.3" +androidx-compose-foundation = "1.4.3" +androidx-compose-material = "1.4.3" +androidx-compose-material3 = "1.1.1" +androidx-compose-runtime = "1.4.3" androidx-compose-theme-adapter = "1.1.19" -androidx-compose-ui = "1.3.0-beta03" +androidx-compose-ui = "1.4.3" androidx-constraintlayout = "2.1.4" -androidx-core = "1.9.0" +androidx-core = "1.10.1" androidx-datastore = "1.0.0" -androidx-expresso-core = "3.4.0" -androidx-ext-junit = "1.1.3" -androidx-fragment-ktx = "1.5.4" +androidx-expresso-core = "3.5.1" +androidx-ext-junit = "1.1.5" +androidx-fragment-ktx = "1.6.0" androidx-legacy = "1.0.0" -androidx-lifecycle = "2.5.1" +androidx-lifecycle = "2.6.1" androidx-lifecycle-extensions = "2.2.0" androidx-media = "1.6.0" androidx-media2 = "1.2.1" -androidx-media3 = "1.0.0" +androidx-media3 = "1.1.0" androidx-navigation = "2.5.2" androidx-paging = "3.1.1" -androidx-recyclerview = "1.2.1" -androidx-room = "2.4.3" +androidx-recyclerview = "1.3.0" +androidx-room = "2.5.2" androidx-viewpager2 = "1.0.0" -androidx-webkit = "1.5.0" +androidx-webkit = "1.7.0" -assertj = "3.23.1" +assertj = "3.24.2" -dokka = "1.7.20" +dokka = "1.8.20" -google-exoplayer = "2.18.1" -google-material = "1.7.0" +google-exoplayer = "2.19.0" +google-material = "1.9.0" -joda-time = "2.12.1" -jsoup = "1.15.3" +joda-time = "2.12.5" +jsoup = "1.16.1" junit = "4.13.2" -kotlin = "1.7.20" -kotlinx-coroutines = "1.6.4" -kotlinx-coroutines-test = "1.6.4" -kotlinx-serialization-json = "1.4.1" +kotlin = "1.9.0" +kotlinx-coroutines = "1.7.2" +kotlinx-coroutines-test = "1.7.2" +kotlinx-serialization-json = "1.5.1" pdfium = "1.8.2" pdf-viewer = "2.8.2" -picasso = "2.71828" +picasso = "2.8" pspdfkit = "8.4.1" -robolectric = "4.9" +robolectric = "4.10.3" timber = "5.0.1" @@ -119,7 +119,7 @@ junit = { group = "junit", name = "junit", version.ref = "junit" } kotlin-gradle = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } kotlin-junit = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit", version.ref = "kotlin" } kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" } -kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" } +kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa991fceae..59bc51a20d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/readium/adapters/pdfium/build.gradle.kts b/readium/adapters/pdfium/build.gradle.kts index b7a6fa47e9..6e7c498957 100644 --- a/readium/adapters/pdfium/build.gradle.kts +++ b/readium/adapters/pdfium/build.gradle.kts @@ -13,19 +13,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/adapters/pdfium/pdfium-document/build.gradle.kts b/readium/adapters/pdfium/pdfium-document/build.gradle.kts index 213d15c9e1..ff8352bb68 100644 --- a/readium/adapters/pdfium/pdfium-document/build.gradle.kts +++ b/readium/adapters/pdfium/pdfium-document/build.gradle.kts @@ -13,19 +13,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/adapters/pdfium/pdfium-navigator/build.gradle.kts b/readium/adapters/pdfium/pdfium-navigator/build.gradle.kts index f24ad57de2..2a99bc1cb1 100644 --- a/readium/adapters/pdfium/pdfium-navigator/build.gradle.kts +++ b/readium/adapters/pdfium/pdfium-navigator/build.gradle.kts @@ -14,19 +14,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/adapters/pspdfkit/build.gradle.kts b/readium/adapters/pspdfkit/build.gradle.kts index 4dd86a85bb..bec4a57193 100644 --- a/readium/adapters/pspdfkit/build.gradle.kts +++ b/readium/adapters/pspdfkit/build.gradle.kts @@ -13,19 +13,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/adapters/pspdfkit/pspdfkit-document/build.gradle.kts b/readium/adapters/pspdfkit/pspdfkit-document/build.gradle.kts index da99ccbfdf..8ecbe21d7a 100644 --- a/readium/adapters/pspdfkit/pspdfkit-document/build.gradle.kts +++ b/readium/adapters/pspdfkit/pspdfkit-document/build.gradle.kts @@ -13,19 +13,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/build.gradle.kts b/readium/adapters/pspdfkit/pspdfkit-navigator/build.gradle.kts index e3cda2e849..b399ff46bd 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/build.gradle.kts +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/build.gradle.kts @@ -14,19 +14,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt index f302faec1d..05999ce0c9 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt @@ -192,9 +192,9 @@ internal class PsPdfKitDocumentFragment( } private val allowedTextSelectionItems = listOf( - R.id.pspdf__text_selection_toolbar_item_share, - R.id.pspdf__text_selection_toolbar_item_copy, - R.id.pspdf__text_selection_toolbar_item_speak + com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_share, + com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_copy, + com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_speak ) override fun onPrepareTextSelectionPopupToolbar(toolbar: PdfTextSelectionPopupToolbar) { diff --git a/readium/lcp/build.gradle.kts b/readium/lcp/build.gradle.kts index c5a52f1ea3..6dc38bd2ec 100644 --- a/readium/lcp/build.gradle.kts +++ b/readium/lcp/build.gradle.kts @@ -8,24 +8,24 @@ plugins { id("com.android.library") kotlin("android") kotlin("plugin.parcelize") - kotlin("kapt") + id("com.google.devtools.ksp") } android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() allWarningsAsErrors = true freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", @@ -38,6 +38,9 @@ android { proguardFiles(getDefaultProguardFile("proguard-android.txt")) } } + buildFeatures { + buildConfig = true + } namespace = "org.readium.r2.lcp" } @@ -68,8 +71,7 @@ dependencies { implementation(libs.androidx.browser) implementation(libs.bundles.room) - kapt(libs.androidx.room.compiler) - kapt("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0") + ksp(libs.androidx.room.compiler) // Tests testImplementation(libs.junit) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDatabase.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDatabase.kt index d877001a6c..c45a0f5fd5 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDatabase.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDatabase.kt @@ -35,8 +35,8 @@ internal abstract class LcpDatabase : RoomDatabase() { return tempInstance } val MIGRATION_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL( + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( """ CREATE TABLE passphrases ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -47,15 +47,15 @@ internal abstract class LcpDatabase : RoomDatabase() { ) """.trimIndent() ) - database.execSQL( + db.execSQL( """ INSERT INTO passphrases (license_id, provider, user_id, passphrase) SELECT id, origin, userId, passphrase FROM Transactions """.trimIndent() ) - database.execSQL("DROP TABLE Transactions") + db.execSQL("DROP TABLE Transactions") - database.execSQL( + db.execSQL( """ CREATE TABLE new_Licenses ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -66,14 +66,14 @@ internal abstract class LcpDatabase : RoomDatabase() { ) """.trimIndent() ) - database.execSQL( + db.execSQL( """ INSERT INTO new_Licenses (license_id, right_print, right_copy, registered) SELECT id, printsLeft, copiesLeft, registered FROM Licenses """.trimIndent() ) - database.execSQL("DROP TABLE Licenses") - database.execSQL("ALTER TABLE new_Licenses RENAME TO licenses") + db.execSQL("DROP TABLE Licenses") + db.execSQL("ALTER TABLE new_Licenses RENAME TO licenses") } } synchronized(this) { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt index f361d9a522..39d90c3944 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt @@ -31,7 +31,7 @@ internal object LcpClient { } private val instance: Any by lazy { - klass.newInstance() + klass.getDeclaredConstructor().newInstance() } private val klass: Class<*> by lazy { diff --git a/readium/navigator-media2/build.gradle.kts b/readium/navigator-media2/build.gradle.kts index 9d1368ac77..1bed109721 100644 --- a/readium/navigator-media2/build.gradle.kts +++ b/readium/navigator-media2/build.gradle.kts @@ -13,19 +13,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/navigator/build.gradle.kts b/readium/navigator/build.gradle.kts index d845d4ace5..3efe7385f0 100644 --- a/readium/navigator/build.gradle.kts +++ b/readium/navigator/build.gradle.kts @@ -14,19 +14,19 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" @@ -43,6 +43,7 @@ android { } buildFeatures { viewBinding = true + buildConfig = true } namespace = "org.readium.r2.navigator" } @@ -73,8 +74,6 @@ dependencies { implementation(libs.bundles.media3) implementation(libs.androidx.viewpager2) implementation(libs.androidx.webkit) - // Needed to avoid a crash with API 31, see https://stackoverflow.com/a/69152986/1474476 - implementation("androidx.work:work-runtime-ktx:2.7.1") implementation(libs.bundles.media2) // ExoPlayer is used by the Audio Navigator. diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt index bd9e125de5..3de827f990 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt @@ -299,8 +299,7 @@ internal class R2FXLLayout : FrameLayout { dispatchOnLongTap(e) } } - - override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { + override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { var consumed = false if (e2.pointerCount == 1 && !scaleDetector!!.isInProgress) { // only drag if we have one pointer and aren't already scaling @@ -319,7 +318,7 @@ internal class R2FXLLayout : FrameLayout { return consumed } - override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { + override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { val scale = scale val newScale = scale.coerceIn(minScale, maxScale) if (newScale.equalsDelta(scale)) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt index caddfa9d67..2100d905c5 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt @@ -206,6 +206,16 @@ internal class TtsSessionAdapter( override fun moveMediaItems(fromIndex: Int, toIndex: Int, newIndex: Int) { } + override fun replaceMediaItem(index: Int, mediaItem: MediaItem) { + } + + override fun replaceMediaItems( + fromIndex: Int, + toIndex: Int, + mediaItems: MutableList + ) { + } + override fun removeMediaItem(index: Int) { } @@ -438,9 +448,6 @@ internal class TtsSessionAdapter( onStop() } - @Deprecated("Deprecated in Java") - override fun stop(reset: Boolean) {} - override fun release() { streamVolumeManager.release() audioFocusManager.release() @@ -716,18 +723,34 @@ internal class TtsSessionAdapter( streamVolumeManager.setVolume(volume) } + override fun setDeviceVolume(volume: Int, flags: Int) { + streamVolumeManager.setVolume(volume) + } + override fun increaseDeviceVolume() { streamVolumeManager.increaseVolume() } + override fun increaseDeviceVolume(flags: Int) { + streamVolumeManager.increaseVolume() + } + override fun decreaseDeviceVolume() { streamVolumeManager.decreaseVolume() } + override fun decreaseDeviceVolume(flags: Int) { + streamVolumeManager.decreaseVolume() + } + override fun setDeviceMuted(muted: Boolean) { streamVolumeManager.setMuted(muted) } + override fun setDeviceMuted(muted: Boolean, flags: Int) { + streamVolumeManager.setMuted(muted) + } + private fun notifyListenersPlaybackChanged( previousPlaybackInfo: TtsPlayer.Playback, playbackInfo: TtsPlayer.Playback, diff --git a/readium/opds/build.gradle.kts b/readium/opds/build.gradle.kts index 6c1af44654..cdaf0d7949 100644 --- a/readium/opds/build.gradle.kts +++ b/readium/opds/build.gradle.kts @@ -13,18 +13,18 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", "-opt-in=org.readium.r2.shared.InternalReadiumApi" diff --git a/readium/shared/build.gradle.kts b/readium/shared/build.gradle.kts index 2c4225340c..8282274403 100644 --- a/readium/shared/build.gradle.kts +++ b/readium/shared/build.gradle.kts @@ -14,15 +14,15 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { allWarningsAsErrors = true @@ -40,6 +40,9 @@ android { proguardFiles(getDefaultProguardFile("proguard-android.txt")) } } + buildFeatures { + buildConfig = true + } namespace = "org.readium.r2.shared" } diff --git a/readium/streamer/build.gradle.kts b/readium/streamer/build.gradle.kts index 863a49d9ca..10f34d68fb 100644 --- a/readium/streamer/build.gradle.kts +++ b/readium/streamer/build.gradle.kts @@ -13,15 +13,15 @@ plugins { android { resourcePrefix = "readium_" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } testOptions { unitTests.isIncludeAndroidResources = true diff --git a/settings.gradle.kts b/settings.gradle.kts index c1b9f5d53a..9a18a9926d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -18,13 +18,16 @@ pluginManagement { // it to integrate Readium in submodules. // See https://github.com/readium/kotlin-toolkit/pull/97 plugins { - id("com.android.application") version ("7.3.1") - id("com.android.library") version ("7.3.1") + id("com.android.application") version ("8.1.0") + id("com.android.library") version ("8.1.0") id("io.github.gradle-nexus.publish-plugin") version ("1.1.0") - id("org.jetbrains.dokka") version ("1.7.20") - id("org.jetbrains.kotlin.android") version ("1.7.20") - id("org.jetbrains.kotlin.plugin.serialization") version ("1.7.10") + id("org.jetbrains.dokka") version ("1.8.20") + id("org.jetbrains.kotlin.android") version ("1.9.0") + id("org.jetbrains.kotlin.plugin.serialization") version ("1.9.0") id("org.jlleitschuh.gradle.ktlint") version ("11.0.0") + // Make sure to align with the Kotlin version. + // See https://github.com/google/ksp/releases + id("com.google.devtools.ksp") version ("1.9.0-1.0.12") } } dependencyResolutionManagement { diff --git a/test-app/build.gradle.kts b/test-app/build.gradle.kts index 018fa7d8cd..1c785ad281 100644 --- a/test-app/build.gradle.kts +++ b/test-app/build.gradle.kts @@ -7,15 +7,15 @@ plugins { id("com.android.application") kotlin("android") - kotlin("kapt") + id("com.google.devtools.ksp") kotlin("plugin.parcelize") } android { - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 21 - targetSdk = 33 + targetSdk = 34 applicationId = "org.readium.r2reader" @@ -28,11 +28,11 @@ android { ndk.abiFilters.add("x86_64") } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = JavaVersion.VERSION_17.toString() freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn" } composeOptions { @@ -41,6 +41,7 @@ android { buildFeatures { viewBinding = true compose = true + buildConfig = true } buildTypes { getByName("release") { @@ -106,7 +107,7 @@ dependencies { // Room database implementation(libs.bundles.room) - kapt(libs.androidx.room.compiler) + ksp(libs.androidx.room.compiler) // Tests testImplementation(libs.junit) diff --git a/test-app/src/main/AndroidManifest.xml b/test-app/src/main/AndroidManifest.xml index 4dcf647a17..5865b76456 100644 --- a/test-app/src/main/AndroidManifest.xml +++ b/test-app/src/main/AndroidManifest.xml @@ -11,6 +11,8 @@ + + diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt index 4d25ff36c6..9447f657ff 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt @@ -17,7 +17,10 @@ import androidx.appcompat.widget.SearchView import androidx.fragment.app.FragmentResultListener import androidx.fragment.app.commit import androidx.fragment.app.commitNow +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import kotlinx.coroutines.launch import org.readium.r2.navigator.DecorableNavigator import org.readium.r2.navigator.Decoration import org.readium.r2.navigator.ExperimentalDecorator @@ -131,9 +134,11 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene (model.settings as UserPreferencesViewModel) .bind(navigator, viewLifecycleOwner) - viewLifecycleOwner.lifecycleScope.launchWhenStarted { - // Display page number labels if the book contains a `page-list` navigation document. - (navigator as? DecorableNavigator)?.applyPageNumberDecorations() + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + // Display page number labels if the book contains a `page-list` navigation document. + (navigator as? DecorableNavigator)?.applyPageNumberDecorations() + } } } @@ -211,7 +216,7 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene } }) - menuSearchView.findViewById(R.id.search_close_btn).setOnClickListener { + menuSearchView.findViewById(androidx.appcompat.R.id.search_close_btn).setOnClickListener { menuSearchView.requestFocus() model.cancelSearch() menuSearchView.setQuery("", false) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt index 42354a09fe..5b5e0b326e 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt @@ -38,10 +38,8 @@ open class ReaderActivity : AppCompatActivity() { private val model: ReaderViewModel by viewModels() - override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory { - val arguments = ReaderActivityContract.parseIntent(this) - return ReaderViewModel.createFactory(application as Application, arguments) - } + override val defaultViewModelProviderFactory: ViewModelProvider.Factory + get() = ReaderViewModel.createFactory(application as Application, ReaderActivityContract.parseIntent(this)) private lateinit var binding: ActivityReaderBinding private lateinit var readerFragment: BaseReaderFragment diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt index 00681de783..17af993680 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt @@ -359,76 +359,80 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List } private fun showHighlightPopupWithStyle(style: Highlight.Style) = - viewLifecycleOwner.lifecycleScope.launchWhenResumed { - // Get the rect of the current selection to know where to position the highlight - // popup. - (navigator as? SelectableNavigator)?.currentSelection()?.rect?.let { selectionRect -> - showHighlightPopup(selectionRect, style) + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + // Get the rect of the current selection to know where to position the highlight + // popup. + (navigator as? SelectableNavigator)?.currentSelection()?.rect?.let { selectionRect -> + showHighlightPopup(selectionRect, style) + } } } private fun showHighlightPopup(rect: RectF, style: Highlight.Style, highlightId: Long? = null) = - viewLifecycleOwner.lifecycleScope.launchWhenResumed { - if (popupWindow?.isShowing == true) return@launchWhenResumed + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + if (popupWindow?.isShowing == true) return@repeatOnLifecycle - model.activeHighlightId.value = highlightId + model.activeHighlightId.value = highlightId - val isReverse = (rect.top > 60) - val popupView = layoutInflater.inflate( - if (isReverse) R.layout.view_action_mode_reverse else R.layout.view_action_mode, - null, - false - ) - popupView.measure( - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) - ) + val isReverse = (rect.top > 60) + val popupView = layoutInflater.inflate( + if (isReverse) R.layout.view_action_mode_reverse else R.layout.view_action_mode, + null, + false + ) + popupView.measure( + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) + ) - popupWindow = PopupWindow( - popupView, - LinearLayout.LayoutParams.WRAP_CONTENT, - LinearLayout.LayoutParams.WRAP_CONTENT - ).apply { - isFocusable = true - setOnDismissListener { - model.activeHighlightId.value = null + popupWindow = PopupWindow( + popupView, + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ).apply { + isFocusable = true + setOnDismissListener { + model.activeHighlightId.value = null + } } - } - val x = rect.left - val y = if (isReverse) rect.top else rect.bottom + rect.height() + val x = rect.left + val y = if (isReverse) rect.top else rect.bottom + rect.height() - popupWindow?.showAtLocation(popupView, Gravity.NO_GRAVITY, x.toInt(), y.toInt()) + popupWindow?.showAtLocation(popupView, Gravity.NO_GRAVITY, x.toInt(), y.toInt()) - val highlight = highlightId?.let { model.highlightById(it) } - popupView.run { - findViewById(R.id.notch).run { - setX(rect.left * 2) - } + val highlight = highlightId?.let { model.highlightById(it) } + popupView.run { + findViewById(R.id.notch).run { + setX(rect.left * 2) + } - fun selectTint(view: View) { - val tint = highlightTints[view.id] ?: return - selectHighlightTint(highlightId, style, tint) - } + fun selectTint(view: View) { + val tint = highlightTints[view.id] ?: return + selectHighlightTint(highlightId, style, tint) + } - findViewById(R.id.red).setOnClickListener(::selectTint) - findViewById(R.id.green).setOnClickListener(::selectTint) - findViewById(R.id.blue).setOnClickListener(::selectTint) - findViewById(R.id.yellow).setOnClickListener(::selectTint) - findViewById(R.id.purple).setOnClickListener(::selectTint) + findViewById(R.id.red).setOnClickListener(::selectTint) + findViewById(R.id.green).setOnClickListener(::selectTint) + findViewById(R.id.blue).setOnClickListener(::selectTint) + findViewById(R.id.yellow).setOnClickListener(::selectTint) + findViewById(R.id.purple).setOnClickListener(::selectTint) - findViewById(R.id.annotation).setOnClickListener { - popupWindow?.dismiss() - showAnnotationPopup(highlightId) - } - findViewById(R.id.del).run { - visibility = if (highlight != null) View.VISIBLE else View.GONE - setOnClickListener { - highlightId?.let { - model.deleteHighlight(highlightId) - } + findViewById(R.id.annotation).setOnClickListener { popupWindow?.dismiss() - mode?.finish() + showAnnotationPopup(highlightId) + } + findViewById(R.id.del).run { + visibility = if (highlight != null) View.VISIBLE else View.GONE + setOnClickListener { + highlightId?.let { + model.deleteHighlight(highlightId) + } + popupWindow?.dismiss() + mode?.finish() + } } } } @@ -439,78 +443,89 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List style: Highlight.Style, @ColorInt tint: Int ) = - viewLifecycleOwner.lifecycleScope.launchWhenResumed { - if (highlightId != null) { - model.updateHighlightStyle(highlightId, style, tint) - } else { - (navigator as? SelectableNavigator)?.let { navigator -> - navigator.currentSelection()?.let { selection -> - model.addHighlight(locator = selection.locator, style = style, tint = tint) + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + if (highlightId != null) { + model.updateHighlightStyle(highlightId, style, tint) + } else { + (navigator as? SelectableNavigator)?.let { navigator -> + navigator.currentSelection()?.let { selection -> + model.addHighlight( + locator = selection.locator, + style = style, + tint = tint + ) + } + navigator.clearSelection() } - navigator.clearSelection() } - } - popupWindow?.dismiss() - mode?.finish() + popupWindow?.dismiss() + mode?.finish() + } } private fun showAnnotationPopup(highlightId: Long? = null) = - viewLifecycleOwner.lifecycleScope.launchWhenResumed { - val activity = activity ?: return@launchWhenResumed - val view = layoutInflater.inflate(R.layout.popup_note, null, false) - val note = view.findViewById(R.id.note) - val alert = AlertDialog.Builder(activity) - .setView(view) - .create() - - fun dismiss() { - alert.dismiss() - mode?.finish() - (activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) - .hideSoftInputFromWindow( - note.applicationWindowToken, - InputMethodManager.HIDE_NOT_ALWAYS - ) - } + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + val activity = activity ?: return@repeatOnLifecycle + val view = layoutInflater.inflate(R.layout.popup_note, null, false) + val note = view.findViewById(R.id.note) + val alert = AlertDialog.Builder(activity) + .setView(view) + .create() + + fun dismiss() { + alert.dismiss() + mode?.finish() + (activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) + .hideSoftInputFromWindow( + note.applicationWindowToken, + InputMethodManager.HIDE_NOT_ALWAYS + ) + } - with(view) { - val highlight = highlightId?.let { model.highlightById(it) } - if (highlight != null) { - note.setText(highlight.annotation) - findViewById(R.id.sidemark).setBackgroundColor(highlight.tint) - findViewById(R.id.select_text).text = highlight.locator.text.highlight - - findViewById(R.id.positive).setOnClickListener { - val text = note.text.toString() - model.updateHighlightAnnotation(highlight.id, annotation = text) - dismiss() + with(view) { + val highlight = highlightId?.let { model.highlightById(it) } + if (highlight != null) { + note.setText(highlight.annotation) + findViewById(R.id.sidemark).setBackgroundColor(highlight.tint) + findViewById(R.id.select_text).text = + highlight.locator.text.highlight + + findViewById(R.id.positive).setOnClickListener { + val text = note.text.toString() + model.updateHighlightAnnotation(highlight.id, annotation = text) + dismiss() + } + } else { + val tint = highlightTints.values.random() + findViewById(R.id.sidemark).setBackgroundColor(tint) + val navigator = + navigator as? SelectableNavigator ?: return@repeatOnLifecycle + val selection = navigator.currentSelection() ?: return@repeatOnLifecycle + navigator.clearSelection() + findViewById(R.id.select_text).text = + selection.locator.text.highlight + + findViewById(R.id.positive).setOnClickListener { + model.addHighlight( + locator = selection.locator, + style = Highlight.Style.HIGHLIGHT, + tint = tint, + annotation = note.text.toString() + ) + dismiss() + } } - } else { - val tint = highlightTints.values.random() - findViewById(R.id.sidemark).setBackgroundColor(tint) - val navigator = navigator as? SelectableNavigator ?: return@launchWhenResumed - val selection = navigator.currentSelection() ?: return@launchWhenResumed - navigator.clearSelection() - findViewById(R.id.select_text).text = selection.locator.text.highlight - - findViewById(R.id.positive).setOnClickListener { - model.addHighlight( - locator = selection.locator, - style = Highlight.Style.HIGHLIGHT, - tint = tint, - annotation = note.text.toString() - ) + + findViewById(R.id.negative).setOnClickListener { dismiss() } } - findViewById(R.id.negative).setOnClickListener { - dismiss() - } + alert.show() } - - alert.show() } fun updateSystemUiVisibility() { diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt index 7a26c0c4dc..e485a18e5a 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt @@ -9,7 +9,6 @@ package org.readium.r2.testapp.utils import android.content.Intent import android.os.IBinder import androidx.annotation.CallSuper -import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ServiceLifecycleDispatcher import androidx.media2.session.MediaSessionService @@ -56,8 +55,4 @@ abstract class LifecycleMedia2SessionService : MediaSessionService(), LifecycleO lifecycleDispatcher.onServicePreSuperOnDestroy() super.onDestroy() } - - override fun getLifecycle(): Lifecycle { - return lifecycleDispatcher.lifecycle - } } From 318971cba7e0beb4e69f2fcafd610a125e18100c Mon Sep 17 00:00:00 2001 From: Steven Zeck <8315038+stevenzeck@users.noreply.github.com> Date: Fri, 28 Jul 2023 05:28:17 -0500 Subject: [PATCH 20/65] Various fixes and cleanup (#371) --- gradle/libs.versions.toml | 22 ++-- .../navigator/PsPdfKitDocumentFragment.kt | 6 +- .../navigator/epub/EpubNavigatorFragment.kt | 4 +- .../media3/tts/session/TtsSessionAdapter.kt | 13 +- .../r2/navigator/pager/R2CbzPageFragment.kt | 38 +++--- .../r2/navigator/pager/R2EpubPageFragment.kt | 90 ++++++++------ test-app/build.gradle.kts | 4 +- .../r2/testapp/catalogs/CatalogFragment.kt | 111 ++++++++++-------- .../r2/testapp/catalogs/CatalogViewModel.kt | 6 +- .../r2/testapp/reader/BaseReaderFragment.kt | 79 +++++++------ .../r2/testapp/reader/EpubReaderFragment.kt | 59 ++++++---- .../r2/testapp/reader/VisualReaderFragment.kt | 36 +++--- .../r2/testapp/shared/views/Preferences.kt | 6 +- .../r2/testapp/utils/compose/AppTheme.kt | 2 +- .../src/main/res/layout/fragment_search.xml | 1 - .../src/main/res/layout/section_header.xml | 2 + 16 files changed, 271 insertions(+), 208 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b83ae79e70..af4127b85d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,32 +1,33 @@ [versions] +accompanist = "0.30.1" + androidx-activity = "1.7.2" androidx-appcompat = "1.6.1" androidx-browser = "1.5.0" androidx-cardview = "1.0.0" -androidx-compose-compiler = "1.5.0" +androidx-compose-compiler = "1.5.1" androidx-compose-animation = "1.4.3" androidx-compose-foundation = "1.4.3" androidx-compose-material = "1.4.3" androidx-compose-material3 = "1.1.1" androidx-compose-runtime = "1.4.3" -androidx-compose-theme-adapter = "1.1.19" androidx-compose-ui = "1.4.3" androidx-constraintlayout = "2.1.4" androidx-core = "1.10.1" androidx-datastore = "1.0.0" androidx-expresso-core = "3.5.1" androidx-ext-junit = "1.1.5" -androidx-fragment-ktx = "1.6.0" +androidx-fragment-ktx = "1.6.1" androidx-legacy = "1.0.0" androidx-lifecycle = "2.6.1" androidx-lifecycle-extensions = "2.2.0" androidx-media = "1.6.0" androidx-media2 = "1.2.1" androidx-media3 = "1.1.0" -androidx-navigation = "2.5.2" -androidx-paging = "3.1.1" -androidx-recyclerview = "1.3.0" +androidx-navigation = "2.6.0" +androidx-paging = "3.2.0" +androidx-recyclerview = "1.3.1" androidx-room = "2.5.2" androidx-viewpager2 = "1.0.0" androidx-webkit = "1.7.0" @@ -43,8 +44,8 @@ jsoup = "1.16.1" junit = "4.13.2" kotlin = "1.9.0" -kotlinx-coroutines = "1.7.2" -kotlinx-coroutines-test = "1.7.2" +kotlinx-coroutines = "1.7.3" +kotlinx-coroutines-test = "1.7.3" kotlinx-serialization-json = "1.5.1" pdfium = "1.8.2" @@ -57,6 +58,8 @@ robolectric = "4.10.3" timber = "5.0.1" [libraries] +accompanist-themeadapter-material = { group = "com.google.accompanist", name = "accompanist-themeadapter-material", version.ref = "accompanist" } + androidx-activity-ktx = { group = "androidx.activity", name = "activity-ktx", version.ref = "androidx-activity" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" } androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "androidx-browser" } @@ -67,7 +70,6 @@ androidx-compose-foundation = { group = "androidx.compose.foundation", name = "f androidx-compose-material = { group = "androidx.compose.material", name = "material", version.ref = "androidx-compose-material" } androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "androidx-compose-material3" } androidx-compose-material-icons = { group = "androidx.compose.material", name = "material-icons-extended", version.ref = "androidx-compose-material" } -androidx-compose-theme-adapter = { group ="com.google.android.material", name = "compose-theme-adapter", version.ref = "androidx-compose-theme-adapter" } androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "androidx-compose-ui" } androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "androidx-compose-ui" } androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" } @@ -137,7 +139,7 @@ timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "tim [bundles] -compose = ["androidx-compose-activity", "androidx-compose-animation", "androidx-compose-foundation", "androidx-compose-material", "androidx-compose-material3", "androidx-compose-material-icons", "androidx-compose-theme-adapter", "androidx-compose-ui", "androidx-compose-ui-tooling"] +compose = ["androidx-compose-activity", "androidx-compose-animation", "androidx-compose-foundation", "androidx-compose-material", "androidx-compose-material3", "androidx-compose-material-icons", "androidx-compose-ui", "androidx-compose-ui-tooling"] coroutines = ["kotlinx-coroutines-core", "kotlinx-coroutines-android"] exoplayer = ["google-exoplayer-core", "google-exoplayer-ui", "google-exoplayer-mediasession", "google-exoplayer-workmanager", "google-exoplayer-extension-media2"] lifecycle = ["androidx-lifecycle-common", "androidx-lifecycle-extensions", "androidx-lifecycle-livedata", "androidx-lifecycle-runtime", "androidx-lifecycle-viewmodel", "androidx-lifecycle-vmsavedstate", "androidx-lifecycle-viewmodel-compose"] diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt index 05999ce0c9..2c59bfb82e 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt @@ -55,7 +55,7 @@ internal class PsPdfKitDocumentFragment( if (field == value) return field = value - reloadDocumentAtPage(pageIndex) + reloadDocumentAtPage() } private lateinit var pdfFragment: PdfFragment @@ -73,10 +73,10 @@ internal class PsPdfKitDocumentFragment( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - reloadDocumentAtPage(initialPageIndex) + reloadDocumentAtPage() } - private fun reloadDocumentAtPage(pageIndex: Int) { + private fun reloadDocumentAtPage() { pdfFragment = createPdfFragment() childFragmentManager.commitNow { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt index dd2c9bea76..904acabbee 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt @@ -28,7 +28,7 @@ import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import androidx.lifecycle.whenStarted +import androidx.lifecycle.withStarted import androidx.viewpager.widget.ViewPager import kotlin.math.ceil import kotlin.reflect.KClass @@ -479,7 +479,7 @@ public class EpubNavigatorFragment internal constructor( } viewLifecycleOwner.lifecycleScope.launch { - whenStarted { + withStarted { // Restore the last locator before a configuration change (e.g. screen rotation), or the // initial locator when given. val locator = savedInstanceState?.getParcelable("locator") ?: initialLocator diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt index 2100d905c5..55af1f64c2 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt @@ -146,11 +146,11 @@ internal class TtsSessionAdapter( COMMAND_GET_AUDIO_ATTRIBUTES, COMMAND_GET_DEVICE_VOLUME, - COMMAND_SET_DEVICE_VOLUME, + COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS, COMMAND_SET_SPEED_AND_PITCH, COMMAND_GET_CURRENT_MEDIA_ITEM, - COMMAND_GET_MEDIA_ITEMS_METADATA, + COMMAND_GET_METADATA, COMMAND_GET_TEXT ).build() @@ -825,11 +825,12 @@ internal class TtsSessionAdapter( } private fun createDeviceInfo(streamVolumeManager: StreamVolumeManager): DeviceInfo { - val newDeviceInfo = DeviceInfo( - DeviceInfo.PLAYBACK_TYPE_LOCAL, - streamVolumeManager.minVolume, - streamVolumeManager.maxVolume + val newDeviceInfo = DeviceInfo.Builder( + DeviceInfo.PLAYBACK_TYPE_LOCAL ) + .setMinVolume(streamVolumeManager.minVolume) + .setMaxVolume(streamVolumeManager.maxVolume) + .build() deviceInfo = newDeviceInfo return newDeviceInfo } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt index 0665502f03..079fdb782a 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt @@ -16,7 +16,9 @@ import android.view.View import android.view.ViewGroup import android.view.WindowManager import androidx.core.view.ViewCompat +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.github.chrisbanes.photoview.PhotoView import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope @@ -85,25 +87,27 @@ internal class R2CbzPageFragment( } private fun updatePadding() { - viewLifecycleOwner.lifecycleScope.launchWhenResumed { - val window = activity?.window ?: return@launchWhenResumed - var top = 0 - var bottom = 0 - - // Add additional padding to take into account the display cutout, if needed. - if ( - android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P && - window.attributes.layoutInDisplayCutoutMode != WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER - ) { - // Request the display cutout insets from the decor view because the ones given by - // setOnApplyWindowInsetsListener are not always correct for preloaded views. - window.decorView.rootWindowInsets?.displayCutout?.let { displayCutoutInsets -> - top += displayCutoutInsets.safeInsetTop - bottom += displayCutoutInsets.safeInsetBottom + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) { + val window = activity?.window ?: return@repeatOnLifecycle + var top = 0 + var bottom = 0 + + // Add additional padding to take into account the display cutout, if needed. + if ( + android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P && + window.attributes.layoutInDisplayCutoutMode != WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER + ) { + // Request the display cutout insets from the decor view because the ones given by + // setOnApplyWindowInsetsListener are not always correct for preloaded views. + window.decorView.rootWindowInsets?.displayCutout?.let { displayCutoutInsets -> + top += displayCutoutInsets.safeInsetTop + bottom += displayCutoutInsets.safeInsetBottom + } } - } - photoView.setPadding(0, top, 0, bottom) + photoView.setPadding(0, top, 0, bottom) + } } } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt index 898c03cb91..c1b7a272bf 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt @@ -22,8 +22,10 @@ import android.webkit.WebView import androidx.core.view.ViewCompat import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.webkit.WebViewClientCompat import kotlin.math.roundToInt import kotlinx.coroutines.flow.* @@ -124,7 +126,7 @@ internal class R2EpubPageFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { _binding = ReadiumNavigatorViewpagerFragmentEpubBinding.inflate(inflater, container, false) containerView = binding.root preferences = activity?.getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE)!! @@ -294,32 +296,36 @@ internal class R2EpubPageFragment : Fragment() { private fun updatePadding() { if (view == null) return - viewLifecycleOwner.lifecycleScope.launchWhenResumed { - val window = activity?.window ?: return@launchWhenResumed - var top = 0 - var bottom = 0 + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) { + val window = activity?.window ?: return@repeatOnLifecycle + var top = 0 + var bottom = 0 + + // Add additional padding to take into account the display cutout, if needed. + if ( + shouldApplyInsetsPadding && + android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P && + window.attributes.layoutInDisplayCutoutMode != WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER + ) { + // Request the display cutout insets from the decor view because the ones given by + // setOnApplyWindowInsetsListener are not always correct for preloaded views. + window.decorView.rootWindowInsets?.displayCutout?.let { displayCutoutInsets -> + top += displayCutoutInsets.safeInsetTop + bottom += displayCutoutInsets.safeInsetBottom + } + } - // Add additional padding to take into account the display cutout, if needed. - if ( - shouldApplyInsetsPadding && - android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P && - window.attributes.layoutInDisplayCutoutMode != WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER - ) { - // Request the display cutout insets from the decor view because the ones given by - // setOnApplyWindowInsetsListener are not always correct for preloaded views. - window.decorView.rootWindowInsets?.displayCutout?.let { displayCutoutInsets -> - top += displayCutoutInsets.safeInsetTop - bottom += displayCutoutInsets.safeInsetBottom + if (!viewModel.isScrollEnabled.value) { + val margin = + resources.getDimension(R.dimen.readium_navigator_epub_vertical_padding) + .toInt() + top += margin + bottom += margin } - } - if (!viewModel.isScrollEnabled.value) { - val margin = resources.getDimension(R.dimen.readium_navigator_epub_vertical_padding).toInt() - top += margin - bottom += margin + containerView.setPadding(0, top, 0, bottom) } - - containerView.setPadding(0, top, 0, bottom) } } @@ -339,17 +345,23 @@ internal class R2EpubPageFragment : Fragment() { if (view == null) return - viewLifecycleOwner.lifecycleScope.launchWhenCreated { - val webView = requireNotNull(webView) - webView.visibility = View.VISIBLE - - pendingLocator - ?.let { locator -> - loadLocator(webView, requireNotNull(navigator).presentation.value.readingProgression, locator) - } - .also { pendingLocator = null } + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) { + val webView = requireNotNull(webView) + webView.visibility = View.VISIBLE + + pendingLocator + ?.let { locator -> + loadLocator( + webView, + requireNotNull(navigator).presentation.value.readingProgression, + locator + ) + } + .also { pendingLocator = null } - webView.listener?.onPageLoaded() + webView.listener?.onPageLoaded() + } } } @@ -359,11 +371,13 @@ internal class R2EpubPageFragment : Fragment() { return } - viewLifecycleOwner.lifecycleScope.launchWhenCreated { - val webView = requireNotNull(webView) - val epubNavigator = requireNotNull(navigator) - loadLocator(webView, epubNavigator.presentation.value.readingProgression, locator) - webView.listener?.onProgressionChanged() + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) { + val webView = requireNotNull(webView) + val epubNavigator = requireNotNull(navigator) + loadLocator(webView, epubNavigator.presentation.value.readingProgression, locator) + webView.listener?.onProgressionChanged() + } } } diff --git a/test-app/build.gradle.kts b/test-app/build.gradle.kts index 1c785ad281..49619c39ff 100644 --- a/test-app/build.gradle.kts +++ b/test-app/build.gradle.kts @@ -49,7 +49,7 @@ android { proguardFiles(getDefaultProguardFile("proguard-android.txt")) } } - packagingOptions { + packaging { resources.excludes.add("META-INF/*") } @@ -76,6 +76,8 @@ dependencies { // Only required if you want to support PDF files using PDFium. implementation(project(":readium:adapters:pdfium")) + implementation(libs.accompanist.themeadapter.material) + implementation(libs.androidx.compose.activity) implementation(libs.androidx.activity.ktx) implementation(libs.androidx.appcompat) diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt index 86aff3c389..f8897cfa16 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt @@ -9,11 +9,16 @@ package org.readium.r2.testapp.catalogs import android.os.Bundle import android.view.LayoutInflater import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.core.os.bundleOf +import androidx.core.view.MenuHost +import androidx.core.view.MenuProvider import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Lifecycle import androidx.navigation.Navigation import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar @@ -55,7 +60,6 @@ class CatalogFragment : Fragment() { publicationAdapter = PublicationAdapter(catalogViewModel::publication::set) navigationAdapter = NavigationAdapter(catalog.type) groupAdapter = GroupAdapter(catalog.type, catalogViewModel::publication::set) - setHasOptionsMenu(true) binding.catalogNavigationList.apply { layoutManager = LinearLayoutManager(requireContext()) @@ -84,63 +88,70 @@ class CatalogFragment : Fragment() { (activity as MainActivity).supportActionBar?.title = catalog.title - // TODO this feels hacky, I don't want to parse the file if it has not changed - if (catalogViewModel.parseData.value == null) { - binding.catalogProgressBar.visibility = View.VISIBLE - catalogViewModel.parseCatalog(catalog) - } - catalogViewModel.parseData.observe(viewLifecycleOwner, { result -> - - facets = result.feed?.facets ?: mutableListOf() - - if (facets.size > 0) { - showFacetMenu = true - } - requireActivity().invalidateOptionsMenu() - - navigationAdapter.submitList(result.feed!!.navigation) - publicationAdapter.submitList(result.feed!!.publications) - groupAdapter.submitList(result.feed!!.groups) + catalogViewModel.parseCatalog(catalog) + binding.catalogProgressBar.visibility = View.VISIBLE + + val menuHost: MenuHost = requireActivity() + + menuHost.addMenuProvider( + object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menu.clear() + if (showFacetMenu) { + facets.let { + for (i in facets.indices) { + val submenu = menu.addSubMenu(facets[i].title) + for (link in facets[i].links) { + val item = submenu.add(link.title) + item.setOnMenuItemClickListener { + val catalog1 = Catalog( + title = link.title!!, + href = link.href, + type = catalog.type + ) + val bundle = bundleOf(CATALOGFEED to catalog1) + Navigation.findNavController(requireView()) + .navigate(R.id.action_navigation_catalog_self, bundle) + true + } + } + } + } + } + } - binding.catalogProgressBar.visibility = View.GONE - }) + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return false + } + }, + viewLifecycleOwner, + Lifecycle.State.RESUMED + ) } private fun handleEvent(event: CatalogViewModel.Event.FeedEvent) { - val message = - when (event) { - is CatalogViewModel.Event.FeedEvent.CatalogParseFailed -> getString(R.string.failed_parsing_catalog) + when (event) { + is CatalogViewModel.Event.FeedEvent.CatalogParseFailed -> { + Snackbar.make( + requireView(), + getString(R.string.failed_parsing_catalog), + Snackbar.LENGTH_LONG + ).show() } - binding.catalogProgressBar.visibility = View.GONE - Snackbar.make( - requireView(), - message, - Snackbar.LENGTH_LONG - ).show() - } - override fun onPrepareOptionsMenu(menu: Menu) { - menu.clear() - if (showFacetMenu) { - facets.let { - for (i in facets.indices) { - val submenu = menu.addSubMenu(facets[i].title) - for (link in facets[i].links) { - val item = submenu.add(link.title) - item.setOnMenuItemClickListener { - val catalog1 = Catalog( - title = link.title!!, - href = link.href, - type = catalog.type - ) - val bundle = bundleOf(CATALOGFEED to catalog1) - Navigation.findNavController(requireView()) - .navigate(R.id.action_navigation_catalog_self, bundle) - true - } - } + is CatalogViewModel.Event.FeedEvent.CatalogParseSuccess -> { + facets = event.result.feed?.facets ?: mutableListOf() + + if (facets.size > 0) { + showFacetMenu = true } + requireActivity().invalidateOptionsMenu() + + navigationAdapter.submitList(event.result.feed!!.navigation) + publicationAdapter.submitList(event.result.feed!!.publications) + groupAdapter.submitList(event.result.feed!!.groups) } } + binding.catalogProgressBar.visibility = View.GONE } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt index 997f9584cb..7aa15b19fb 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt @@ -8,7 +8,6 @@ package org.readium.r2.testapp.catalogs import android.app.Application import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import java.io.File import java.net.MalformedURLException @@ -37,7 +36,6 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) val detailChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) val eventChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) - val parseData = MutableLiveData() lateinit var publication: Publication fun parseCatalog(catalog: Catalog) = viewModelScope.launch { @@ -55,7 +53,7 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) } } parseRequest?.onSuccess { - parseData.postValue(it) + eventChannel.send(Event.FeedEvent.CatalogParseSuccess(it)) } parseRequest?.onFailure { Timber.e(it) @@ -96,6 +94,8 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) sealed class FeedEvent : Event() { object CatalogParseFailed : FeedEvent() + + class CatalogParseSuccess(val result: ParseData) : FeedEvent() } sealed class DetailEvent : Event() { diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt index 3318834dba..f433230041 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt @@ -10,9 +10,13 @@ import android.os.Bundle import android.view.Menu import android.view.MenuInflater import android.view.MenuItem +import android.view.View import android.widget.Toast +import androidx.core.view.MenuHost +import androidx.core.view.MenuProvider import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Lifecycle import org.readium.r2.lcp.lcpLicense import org.readium.r2.navigator.Navigator import org.readium.r2.navigator.preferences.Configurable @@ -37,7 +41,6 @@ abstract class BaseReaderFragment : Fragment() { protected abstract val navigator: Navigator override fun onCreate(savedInstanceState: Bundle?) { - setHasOptionsMenu(true) super.onCreate(savedInstanceState) model.fragmentChannel.receive(this) { event -> @@ -52,44 +55,54 @@ abstract class BaseReaderFragment : Fragment() { } } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val menuHost: MenuHost = requireActivity() + + menuHost.addMenuProvider( + object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.menu_reader, menu) + + menu.findItem(R.id.settings).isVisible = + navigator is Configurable<*, *> + + menu.findItem(R.id.drm).isVisible = + model.publication.lcpLicense != null + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + when (menuItem.itemId) { + R.id.toc -> { + model.activityChannel.send(ReaderViewModel.Event.OpenOutlineRequested) + } + R.id.bookmark -> { + model.insertBookmark(navigator.currentLocator.value) + } + R.id.settings -> { + val settingsModel = checkNotNull(model.settings) + UserPreferencesBottomSheetDialogFragment(settingsModel, "User Settings") + .show(childFragmentManager, "Settings") + } + R.id.drm -> { + model.activityChannel.send(ReaderViewModel.Event.OpenDrmManagementRequested) + } + } + return true + } + }, + viewLifecycleOwner, + Lifecycle.State.RESUMED + ) + } + override fun onHiddenChanged(hidden: Boolean) { super.onHiddenChanged(hidden) setMenuVisibility(!hidden) requireActivity().invalidateOptionsMenu() } - override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) { - menuInflater.inflate(R.menu.menu_reader, menu) - - menu.findItem(R.id.settings).isVisible = - navigator is Configurable<*, *> - - menu.findItem(R.id.drm).isVisible = - model.publication.lcpLicense != null - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.toc -> { - model.activityChannel.send(ReaderViewModel.Event.OpenOutlineRequested) - } - R.id.bookmark -> { - model.insertBookmark(navigator.currentLocator.value) - } - R.id.settings -> { - val settingsModel = checkNotNull(model.settings) - UserPreferencesBottomSheetDialogFragment(settingsModel, "User Settings") - .show(childFragmentManager, "Settings") - } - R.id.drm -> { - model.activityChannel.send(ReaderViewModel.Event.OpenDrmManagementRequested) - } - else -> return super.onOptionsItemSelected(item) - } - - return true - } - open fun go(locator: Locator, animated: Boolean) { navigator.go(locator, animated) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt index 9447f657ff..12d4b85f35 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt @@ -14,6 +14,8 @@ import android.view.inputmethod.InputMethodManager import android.widget.ImageView import androidx.annotation.ColorInt import androidx.appcompat.widget.SearchView +import androidx.core.view.MenuHost +import androidx.core.view.MenuProvider import androidx.fragment.app.FragmentResultListener import androidx.fragment.app.commit import androidx.fragment.app.commitNow @@ -105,8 +107,6 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene } ) - setHasOptionsMenu(true) - super.onCreate(savedInstanceState) } @@ -140,6 +140,37 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene (navigator as? DecorableNavigator)?.applyPageNumberDecorations() } } + + val menuHost: MenuHost = requireActivity() + + menuHost.addMenuProvider( + object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuSearch = menu.findItem(R.id.search).apply { + isVisible = true + menuSearchView = actionView as SearchView + } + + connectSearch() + if (!isSearchViewIconified) menuSearch.expandActionView() + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + when (menuItem.itemId) { + R.id.search -> { + return true + } + android.R.id.home -> { + menuSearch.collapseActionView() + return true + } + } + return true + } + }, + viewLifecycleOwner, + Lifecycle.State.RESUMED + ) } /** @@ -164,18 +195,6 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene applyDecorations(decorations, "pageNumbers") } - override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) { - super.onCreateOptionsMenu(menu, menuInflater) - - menuSearch = menu.findItem(R.id.search).apply { - isVisible = true - menuSearchView = actionView as SearchView - } - - connectSearch() - if (!isSearchViewIconified) menuSearch.expandActionView() - } - override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putBoolean(IS_SEARCH_VIEW_ICONIFIED, isSearchViewIconified) @@ -227,18 +246,6 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene } } - override fun onOptionsItemSelected(item: MenuItem): Boolean = - when (item.itemId) { - R.id.search -> { - super.onOptionsItemSelected(item) - } - android.R.id.home -> { - menuSearch.collapseActionView() - true - } - else -> super.onOptionsItemSelected(item) - } - private fun showSearchFragment() { childFragmentManager.commit { childFragmentManager.findFragmentByTag(SEARCH_FRAGMENT_TAG)?.let { remove(it) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt index 17af993680..a345ccf419 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt @@ -30,6 +30,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.dp +import androidx.core.view.MenuHost +import androidx.core.view.MenuProvider import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -132,6 +134,25 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List content = { Overlay() } ) } + + val menuHost: MenuHost = requireActivity() + + menuHost.addMenuProvider( + object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menu.findItem(R.id.tts).isVisible = (model.tts != null) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + when (menuItem.itemId) { + R.id.tts -> checkNotNull(model.tts).start(navigator) + } + return true + } + }, + viewLifecycleOwner, + Lifecycle.State.RESUMED + ) } @Composable @@ -152,7 +173,7 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List private fun setupObservers() { viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) { navigator.currentLocator .onEach { model.saveProgression(it) } .launchIn(this) @@ -271,19 +292,6 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List requireActivity().invalidateOptionsMenu() } - override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) { - super.onCreateOptionsMenu(menu, menuInflater) - menu.findItem(R.id.tts).isVisible = (model.tts != null) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.tts -> checkNotNull(model.tts).start(navigator) - else -> return super.onOptionsItemSelected(item) - } - return true - } - // DecorableNavigator.Listener private val decorationListener by lazy { DecorationListener() } diff --git a/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt b/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt index 38bf618988..f4ad6a7c98 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt @@ -143,14 +143,14 @@ private fun MenuItem( ) } ) { dismiss -> - for (value in values) { + for (aValue in values) { DropdownMenuItem( onClick = { dismiss() - onValueChanged(value) + onValueChanged(aValue) } ) { - Text(formatValue(value)) + Text(formatValue(aValue)) } } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/AppTheme.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/AppTheme.kt index b26ab96095..4bae27d3de 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/AppTheme.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/AppTheme.kt @@ -7,7 +7,7 @@ package org.readium.r2.testapp.utils.compose import androidx.compose.runtime.Composable -import com.google.android.material.composethemeadapter.MdcTheme +import com.google.accompanist.themeadapter.material.MdcTheme /** * Setup the Compose app-wide theme. diff --git a/test-app/src/main/res/layout/fragment_search.xml b/test-app/src/main/res/layout/fragment_search.xml index a7f1c4c466..125aa93c46 100644 --- a/test-app/src/main/res/layout/fragment_search.xml +++ b/test-app/src/main/res/layout/fragment_search.xml @@ -17,7 +17,6 @@ android:id="@+id/search_recyclerView" android:layout_width="0dp" android:layout_height="0dp" - android:background="@android:color/white" app:layout_constraintBottom_toBottomOf="@id/search_overlay" app:layout_constraintEnd_toEndOf="@id/search_overlay" app:layout_constraintStart_toStartOf="@id/search_overlay" diff --git a/test-app/src/main/res/layout/section_header.xml b/test-app/src/main/res/layout/section_header.xml index b2afa8ab6c..93b05d379a 100644 --- a/test-app/src/main/res/layout/section_header.xml +++ b/test-app/src/main/res/layout/section_header.xml @@ -9,6 +9,8 @@ android:id="@+id/header" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/colorPrimarySurface" + android:textColor="?attr/colorOnPrimarySurface" android:orientation="vertical" android:ellipsize="end" android:maxLines="3" From a9e8b0d9ac26256bb14898db628ff91d3403f4e3 Mon Sep 17 00:00:00 2001 From: Steven Zeck <8315038+stevenzeck@users.noreply.github.com> Date: Wed, 2 Aug 2023 03:06:23 -0500 Subject: [PATCH 21/65] More cleanup (#372) --- .../navigator/media2/ExoPlayerDataSource.kt | 3 + .../navigator/media2/MediaNavigator.kt | 3 + .../readium/r2/navigator/R2BasicWebView.kt | 4 +- .../org/readium/r2/navigator/R2WebView.kt | 24 -------- .../navigator/audio/PublicationDataSource.kt | 3 + .../navigator/epub/EpubNavigatorFragment.kt | 5 +- .../navigator/image/ImageNavigatorFragment.kt | 3 +- .../r2/navigator/media/ExoMediaPlayer.kt | 3 + .../r2/navigator/media/MediaService.kt | 8 ++- .../r2/navigator/pager/R2CbzPageFragment.kt | 3 +- .../r2/navigator/pager/R2EpubPageFragment.kt | 8 +-- .../navigator/pager/R2FragmentPagerAdapter.kt | 5 +- settings.gradle.kts | 2 +- .../r2/testapp/catalogs/CatalogFragment.kt | 4 +- .../r2/testapp/outline/NavigationFragment.kt | 3 +- .../r2/testapp/outline/OutlineContract.kt | 3 +- .../r2/testapp/reader/EpubReaderFragment.kt | 5 +- .../readium/r2/testapp/reader/MediaService.kt | 4 +- .../r2/testapp/reader/VisualReaderFragment.kt | 2 +- .../r2/testapp/search/SearchPagingSource.kt | 4 +- .../utils/LifecycleMedia2SessionService.kt | 58 ------------------- .../r2/testapp/utils/R2DispatcherActivity.kt | 3 +- 22 files changed, 53 insertions(+), 107 deletions(-) delete mode 100644 test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt index 639ae6839e..06e3073c23 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt @@ -4,6 +4,9 @@ * available in the top-level LICENSE file of the project. */ +// Everything in this file will be deprecated +@file:Suppress("DEPRECATION") + package org.readium.navigator.media2 import android.net.Uri diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt index 24c00d9996..9453e48bbb 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt @@ -4,6 +4,9 @@ * available in the top-level LICENSE file of the project. */ +// Everything in this file will be deprecated +@file:Suppress("DEPRECATION") + package org.readium.navigator.media2 import android.app.PendingIntent diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt index f34da5d47b..d11ca5f146 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt @@ -373,9 +373,7 @@ internal open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebV // Set an elevation value for popup window // Call requires API level 21 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mPopupWindow.elevation = 5.0f - } + mPopupWindow.elevation = 5.0f val textView = customView.findViewById(R.id.footnote) as TextView if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt index 1e752a50ca..d552d3259b 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt @@ -64,8 +64,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } } - private val USE_CACHE = false - private val MAX_SETTLE_DURATION = 600 // ms private val MIN_DISTANCE_FOR_FLING = 25 // dips private val MIN_FLING_VELOCITY = 400 // dips @@ -106,8 +104,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView private val mFirstOffset = -java.lang.Float.MAX_VALUE private val mLastOffset = java.lang.Float.MAX_VALUE - private var mScrollingCacheEnabled: Boolean = false - private var mIsBeingDragged: Boolean = false private var mGutterSize: Int = 30 private var mTouchSlop: Int = 0 @@ -396,7 +392,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView sx = if (mIsScrollStarted) mScroller!!.currX else mScroller!!.startX // And abort the current scrolling. mScroller!!.abortAnimation() - setScrollingCacheEnabled(false) } else { sx = scrollX } @@ -409,7 +404,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView return } - setScrollingCacheEnabled(true) setScrollState(SCROLL_STATE_SETTLING) val halfWidth = width / 2 @@ -662,8 +656,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView private fun completeScroll(postEvents: Boolean) { val needPopulate = mScrollState == SCROLL_STATE_SETTLING if (needPopulate) { - // Done with scroll, no longer want to cache view drawing. - setScrollingCacheEnabled(false) val wasScrolling = !mScroller!!.isFinished if (wasScrolling) { mScroller!!.abortAnimation() @@ -730,7 +722,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView else mInitialMotionX - mTouchSlop setScrollState(SCROLL_STATE_DRAGGING) - setScrollingCacheEnabled(true) } } } @@ -885,21 +876,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } } - private fun setScrollingCacheEnabled(enabled: Boolean) { - if (mScrollingCacheEnabled != enabled) { - mScrollingCacheEnabled = enabled - if (USE_CACHE) { - val size = childCount - for (i in 0 until size) { - val child = getChildAt(i) - if (child.visibility != View.GONE) { - child.isDrawingCacheEnabled = enabled - } - } - } - } - } - override fun dispatchKeyEvent(event: KeyEvent): Boolean { // Let the focused view and/or our descendants get the key first return super.dispatchKeyEvent(event) || executeKeyEvent(event) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt index 54c60c192b..30bf2164f3 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt @@ -4,6 +4,9 @@ * available in the top-level LICENSE file of the project. */ +// Everything in this file will be deprecated +@file:Suppress("DEPRECATION") + package org.readium.r2.navigator.audio import android.net.Uri diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt index 904acabbee..218129766e 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt @@ -21,6 +21,7 @@ import android.webkit.WebResourceResponse import android.webkit.WebView import androidx.collection.forEach import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.os.BundleCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentFactory @@ -482,7 +483,8 @@ public class EpubNavigatorFragment internal constructor( withStarted { // Restore the last locator before a configuration change (e.g. screen rotation), or the // initial locator when given. - val locator = savedInstanceState?.getParcelable("locator") ?: initialLocator + val locator = savedInstanceState?.let { BundleCompat.getParcelable(it, "locator", Locator::class.java) } + ?: initialLocator if (locator != null) { go(locator) } @@ -1038,6 +1040,7 @@ public class EpubNavigatorFragment internal constructor( * @param config Additional configuration. */ @Deprecated("Use `EpubNavigatorFactory().createFragmentFactory()` instead", level = DeprecationLevel.ERROR) + @Suppress("UNUSED_PARAMETER") public fun createFactory( publication: Publication, baseUrl: String? = null, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt index 00a25a4b8b..d08354be5b 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt @@ -217,6 +217,7 @@ public class ImageNavigatorFragment private constructor( override val publicationView: View get() = requireView() + @Suppress("DEPRECATION") @Deprecated( "Use `presentation.value.readingProgression` instead", replaceWith = ReplaceWith("presentation.value.readingProgression"), @@ -229,7 +230,7 @@ public class ImageNavigatorFragment private constructor( override val presentation: StateFlow = MutableStateFlow( SimplePresentation( - readingProgression = when (publication.metadata.effectiveReadingProgression) { + readingProgression = when (publication.metadata.readingProgression) { PublicationReadingProgression.RTL -> ReadingProgression.RTL else -> ReadingProgression.LTR }, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt index c14447bab7..ca360ee114 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt @@ -4,6 +4,9 @@ * available in the top-level LICENSE file of the project. */ +// Everything in this file will be deprecated +@file:Suppress("DEPRECATION") + package org.readium.r2.navigator.media import android.app.Notification diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt index f2293743dd..9025277b30 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt @@ -18,6 +18,8 @@ import android.os.ResultReceiver import android.support.v4.media.MediaBrowserCompat import android.support.v4.media.session.MediaSessionCompat import android.widget.Toast +import androidx.core.app.ServiceCompat +import androidx.core.os.BundleCompat import androidx.media.MediaBrowserServiceCompat import kotlin.reflect.KMutableProperty0 import kotlinx.coroutines.* @@ -151,7 +153,7 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by return null } - val locator = (extras?.getParcelable(EXTRA_LOCATOR) as? Locator) + val locator = extras?.let { BundleCompat.getParcelable(it, EXTRA_LOCATOR, Locator::class.java) } ?: href ?.let { navigator.publication.linkWithHref(it) } ?.let { navigator.publication.locatorFromLink(it) } @@ -178,7 +180,7 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by override fun onNotificationCancelled(notificationId: Int) { this@MediaService.notificationId = null this@MediaService.notification = null - stopForeground(true) + ServiceCompat.stopForeground(this@MediaService, ServiceCompat.STOP_FOREGROUND_REMOVE) if (currentNavigator.value?.isPlaying == false) { onPlayerStopped() @@ -249,7 +251,7 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by startForeground(id, note) } } else { - stopForeground(false) + ServiceCompat.stopForeground(this@MediaService, ServiceCompat.STOP_FOREGROUND_DETACH) } } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt index 079fdb782a..85aab5db2b 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt @@ -15,6 +15,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowManager +import androidx.core.os.BundleCompat import androidx.core.view.ViewCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -38,7 +39,7 @@ internal class R2CbzPageFragment( get() = Dispatchers.Main private val link: Link - get() = requireArguments().getParcelable("link")!! + get() = BundleCompat.getParcelable(requireArguments(), "link", Link::class.java)!! private lateinit var containerView: View private lateinit var photoView: PhotoView diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt index c1b7a272bf..b475930231 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt @@ -19,6 +19,7 @@ import android.view.* import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse import android.webkit.WebView +import androidx.core.os.BundleCompat import androidx.core.view.ViewCompat import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -50,7 +51,7 @@ internal class R2EpubPageFragment : Fragment() { get() = requireArguments().getString("url") internal val link: Link? - get() = requireArguments().getParcelable("link") + get() = BundleCompat.getParcelable(requireArguments(), "link", Link::class.java) private var pendingLocator: Locator? = null @@ -118,7 +119,7 @@ internal class R2EpubPageFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - pendingLocator = requireArguments().getParcelable("initialLocator") + pendingLocator = BundleCompat.getParcelable(requireArguments(), "initialLocator", Locator::class.java) } @SuppressLint("SetJavaScriptEnabled", "JavascriptInterface") @@ -170,9 +171,8 @@ internal class R2EpubPageFragment : Fragment() { clampedX: Boolean, clampedY: Boolean ) { - val activity = activity ?: return + activity ?: return val metrics = DisplayMetrics() - activity.windowManager.defaultDisplay.getMetrics(metrics) val topDecile = webView.contentHeight - 1.15 * metrics.heightPixels val bottomDecile = (webView.contentHeight - metrics.heightPixels).toDouble() diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt index f58f52fb89..d024e1b313 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt @@ -15,11 +15,14 @@ import android.os.Parcelable import android.view.View import android.view.ViewGroup import androidx.collection.LongSparseArray +import androidx.core.os.BundleCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentTransaction import androidx.viewpager.widget.PagerAdapter +// This class will be going away when the navigator is rewritten +@Suppress("DEPRECATION") internal abstract class R2FragmentPagerAdapter(private val mFragmentManager: FragmentManager) : androidx.fragment.app.FragmentStatePagerAdapter(mFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { val mFragments = LongSparseArray() @@ -148,7 +151,7 @@ internal abstract class R2FragmentPagerAdapter(private val mFragmentManager: Fra mFragments.clear() if (fss != null) { for (fs in fss) { - mSavedStates.put(fs, bundle.getParcelable(fs.toString()) as Fragment.SavedState) + mSavedStates.put(fs, BundleCompat.getParcelable(bundle, fs.toString(), Fragment.SavedState::class.java)) } } val keys = bundle.keySet() diff --git a/settings.gradle.kts b/settings.gradle.kts index 9a18a9926d..f670f64fb9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -20,7 +20,7 @@ pluginManagement { plugins { id("com.android.application") version ("8.1.0") id("com.android.library") version ("8.1.0") - id("io.github.gradle-nexus.publish-plugin") version ("1.1.0") + id("io.github.gradle-nexus.publish-plugin") version ("1.3.0") id("org.jetbrains.dokka") version ("1.8.20") id("org.jetbrains.kotlin.android") version ("1.9.0") id("org.jetbrains.kotlin.plugin.serialization") version ("1.9.0") diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt index f8897cfa16..6fdabfaab3 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt @@ -13,6 +13,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import androidx.core.os.BundleCompat import androidx.core.os.bundleOf import androidx.core.view.MenuHost import androidx.core.view.MenuProvider @@ -50,7 +51,8 @@ class CatalogFragment : Fragment() { ): View { catalogViewModel.eventChannel.receive(this) { handleEvent(it) } - catalog = arguments?.get(CATALOGFEED) as Catalog + + catalog = arguments?.let { BundleCompat.getParcelable(it, CATALOGFEED, Catalog::class.java) }!! binding = FragmentCatalogBinding.inflate(inflater, container, false) return binding.root } diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt index 8626204fd8..1c50a406aa 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt @@ -11,6 +11,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.LinearLayout +import androidx.core.os.BundleCompat import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResult import androidx.lifecycle.ViewModelProvider @@ -41,7 +42,7 @@ class NavigationFragment : Fragment() { publication = it.publication } - links = requireNotNull(requireArguments().getParcelableArrayList(LINKS_ARG)) + links = requireNotNull(BundleCompat.getParcelableArrayList(requireArguments(), LINKS_ARG, Link::class.java)) } override fun onCreateView( diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt index 55f23bc6a7..434b314442 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt @@ -7,6 +7,7 @@ package org.readium.r2.testapp.outline import android.os.Bundle +import androidx.core.os.BundleCompat import org.readium.r2.shared.publication.Locator object OutlineContract { @@ -21,7 +22,7 @@ object OutlineContract { Bundle().apply { putParcelable(DESTINATION_KEY, locator) } fun parseResult(result: Bundle): Result { - val destination = requireNotNull(result.getParcelable(DESTINATION_KEY)) + val destination = requireNotNull(BundleCompat.getParcelable(result, DESTINATION_KEY, Locator::class.java)) return Result(destination) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt index 12d4b85f35..d39c496aa7 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt @@ -14,6 +14,7 @@ import android.view.inputmethod.InputMethodManager import android.widget.ImageView import androidx.annotation.ColorInt import androidx.appcompat.widget.SearchView +import androidx.core.os.BundleCompat import androidx.core.view.MenuHost import androidx.core.view.MenuProvider import androidx.fragment.app.FragmentResultListener @@ -101,7 +102,7 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene this, FragmentResultListener { _, result -> menuSearch.collapseActionView() - result.getParcelable(SearchFragment::class.java.name)?.let { + BundleCompat.getParcelable(result, SearchFragment::class.java.name, Locator::class.java)?.let { navigator.go(it) } } @@ -241,7 +242,7 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene menuSearchView.setQuery("", false) (activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.showSoftInput( - this.view, InputMethodManager.SHOW_FORCED + this.view, 0 ) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt index b1a9d0f3ca..9f384735c5 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt @@ -13,6 +13,7 @@ import android.content.Intent import android.content.ServiceConnection import android.os.Build import android.os.IBinder +import androidx.core.app.ServiceCompat import androidx.core.content.ContextCompat import androidx.media3.session.MediaSession import androidx.media3.session.MediaSessionService @@ -53,13 +54,14 @@ class MediaService : MediaSessionService() { sessionMutable.asStateFlow() fun closeSession() { - stopForeground(true) + ServiceCompat.stopForeground(this@MediaService, ServiceCompat.STOP_FOREGROUND_REMOVE) session.value?.mediaSession?.release() session.value?.navigator?.close() session.value?.coroutineScope?.cancel() sessionMutable.value = null } + @OptIn(FlowPreview::class) fun openSession( navigator: N, bookId: Long diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt index a345ccf419..c9dafa121f 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt @@ -262,7 +262,7 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List */ private suspend fun confirmAndInstallTtsVoice(language: Language) { val activity = activity ?: return - val tts = model.tts ?: return + model.tts ?: return if ( activity.confirmDialog( diff --git a/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt b/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt index 4ecee81641..9d858e5f87 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt @@ -8,13 +8,13 @@ package org.readium.r2.testapp.search import androidx.paging.PagingSource import androidx.paging.PagingState -import org.readium.r2.shared.Search +import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.LocatorCollection import org.readium.r2.shared.publication.services.search.SearchTry -@OptIn(Search::class) +@OptIn(ExperimentalReadiumApi::class) class SearchPagingSource( private val listener: Listener? ) : PagingSource() { diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt deleted file mode 100644 index e485a18e5a..0000000000 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/LifecycleMedia2SessionService.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.testapp.utils - -import android.content.Intent -import android.os.IBinder -import androidx.annotation.CallSuper -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ServiceLifecycleDispatcher -import androidx.media2.session.MediaSessionService - -/* - * Borrowed from - * https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/lifecycle/lifecycle-service/src/main/java/androidx/lifecycle/LifecycleService.java - */ - -abstract class LifecycleMedia2SessionService : MediaSessionService(), LifecycleOwner { - - @Suppress("LeakingThis") - private val lifecycleDispatcher = ServiceLifecycleDispatcher(this) - - @CallSuper - override fun onCreate() { - lifecycleDispatcher.onServicePreSuperOnCreate() - super.onCreate() - } - - @CallSuper - override fun onBind(intent: Intent): IBinder? { - lifecycleDispatcher.onServicePreSuperOnBind() - return super.onBind(intent) - } - - @CallSuper - override fun onStart(intent: Intent?, startId: Int) { - lifecycleDispatcher.onServicePreSuperOnStart() - super.onStart(intent, startId) - } - - // this method is added only to annotate it with @CallSuper. - // In usual service super.onStartCommand is no-op, but in LifecycleService - // it results in mDispatcher.onServicePreSuperOnStart() call, because - // super.onStartCommand calls onStart(). - @CallSuper - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - return super.onStartCommand(intent, flags, startId) - } - - @CallSuper - override fun onDestroy() { - lifecycleDispatcher.onServicePreSuperOnDestroy() - super.onDestroy() - } -} diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/R2DispatcherActivity.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/R2DispatcherActivity.kt index 65fd24eb6a..df9bcc3e60 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/R2DispatcherActivity.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/R2DispatcherActivity.kt @@ -14,6 +14,7 @@ import android.app.Activity import android.content.Intent import android.net.Uri import android.os.Bundle +import androidx.core.content.IntentCompat import org.readium.r2.testapp.MainActivity import timber.log.Timber @@ -44,7 +45,7 @@ class R2DispatcherActivity : Activity() { if ("text/plain" == intent.type) { intent.getStringExtra(Intent.EXTRA_TEXT).let { Uri.parse(it) } } else { - intent.getParcelableExtra(Intent.EXTRA_STREAM) + IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java) } } else -> { From 1570e80ab0a8f28255e53cabb291b1152f565a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Tue, 22 Aug 2023 15:51:06 +0200 Subject: [PATCH 22/65] Replace the `Fetcher` by `Container` and refactor media type sniffing (#373) Co-authored-by: Quentin Gliosca --- .gitignore | 3 +- CHANGELOG.md | 9 + .../pdfium/document/PdfiumDocument.kt | 18 +- .../pdfium/navigator/PdfiumDefaults.kt | 2 +- .../navigator/PdfiumDocumentFragment.kt | 8 +- .../pdfium/navigator/PdfiumPreferences.kt | 4 +- .../navigator/PdfiumPreferencesEditor.kt | 10 +- .../navigator/PdfiumPreferencesFilters.kt | 4 +- .../pdfium/navigator/PdfiumSettings.kt | 2 +- .../navigator/PdfiumSettingsResolver.kt | 2 +- .../pspdfkit/document/PsPdfKitDocument.kt | 4 +- .../pspdfkit/document/ResourceDataProvider.kt | 5 +- .../pspdfkit/navigator/PsPdfKitDefaults.kt | 2 +- .../navigator/PsPdfKitDocumentFragment.kt | 11 +- .../navigator/PsPdfKitEngineProvider.kt | 1 - .../pspdfkit/navigator/PsPdfKitPreferences.kt | 4 +- .../navigator/PsPdfKitPreferencesEditor.kt | 16 +- .../navigator/PsPdfKitPreferencesFilters.kt | 4 +- .../pspdfkit/navigator/PsPdfKitSettings.kt | 2 +- .../navigator/PsPdfKitSettingsResolver.kt | 4 +- .../org/readium/r2/lcp/LcpAuthenticating.kt | 34 +- .../readium/r2/lcp/LcpContentProtection.kt | 68 +- .../java/org/readium/r2/lcp/LcpDecryptor.kt | 119 +-- .../org/readium/r2/lcp/LcpDecryptorTest.kt | 45 +- .../java/org/readium/r2/lcp/LcpException.kt | 161 +++- .../java/org/readium/r2/lcp/LcpLicense.kt | 48 +- .../java/org/readium/r2/lcp/LcpService.kt | 75 +- .../readium/r2/lcp/MaterialRenewListener.kt | 4 +- .../r2/lcp/auth/LcpDialogAuthentication.kt | 36 +- .../lcp/auth/LcpPassphraseAuthentication.kt | 7 +- .../org/readium/r2/lcp/license/License.kt | 39 +- .../r2/lcp/license/LicenseValidation.kt | 84 +- .../readium/r2/lcp/license/StateMachine.kt | 6 +- .../container/ContainerLicenseContainer.kt | 8 +- .../lcp/license/container/LicenseContainer.kt | 4 +- .../license/container/ZIPLicenseContainer.kt | 3 +- .../r2/lcp/license/model/LicenseDocument.kt | 12 +- .../r2/lcp/license/model/StatusDocument.kt | 20 +- .../r2/lcp/license/model/components/Link.kt | 7 +- .../lcp/license/model/components/lsd/Event.kt | 10 +- .../org/readium/r2/lcp/persistence/LcpDao.kt | 36 +- .../org/readium/r2/lcp/public/Deprecated.kt | 57 +- .../org/readium/r2/lcp/service/CRLService.kt | 10 +- .../readium/r2/lcp/service/DeviceService.kt | 5 +- .../org/readium/r2/lcp/service/LcpClient.kt | 24 +- .../readium/r2/lcp/service/LicensesService.kt | 72 +- .../readium/r2/lcp/service/NetworkService.kt | 17 +- .../r2/lcp/service/PassphrasesService.kt | 23 +- .../navigator/media2/ExoPlayerDataSource.kt | 34 +- .../navigator/media2/MediaNavigator.kt | 17 +- .../org/readium/navigator/media2/OptIn.kt | 7 +- .../navigator/media2/SessionPlayerFacade.kt | 2 +- .../navigator/media2/SessionPlayerHelpers.kt | 7 +- .../navigator/media2/SmartSeekerTest.kt | 9 +- .../r2/navigator/DecorableNavigator.kt | 14 +- .../org/readium/r2/navigator/Navigator.kt | 22 +- .../java/org/readium/r2/navigator/OptIn.kt | 21 +- .../readium/r2/navigator/R2BasicWebView.kt | 15 +- .../org/readium/r2/navigator/R2WebView.kt | 43 +- .../r2/navigator/SelectableNavigator.kt | 2 +- .../r2/navigator/SimplePresentation.kt | 2 +- .../navigator/audio/PublicationDataSource.kt | 41 +- .../cbz/{Deprecated.kt => R2CbzActivity.kt} | 8 +- .../{Deprecated.kt => R2DiViNaActivity.kt} | 3 - .../readium/r2/navigator/epub/Deprecated.kt | 7 +- .../r2/navigator/epub/EpubNavigatorFactory.kt | 6 +- .../navigator/epub/EpubNavigatorFragment.kt | 64 +- .../navigator/epub/EpubNavigatorViewModel.kt | 22 +- .../r2/navigator/epub/EpubPreferences.kt | 11 +- .../navigator/epub/EpubPreferencesEditor.kt | 59 +- .../navigator/epub/EpubPreferencesFilters.kt | 4 +- .../readium/r2/navigator/epub/EpubSettings.kt | 14 +- .../r2/navigator/epub/EpubSettingsResolver.kt | 2 +- .../readium/r2/navigator/epub/HtmlInjector.kt | 25 +- .../r2/navigator/epub/WebViewServer.kt | 51 +- .../epub/css/FontFamilyDeclaration.kt | 2 +- .../readium/r2/navigator/epub/css/Layout.kt | 5 +- .../r2/navigator/epub/css/Properties.kt | 11 +- .../r2/navigator/epub/css/ReadiumCss.kt | 22 +- .../r2/navigator/epub/fxl/R2FXLLayout.kt | 34 +- .../r2/navigator/epub/fxl/R2FXLUtils.kt | 7 +- .../navigator/html/HtmlDecorationTemplate.kt | 42 +- .../navigator/image/ImageNavigatorFragment.kt | 24 +- .../r2/navigator/media/ExoMediaPlayer.kt | 16 +- .../r2/navigator/media/MediaService.kt | 28 +- .../navigator/media/MediaSessionNavigator.kt | 11 +- .../media3/api/DefaultMediaMetadataFactory.kt | 2 +- .../navigator/media3/audio/AudioNavigator.kt | 22 +- .../media3/audio/AudioNavigatorFactory.kt | 13 +- .../media3/audio/MetadataRetriever.kt | 13 +- .../media3/exoplayer/ExoAudiobookPlayer.kt | 2 +- .../media3/exoplayer/ExoPlayerDataSource.kt | 27 +- .../media3/exoplayer/ExoPlayerEngine.kt | 3 +- .../media3/exoplayer/ExoPlayerPreferences.kt | 4 +- .../exoplayer/ExoPlayerPreferencesEditor.kt | 6 +- .../exoplayer/ExoPlayerSettingsResolver.kt | 3 +- .../media3/syncmedia/GuidedMediaNavigator.kt | 6 +- .../media3/tts/TtsContentIterator.kt | 5 +- .../r2/navigator/media3/tts/TtsNavigator.kt | 10 +- .../media3/tts/TtsNavigatorFactory.kt | 7 +- .../r2/navigator/media3/tts/TtsPlayer.kt | 9 +- .../media3/tts/android/AndroidTtsEngine.kt | 10 +- .../tts/android/AndroidTtsPreferences.kt | 4 +- .../android/AndroidTtsPreferencesEditor.kt | 10 +- .../media3/tts/android/AndroidTtsSettings.kt | 2 +- .../tts/session/AudioBecomingNoisyManager.kt | 3 +- .../media3/tts/session/AudioFocusManager.kt | 80 +- .../media3/tts/session/StreamVolumeManager.kt | 3 +- .../media3/tts/session/TtsSessionAdapter.kt | 76 +- .../media3/tts/session/TtsTimeline.kt | 2 +- .../r2/navigator/pager/R2CbzPageFragment.kt | 1 - .../r2/navigator/pager/R2EpubPageFragment.kt | 22 +- .../r2/navigator/pager/R2FXLPageFragment.kt | 17 +- .../navigator/pager/R2FragmentPagerAdapter.kt | 15 +- .../r2/navigator/pdf/PdfNavigatorFactory.kt | 2 +- .../r2/navigator/pdf/PdfNavigatorFragment.kt | 12 +- .../r2/navigator/pdf/PdfNavigatorViewModel.kt | 20 + .../pdf/{Deprecated.kt => R2PdfActivity.kt} | 8 +- .../navigator/preferences/MappedPreference.kt | 14 +- .../preferences/PreferenceDelegate.kt | 6 +- .../readium/r2/navigator/preferences/Types.kt | 97 ++- .../r2/navigator/util/EdgeTapNavigation.kt | 6 +- .../readium/r2/navigator/DecorationTest.kt | 6 +- .../r2/navigator/audio/SmartSeekerTest.kt | 9 +- .../epub/EpubSettingsResolverTest.kt | 516 ++++++++++--- .../r2/navigator/epub/css/PropertiesTest.kt | 14 +- .../r2/navigator/epub/css/ReadiumCssTest.kt | 2 +- .../java/org/readium/r2/opds/OPDS1Parser.kt | 61 +- .../java/org/readium/r2/opds/OPDS2Parser.kt | 38 +- .../org/readium/r2/opds/OPDS1ParserTest.kt | 75 +- .../org/readium/r2/shared/util/HrefTest.kt | 719 +++++++++++++++--- .../java/org/readium/r2/shared/Deprecated.kt | 169 +++- .../org/readium/r2/shared/MediaOverlays.kt | 10 +- .../main/java/org/readium/r2/shared/OptIn.kt | 36 +- .../java/org/readium/r2/shared/ReadiumCSS.kt | 27 +- .../java/org/readium/r2/shared/RootFile.kt | 1 + .../org/readium/r2/shared/UserException.kt | 11 +- .../java/org/readium/r2/shared/asset/Asset.kt | 24 +- .../readium/r2/shared/asset/AssetRetriever.kt | 233 +++--- .../java/org/readium/r2/shared/drm/DRM.kt | 8 +- .../java/org/readium/r2/shared/error/Error.kt | 2 +- .../readium/r2/shared/extensions/Bitmap.kt | 3 +- .../readium/r2/shared/extensions/ByteArray.kt | 11 + .../org/readium/r2/shared/extensions/File.kt | 4 +- .../r2/shared/extensions/InputStream.kt | 3 +- .../readium/r2/shared/extensions/Intent.kt | 49 +- .../org/readium/r2/shared/extensions/JSON.kt | 4 +- .../readium/r2/shared/extensions/LongRange.kt | 11 +- .../r2/shared/fetcher/BytesResource.kt | 53 -- .../r2/shared/fetcher/ContainerFetcher.kt | 100 --- .../org/readium/r2/shared/fetcher/Fetcher.kt | 119 --- .../readium/r2/shared/fetcher/FileFetcher.kt | 93 --- .../org/readium/r2/shared/fetcher/Resource.kt | 413 ---------- .../r2/shared/fetcher/RoutingFetcher.kt | 48 -- .../r2/shared/fetcher/TransformingFetcher.kt | 36 - .../org/readium/r2/shared/opds/Acquisition.kt | 14 +- .../readium/r2/shared/parser/xml/XmlParser.kt | 11 +- .../r2/shared/publication/Accessibility.kt | 35 +- .../r2/shared/publication/ContentLayout.kt | 3 + .../r2/shared/publication/Contributor.kt | 33 +- .../org/readium/r2/shared/publication/Link.kt | 86 ++- .../r2/shared/publication/LocalizedString.kt | 6 +- .../readium/r2/shared/publication/Locator.kt | 42 +- .../readium/r2/shared/publication/Manifest.kt | 73 +- .../readium/r2/shared/publication/Metadata.kt | 172 ++++- .../r2/shared/publication/Properties.kt | 10 + .../r2/shared/publication/Publication.kt | 203 +++-- .../publication/PublicationCollection.kt | 47 +- .../publication/PublicationServicesHolder.kt | 42 + .../shared/publication/ReadingProgression.kt | 12 +- .../readium/r2/shared/publication/Subject.kt | 21 +- .../shared/publication/archive/Properties.kt | 49 +- .../r2/shared/publication/epub/EpubLayout.kt | 13 +- .../r2/shared/publication/html/DomRange.kt | 12 +- .../r2/shared/publication/opds/Properties.kt | 12 +- .../publication/presentation/Presentation.kt | 137 +++- .../AdeptFallbackContentProtection.kt | 20 +- .../protection/ContentProtection.kt | 24 +- .../ContentProtectionSchemeRetriever.kt | 2 +- .../LcpFallbackContentProtection.kt | 19 +- .../services/ContentProtectionService.kt | 92 ++- .../publication/services/CoverService.kt | 33 +- .../publication/services/LocatorService.kt | 6 +- .../publication/services/PositionsService.kt | 53 +- .../publication/services/content/Content.kt | 14 +- .../services/content/ContentService.kt | 19 +- .../services/content/ContentTokenizer.kt | 17 +- .../iterators/HtmlResourceContentIterator.kt | 71 +- .../iterators/PublicationContentIterator.kt | 26 +- .../services/search/SearchService.kt | 14 +- .../services/search/StringSearchService.kt | 47 +- .../r2/shared/resource/BufferingResource.kt | 157 ++++ .../r2/shared/resource/BytesResource.kt | 74 +- .../readium/r2/shared/resource/Container.kt | 61 +- .../r2/shared/resource/ContentResource.kt | 32 +- .../shared/resource/DefaultArchiveFactory.kt | 12 +- .../r2/shared/resource/DirectoryContainer.kt | 40 +- .../readium/r2/shared/resource/Factories.kt | 40 +- .../r2/shared/resource/FallbackResource.kt | 74 ++ .../r2/shared/resource/FileChannelResource.kt | 14 +- .../r2/shared/resource/FileResource.kt | 48 +- .../r2/shared/resource/LazyResource.kt | 57 ++ .../r2/shared/resource/MediaTypeExt.kt | 23 + .../readium/r2/shared/resource/Resource.kt | 57 +- .../r2/shared/resource/ResourceInputStream.kt | 10 +- .../r2/shared/resource/RoutingContainer.kt | 55 ++ .../shared/resource/SynchronizedResource.kt | 51 ++ .../shared/resource/TransformingContainer.kt | 43 ++ .../shared/resource/TransformingResource.kt | 79 ++ .../r2/shared/resource/ZipContainer.kt | 132 +++- .../content}/ResourceContentExtractor.kt | 16 +- .../org/readium/r2/shared/util/Closeable.kt | 5 +- .../org/readium/r2/shared/util/CursorList.kt | 6 +- .../org/readium/r2/shared/util/Deprecated.kt | 6 +- .../java/org/readium/r2/shared/util/Either.kt | 4 +- .../java/org/readium/r2/shared/util/Href.kt | 168 ++-- .../org/readium/r2/shared/util/Language.kt | 5 +- .../readium/r2/shared/util/MapCompanion.kt | 16 +- .../org/readium/r2/shared/util/URITemplate.kt | 7 +- .../java/org/readium/r2/shared/util/Url.kt | 9 + .../archive/channel/ChannelZipContainer.kt | 79 +- .../util/archive/channel/HttpChannel.kt | 3 +- .../util/archive/channel/ResourceChannel.kt | 2 +- .../r2/shared/util/http/DefaultHttpClient.kt | 23 +- .../readium/r2/shared/util/http/HttpClient.kt | 6 +- .../r2/shared/util/http/HttpContainer.kt | 47 ++ .../r2/shared/util/http/HttpException.kt | 13 +- .../r2/shared/util/http/HttpFetcher.kt | 70 -- .../r2/shared/util/http/HttpHeaders.kt | 14 +- .../r2/shared/util/http/HttpRequest.kt | 6 +- .../r2/shared/util/http/HttpResource.kt | 36 +- .../shared/util/http/HttpResourceFactory.kt | 2 +- .../shared/util/http/HttpURLConnectionExt.kt | 23 + .../readium/r2/shared/util/http/MediaType.kt | 64 -- .../r2/shared/util/io/CountingInputStream.kt | 3 +- .../r2/shared/util/mediatype/Extensions.kt | 65 +- .../shared/util/mediatype/FormatRegistry.kt | 50 ++ .../r2/shared/util/mediatype/MediaType.kt | 455 ++++++----- .../shared/util/mediatype/MediaTypeHints.kt | 77 ++ .../util/mediatype/MediaTypeRetriever.kt | 290 ++----- .../shared/util/mediatype/MediaTypeSniffer.kt | 665 ++++++++++++++++ .../util/mediatype/MediaTypeSnifferContent.kt | 131 ++++ .../r2/shared/util/mediatype/Sniffer.kt | 485 ------------ .../shared/util/mediatype/SnifferContext.kt | 312 -------- .../readium/r2/shared/util/pdf/PdfDocument.kt | 14 +- .../r2/shared/util/tokenizer/TextTokenizer.kt | 13 +- .../java/org/readium/r2/shared/TestUtils.kt | 11 - .../readium/r2/shared/extensions/URLTest.kt | 25 +- .../r2/shared/fetcher/ContainerFetcherTest.kt | 207 ----- .../r2/shared/fetcher/FileFetcherTest.kt | 158 ---- .../r2/shared/parser/xml/XmlParserTest.kt | 8 +- .../shared/publication/AccessibilityTest.kt | 32 +- .../readium/r2/shared/publication/LinkTest.kt | 14 +- .../shared/publication/LocalizedStringTest.kt | 10 +- .../r2/shared/publication/LocatorTest.kt | 90 ++- .../r2/shared/publication/ManifestTest.kt | 92 ++- .../r2/shared/publication/MetadataTest.kt | 20 +- .../publication/PublicationCollectionTest.kt | 24 +- .../r2/shared/publication/PublicationTest.kt | 80 +- .../shared/publication/opds/PropertiesTest.kt | 11 +- .../AdeptFallbackContentProtectionTest.kt | 1 - .../LcpFallbackContentProtectionTest.kt | 4 +- .../publication/protection/TestContainer.kt | 23 +- .../publication/services/CoverServiceTest.kt | 19 +- .../services/LocatorServiceTest.kt | 29 +- .../services/PositionsServiceTest.kt | 12 +- .../HtmlResourceContentIteratorTest.kt | 38 +- .../BufferingResourceTest.kt | 19 +- .../shared/resource/DirectoryContainerTest.kt | 142 ++++ .../resource/ResourceInputStreamTest.kt | 26 +- .../ResourcePropertiesTest.kt} | 6 +- .../r2/shared/resource/ZipContainerTest.kt | 126 +-- .../readium/r2/shared/util/URITemplateTest.kt | 4 +- .../r2/shared/util/http/ProblemDetailsTest.kt | 5 +- .../util/mediatype/FormatRegistryTest.kt | 27 + .../util/mediatype/MediaTypeRetrieverTest.kt | 506 +++++++++++- .../r2/shared/util/mediatype/MediaTypeTest.kt | 303 ++++---- .../r2/shared/util/mediatype/SnifferTest.kt | 316 -------- .../util/tokenizer/IcuTextTokenizerTest.kt | 12 +- .../util/tokenizer/NaiveTextTokenizerTest.kt | 2 +- .../org/readium/r2/shared/fetcher/epub.epub | Bin 161291 -> 0 bytes .../org/readium/r2/shared/fetcher/text.txt | 1 - .../directory/subdirectory/hello.mp3 | 0 .../directory/subdirectory/text2.txt | 0 .../{fetcher => resource}/directory/text1.txt | 0 .../readium/r2/streamer/ParserAssetFactory.kt | 102 +-- .../readium/r2/streamer/PublicationFactory.kt | 46 +- .../r2/streamer/container/Container.kt | 57 +- .../r2/streamer/extensions/Container.kt | 46 ++ .../readium/r2/streamer/extensions/Fetcher.kt | 35 - .../readium/r2/streamer/extensions/Link.kt | 24 +- .../readium/r2/streamer/fetcher/Fetcher.kt | 7 +- .../r2/streamer/parser/PublicationParser.kt | 13 +- .../parser/audio/AudioLocatorService.kt | 9 +- .../r2/streamer/parser/audio/AudioParser.kt | 22 +- .../parser/epub/AccessibilityAdapter.kt | 14 +- .../streamer/parser/epub/EncryptionParser.kt | 7 +- .../streamer/parser/epub/EpubDeobfuscator.kt | 42 +- .../r2/streamer/parser/epub/EpubParser.kt | 70 +- .../parser/epub/EpubPositionsService.kt | 37 +- .../streamer/parser/epub/ManifestAdapter.kt | 8 +- .../streamer/parser/epub/MetadataAdapter.kt | 33 +- .../r2/streamer/parser/epub/MetadataParser.kt | 36 +- .../parser/epub/NavigationDocumentParser.kt | 34 +- .../r2/streamer/parser/epub/NcxParser.kt | 18 +- .../streamer/parser/epub/PackageDocument.kt | 20 +- .../parser/epub/PresentationAdapter.kt | 20 +- .../streamer/parser/epub/PropertyDataType.kt | 3 +- .../streamer/parser/epub/ResourceAdapter.kt | 21 +- .../r2/streamer/parser/epub/SmilParser.kt | 14 +- .../r2/streamer/parser/image/ImageParser.kt | 24 +- .../r2/streamer/parser/pdf/PdfParser.kt | 18 +- .../parser/pdf/PdfPositionsService.kt | 2 +- .../parser/readium/LcpdfPositionsService.kt | 23 +- .../parser/readium/ReadiumWebPubParser.kt | 25 +- .../readium/r2/streamer/server/Resources.kt | 5 +- .../org/readium/r2/streamer/server/Server.kt | 12 +- .../java/org/readium/r2/streamer/TestUtils.kt | 4 +- .../streamer/extensions/ContainerEntryTest.kt | 73 ++ .../r2/streamer/extensions/LinkTest.kt | 54 -- .../parser/audio/AudioLocatorServiceTest.kt | 77 +- .../parser/epub/EncryptionParserTest.kt | 10 +- .../parser/epub/EpubDeobfuscatorTest.kt | 74 +- .../parser/epub/EpubPositionsServiceTest.kt | 170 +++-- .../r2/streamer/parser/epub/MetadataTest.kt | 60 +- .../epub/NavigationDocumentParserTest.kt | 11 +- .../r2/streamer/parser/epub/NcxParserTest.kt | 11 +- .../parser/epub/PackageDocumentTest.kt | 64 +- .../parser/epub/PropertyDataTypeTest.kt | 8 +- .../streamer/parser/image/ImageParserTest.kt | 32 +- settings.gradle.kts | 2 +- .../org/readium/r2/testapp/Application.kt | 10 +- .../org/readium/r2/testapp/MainActivity.kt | 4 +- .../readium/r2/testapp/PublicationError.kt | 20 +- .../java/org/readium/r2/testapp/Readium.kt | 34 +- .../r2/testapp/bookshelf/BookRepository.kt | 26 +- .../r2/testapp/bookshelf/BookshelfAdapter.kt | 5 +- .../r2/testapp/bookshelf/BookshelfFragment.kt | 14 +- .../testapp/bookshelf/BookshelfViewModel.kt | 5 +- .../catalogs/CatalogFeedListAdapter.kt | 1 - .../catalogs/CatalogFeedListFragment.kt | 5 +- .../catalogs/CatalogFeedListViewModel.kt | 4 +- .../r2/testapp/catalogs/CatalogFragment.kt | 1 - .../r2/testapp/catalogs/CatalogViewModel.kt | 16 +- .../r2/testapp/catalogs/GroupAdapter.kt | 4 +- .../r2/testapp/catalogs/NavigationAdapter.kt | 4 +- .../r2/testapp/catalogs/PublicationAdapter.kt | 1 - .../catalogs/PublicationDetailFragment.kt | 12 +- .../org/readium/r2/testapp/db/BooksDao.kt | 16 +- .../org/readium/r2/testapp/db/CatalogDao.kt | 4 +- .../readium/r2/testapp/domain/model/Book.kt | 12 +- .../r2/testapp/domain/model/Bookmark.kt | 25 +- .../r2/testapp/domain/model/Catalog.kt | 10 +- .../r2/testapp/domain/model/Highlight.kt | 25 +- .../r2/testapp/drm/DrmManagementFragment.kt | 8 +- .../r2/testapp/drm/LcpManagementViewModel.kt | 9 +- .../testapp/opds/GridAutoFitLayoutManager.kt | 13 +- .../r2/testapp/outline/BookmarksFragment.kt | 20 +- .../r2/testapp/outline/HighlightsFragment.kt | 24 +- .../r2/testapp/outline/NavigationFragment.kt | 22 +- .../r2/testapp/outline/OutlineContract.kt | 4 +- .../r2/testapp/outline/OutlineFragment.kt | 14 +- .../r2/testapp/reader/AudioReaderFragment.kt | 5 +- .../r2/testapp/reader/BaseReaderFragment.kt | 8 +- .../r2/testapp/reader/EpubReaderFragment.kt | 25 +- .../FullscreenReaderActivityDelegate.kt | 13 +- .../r2/testapp/reader/ImageReaderFragment.kt | 7 +- .../readium/r2/testapp/reader/MediaService.kt | 6 +- .../r2/testapp/reader/PdfReaderFragment.kt | 9 +- .../r2/testapp/reader/ReaderActivity.kt | 15 +- .../testapp/reader/ReaderActivityContract.kt | 3 +- .../r2/testapp/reader/ReaderInitData.kt | 14 +- .../r2/testapp/reader/ReaderRepository.kt | 39 +- .../r2/testapp/reader/ReaderViewModel.kt | 14 +- .../r2/testapp/reader/VisualReaderFragment.kt | 14 +- .../reader/preferences/PreferencesManagers.kt | 6 +- .../reader/preferences/UserPreferences.kt | 16 +- .../preferences/UserPreferencesViewModel.kt | 12 +- .../r2/testapp/reader/tts/TtsControls.kt | 24 +- .../r2/testapp/reader/tts/TtsViewModel.kt | 7 +- .../r2/testapp/search/SearchResultAdapter.kt | 4 +- .../r2/testapp/shared/views/Preferences.kt | 15 +- .../r2/testapp/utils/ContentResolverUtil.kt | 5 +- .../r2/testapp/utils/SectionDecoration.kt | 17 +- .../r2/testapp/utils/SystemUiManagement.kt | 4 +- .../r2/testapp/utils/compose/ColorPicker.kt | 2 +- .../ComposeBottomSheetDialogFragment.kt | 6 +- .../utils/compose/DropdownMenuButton.kt | 2 +- .../r2/testapp/utils/compose/ToggleButton.kt | 7 +- .../r2/testapp/utils/extensions/File.kt | 46 +- .../r2/testapp/utils/extensions/Uri.kt | 32 +- test-app/src/main/res/values/arrays.xml | 6 +- 392 files changed, 9585 insertions(+), 6122 deletions(-) rename readium/navigator/src/main/java/org/readium/r2/navigator/cbz/{Deprecated.kt => R2CbzActivity.kt} (71%) rename readium/navigator/src/main/java/org/readium/r2/navigator/divina/{Deprecated.kt => R2DiViNaActivity.kt} (90%) rename readium/navigator/src/main/java/org/readium/r2/navigator/pdf/{Deprecated.kt => R2PdfActivity.kt} (74%) delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationServicesHolder.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/FallbackResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/LazyResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/MediaTypeExt.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/RoutingContainer.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/SynchronizedResource.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingContainer.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt rename readium/shared/src/main/java/org/readium/r2/shared/{fetcher => resource/content}/ResourceContentExtractor.kt (73%) create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpContainer.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpURLConnectionExt.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/FormatRegistry.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeHints.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSniffer.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSnifferContent.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt delete mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt delete mode 100644 readium/shared/src/test/java/org/readium/r2/shared/fetcher/ContainerFetcherTest.kt delete mode 100644 readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt rename readium/shared/src/test/java/org/readium/r2/shared/{fetcher => resource}/BufferingResourceTest.kt (87%) create mode 100644 readium/shared/src/test/java/org/readium/r2/shared/resource/DirectoryContainerTest.kt rename readium/shared/src/test/java/org/readium/r2/shared/{publication/archive/PropertiesTest.kt => resource/ResourcePropertiesTest.kt} (93%) create mode 100644 readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/FormatRegistryTest.kt delete mode 100644 readium/shared/src/test/java/org/readium/r2/shared/util/mediatype/SnifferTest.kt delete mode 100644 readium/shared/src/test/resources/org/readium/r2/shared/fetcher/epub.epub delete mode 100644 readium/shared/src/test/resources/org/readium/r2/shared/fetcher/text.txt rename readium/shared/src/test/resources/org/readium/r2/shared/{fetcher => resource}/directory/subdirectory/hello.mp3 (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{fetcher => resource}/directory/subdirectory/text2.txt (100%) rename readium/shared/src/test/resources/org/readium/r2/shared/{fetcher => resource}/directory/text1.txt (100%) create mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Container.kt delete mode 100644 readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt create mode 100644 readium/streamer/src/test/java/org/readium/r2/streamer/extensions/ContainerEntryTest.kt delete mode 100644 readium/streamer/src/test/java/org/readium/r2/streamer/extensions/LinkTest.kt diff --git a/.gitignore b/.gitignore index 3070fa2ac9..972d91fb72 100644 --- a/.gitignore +++ b/.gitignore @@ -82,4 +82,5 @@ lint/reports/ docs/readium docs/index.md docs/package-list -site/ \ No newline at end of file +site/ +androidTestResultsUserPreferences.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 895e903e9f..3ecffd651d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,11 @@ All notable changes to this project will be documented in this file. Take a look * Readium resources are now prefixed with `readium_`. Take care of updating any overridden resource by following [the migration guide](docs/migration-guide.md#300). +#### Shared + +* `Publication.localizedTitle` is nullable, as we cannot guarantee that all publication sources offer a title. +* The `MediaType` sniffing helpers are deprecated in favor of `MediaTypeRetriever` (for media type and file extension hints and raw content) and `AssetRetriever` (for URLs). + #### Navigator * `EpubNavigatorFragment.firstVisibleElementLocator()` now returns the first *block* element that is visible on the screen, even if it starts on previous pages. @@ -39,6 +44,10 @@ All notable changes to this project will be documented in this file. Take a look * All the navigator `Activity` are deprecated in favor of the `Fragment` variants. +#### Streamer + +* The `Fetcher` interface was deprecated in favor of the `Container` one in `readium-shared`. + ### Fixed #### Navigator diff --git a/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt b/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt index baf4429263..9369c2d827 100644 --- a/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt +++ b/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt @@ -19,9 +19,10 @@ import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.md5 import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.pdf.PdfDocument import org.readium.r2.shared.util.pdf.PdfDocumentFactory +import org.readium.r2.shared.util.toFile import org.readium.r2.shared.util.use import timber.log.Timber @@ -87,26 +88,29 @@ public class PdfiumDocumentFactory(context: Context) : PdfDocumentFactory { init { @@ -40,6 +40,6 @@ public data class PdfiumPreferences( fit = other.fit ?: fit, pageSpacing = other.pageSpacing ?: pageSpacing, readingProgression = other.readingProgression ?: readingProgression, - scrollAxis = other.scrollAxis ?: scrollAxis, + scrollAxis = other.scrollAxis ?: scrollAxis ) } diff --git a/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesEditor.kt b/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesEditor.kt index 1008054e0f..39cdd61240 100644 --- a/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesEditor.kt +++ b/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesEditor.kt @@ -22,7 +22,7 @@ import org.readium.r2.shared.publication.Metadata public class PdfiumPreferencesEditor internal constructor( initialPreferences: PdfiumPreferences, publicationMetadata: Metadata, - defaults: PdfiumDefaults, + defaults: PdfiumDefaults ) : PreferencesEditor { private data class State( @@ -55,7 +55,7 @@ public class PdfiumPreferencesEditor internal constructor( getEffectiveValue = { state.settings.fit }, getIsEffective = { true }, updateValue = { value -> updateValues { it.copy(fit = value) } }, - supportedValues = listOf(Fit.CONTAIN, Fit.WIDTH), + supportedValues = listOf(Fit.CONTAIN, Fit.WIDTH) ) /** @@ -69,7 +69,7 @@ public class PdfiumPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(pageSpacing = value) } }, supportedRange = 0.0..50.0, progressionStrategy = DoubleIncrement(5.0), - valueFormatter = { "${it.format(1)} dp" }, + valueFormatter = { "${it.format(1)} dp" } ) /** @@ -81,7 +81,7 @@ public class PdfiumPreferencesEditor internal constructor( getEffectiveValue = { state.settings.readingProgression }, getIsEffective = { true }, updateValue = { value -> updateValues { it.copy(readingProgression = value) } }, - supportedValues = listOf(ReadingProgression.LTR, ReadingProgression.RTL), + supportedValues = listOf(ReadingProgression.LTR, ReadingProgression.RTL) ) /** @@ -93,7 +93,7 @@ public class PdfiumPreferencesEditor internal constructor( getEffectiveValue = { state.settings.scrollAxis }, getIsEffective = { true }, updateValue = { value -> updateValues { it.copy(scrollAxis = value) } }, - supportedValues = listOf(Axis.VERTICAL, Axis.HORIZONTAL), + supportedValues = listOf(Axis.VERTICAL, Axis.HORIZONTAL) ) private fun updateValues(updater: (PdfiumPreferences) -> PdfiumPreferences) { diff --git a/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesFilters.kt b/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesFilters.kt index 80c5a1f0b2..c106dec929 100644 --- a/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesFilters.kt +++ b/readium/adapters/pdfium/pdfium-navigator/src/main/java/org/readium/adapters/pdfium/navigator/PdfiumPreferencesFilters.kt @@ -17,7 +17,7 @@ public object PdfiumSharedPreferencesFilter : PreferencesFilter Unit = { Timber.e(it) } ) : DataProvider { diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDefaults.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDefaults.kt index 3720958af9..6365138cf2 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDefaults.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDefaults.kt @@ -23,5 +23,5 @@ public data class PsPdfKitDefaults( val pageSpacing: Double? = null, val readingProgression: ReadingProgression? = null, val scroll: Boolean? = null, - val spread: Spread? = null, + val spread: Spread? = null ) diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt index 2c59bfb82e..3a9e9cc8f2 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitDocumentFragment.kt @@ -123,8 +123,11 @@ internal class PsPdfKitDocumentFragment( .pagePadding(settings.pageSpacing.roundToInt()) .restoreLastViewedPage(false) .scrollDirection( - if (!settings.scroll) PageScrollDirection.HORIZONTAL - else settings.scrollAxis.scrollDirection + if (!settings.scroll) { + PageScrollDirection.HORIZONTAL + } else { + settings.scrollAxis.scrollDirection + } ) .scrollMode(settings.scroll.scrollMode) .scrollOnEdgeTapEnabled(false) @@ -185,7 +188,9 @@ internal class PsPdfKitDocumentFragment( if ( pagePosition == null || clickedAnnotation is LinkAnnotation || clickedAnnotation is SoundAnnotation - ) return false + ) { + return false + } pdfFragment.viewProjection.toViewPoint(pagePosition, pageIndex) return listener?.onTap(pagePosition) ?: false diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitEngineProvider.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitEngineProvider.kt index 7bbe6eb2e9..33414ca505 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitEngineProvider.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitEngineProvider.kt @@ -34,7 +34,6 @@ public class PsPdfKitEngineProvider( override suspend fun createDocumentFragment( input: PdfDocumentFragmentInput ): PdfDocumentFragment { - val publication = input.publication val document = PsPdfKitDocumentFactory(context) .cachedIn(publication) diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferences.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferences.kt index 4f8910a1a1..3a793387c0 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferences.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferences.kt @@ -30,7 +30,7 @@ public data class PsPdfKitPreferences( val readingProgression: ReadingProgression? = null, val scroll: Boolean? = null, val scrollAxis: Axis? = null, - val spread: Spread? = null, + val spread: Spread? = null ) : Configurable.Preferences { init { @@ -46,6 +46,6 @@ public data class PsPdfKitPreferences( readingProgression = other.readingProgression ?: readingProgression, scroll = other.scroll ?: scroll, scrollAxis = other.scrollAxis ?: scrollAxis, - spread = other.spread ?: spread, + spread = other.spread ?: spread ) } diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesEditor.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesEditor.kt index 4791abbf23..c56496670b 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesEditor.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesEditor.kt @@ -33,7 +33,7 @@ import org.readium.r2.shared.publication.Metadata public class PsPdfKitPreferencesEditor internal constructor( initialPreferences: PsPdfKitPreferences, publicationMetadata: Metadata, - defaults: PsPdfKitDefaults, + defaults: PsPdfKitDefaults ) : PreferencesEditor { private data class State( @@ -66,7 +66,7 @@ public class PsPdfKitPreferencesEditor internal constructor( getEffectiveValue = { state.settings.fit }, getIsEffective = { true }, updateValue = { value -> updateValues { it.copy(fit = value) } }, - supportedValues = listOf(Fit.CONTAIN, Fit.WIDTH), + supportedValues = listOf(Fit.CONTAIN, Fit.WIDTH) ) /** @@ -81,7 +81,7 @@ public class PsPdfKitPreferencesEditor internal constructor( getValue = { preferences.offsetFirstPage }, getEffectiveValue = { state.settings.offsetFirstPage }, getIsEffective = { !state.settings.scroll && state.settings.spread != Spread.NEVER }, - updateValue = { value -> updateValues { it.copy(offsetFirstPage = value) } }, + updateValue = { value -> updateValues { it.copy(offsetFirstPage = value) } } ) /** @@ -95,7 +95,7 @@ public class PsPdfKitPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(pageSpacing = value) } }, supportedRange = 0.0..50.0, progressionStrategy = DoubleIncrement(5.0), - valueFormatter = { "${it.format(1)} dp" }, + valueFormatter = { "${it.format(1)} dp" } ) /** @@ -107,7 +107,7 @@ public class PsPdfKitPreferencesEditor internal constructor( getEffectiveValue = { state.settings.readingProgression }, getIsEffective = { true }, updateValue = { value -> updateValues { it.copy(readingProgression = value) } }, - supportedValues = listOf(ReadingProgression.LTR, ReadingProgression.RTL), + supportedValues = listOf(ReadingProgression.LTR, ReadingProgression.RTL) ) /** @@ -118,7 +118,7 @@ public class PsPdfKitPreferencesEditor internal constructor( getValue = { preferences.scroll }, getEffectiveValue = { state.settings.scroll }, getIsEffective = { true }, - updateValue = { value -> updateValues { it.copy(scroll = value) } }, + updateValue = { value -> updateValues { it.copy(scroll = value) } } ) /** @@ -132,7 +132,7 @@ public class PsPdfKitPreferencesEditor internal constructor( getEffectiveValue = { state.settings.scrollAxis }, getIsEffective = { state.settings.scroll }, updateValue = { value -> updateValues { it.copy(scrollAxis = value) } }, - supportedValues = listOf(Axis.VERTICAL, Axis.HORIZONTAL), + supportedValues = listOf(Axis.VERTICAL, Axis.HORIZONTAL) ) /** @@ -146,7 +146,7 @@ public class PsPdfKitPreferencesEditor internal constructor( getEffectiveValue = { state.settings.spread }, getIsEffective = { !state.settings.scroll }, updateValue = { value -> updateValues { it.copy(spread = value) } }, - supportedValues = listOf(Spread.AUTO, Spread.NEVER, Spread.ALWAYS), + supportedValues = listOf(Spread.AUTO, Spread.NEVER, Spread.ALWAYS) ) private fun updateValues(updater: (PsPdfKitPreferences) -> PsPdfKitPreferences) { diff --git a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesFilters.kt b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesFilters.kt index 9a681699bc..6037094664 100644 --- a/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesFilters.kt +++ b/readium/adapters/pspdfkit/pspdfkit-navigator/src/main/java/org/readium/adapters/pspdfkit/navigator/PsPdfKitPreferencesFilters.kt @@ -19,7 +19,7 @@ public object PsPdfKitSharedPreferencesFilter : PreferencesFilter - get() = document.links(LicenseDocument.Rel.support) + get() = document.links(LicenseDocument.Rel.Support) /** * URI of the license provider. @@ -100,22 +100,42 @@ public interface LcpAuthenticating { } } -@Deprecated("Renamed to `LcpAuthenticating`", replaceWith = ReplaceWith("LcpAuthenticating"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpAuthenticating`", + replaceWith = ReplaceWith("LcpAuthenticating"), + level = DeprecationLevel.ERROR +) public typealias LCPAuthenticating = LcpAuthenticating @Deprecated("Not used anymore", level = DeprecationLevel.ERROR) public interface LCPAuthenticationDelegate -@Deprecated("Renamed to `LcpAuthenticating.AuthenticationReason`", replaceWith = ReplaceWith("LcpAuthenticating.AuthenticationReason"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpAuthenticating.AuthenticationReason`", + replaceWith = ReplaceWith("LcpAuthenticating.AuthenticationReason"), + level = DeprecationLevel.ERROR +) public typealias LCPAuthenticationReason = LcpAuthenticating.AuthenticationReason -@Deprecated("Renamed to `LcpAuthenticating.AuthenticatedLicense`", replaceWith = ReplaceWith("LcpAuthenticating.AuthenticatedLicense"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpAuthenticating.AuthenticatedLicense`", + replaceWith = ReplaceWith("LcpAuthenticating.AuthenticatedLicense"), + level = DeprecationLevel.ERROR +) public typealias LCPAuthenticatedLicense = LcpAuthenticating.AuthenticatedLicense -@Deprecated("Renamed to `PassphraseNotFound`", replaceWith = ReplaceWith("PassphraseNotFound"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `PassphraseNotFound`", + replaceWith = ReplaceWith("PassphraseNotFound"), + level = DeprecationLevel.ERROR +) public val LcpAuthenticating.AuthenticationReason.Companion.passphraseNotFound: LcpAuthenticating.AuthenticationReason get() = LcpAuthenticating.AuthenticationReason.PassphraseNotFound -@Deprecated("Renamed to `InvalidPassphrase`", replaceWith = ReplaceWith("InvalidPassphrase"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `InvalidPassphrase`", + replaceWith = ReplaceWith("InvalidPassphrase"), + level = DeprecationLevel.ERROR +) public val LcpAuthenticating.AuthenticationReason.Companion.invalidPassphrase: LcpAuthenticating.AuthenticationReason get() = LcpAuthenticating.AuthenticationReason.InvalidPassphrase diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt index d756b7caa4..9b713ab0fe 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt @@ -9,26 +9,28 @@ package org.readium.r2.lcp import org.readium.r2.lcp.auth.LcpPassphraseAuthentication import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.asset.AssetRetriever +import org.readium.r2.shared.asset.AssetType import org.readium.r2.shared.error.ThrowableError import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.error.getOrElse -import org.readium.r2.shared.fetcher.ContainerFetcher -import org.readium.r2.shared.fetcher.TransformingFetcher import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.encryption.encryption +import org.readium.r2.shared.publication.flatten import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.publication.services.contentProtectionServiceFactory import org.readium.r2.shared.resource.ArchiveFactory import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceFactory +import org.readium.r2.shared.resource.TransformingContainer import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.util.toFile internal class LcpContentProtection( private val lcpService: LcpService, private val authentication: LcpAuthenticating, - private val mediaTypeRetriever: MediaTypeRetriever, - private val resourceFactory: ResourceFactory, - private val archiveFactory: ArchiveFactory + private val assetRetriever: AssetRetriever ) : ContentProtection { override val scheme: ContentProtection.Scheme = @@ -71,32 +73,43 @@ internal class LcpContentProtection( ?.let { LcpPassphraseAuthentication(it, fallback = this.authentication) } ?: this.authentication - val file = (asset as? Asset.Resource)?.resource?.file - ?: (asset as? Asset.Container)?.container?.file + val file = (asset as? Asset.Resource)?.resource?.source?.toFile() + ?: (asset as? Asset.Container)?.container?.source?.toFile() return file // This is less restrictive with regard to network availability. - ?.let { lcpService.retrieveLicense(it, asset.mediaType, authentication, allowUserInteraction, sender) } + ?.let { + lcpService.retrieveLicense( + it, + asset.mediaType, + authentication, + allowUserInteraction, + sender + ) + } ?: lcpService.retrieveLicense(asset, authentication, allowUserInteraction, sender) } private fun createResultAsset( asset: Asset.Container, - license: Try, + license: Try ): Try { val serviceFactory = LcpContentProtectionService .createFactory(license.getOrNull(), license.failureOrNull()) - val fetcher = TransformingFetcher( - ContainerFetcher(asset.container, mediaTypeRetriever), - LcpDecryptor(license.getOrNull())::transform - ) + val decryptor = LcpDecryptor(license.getOrNull()) + + val container = TransformingContainer(asset.container, decryptor::transform) val protectedFile = ContentProtection.Asset( - name = asset.name, mediaType = asset.mediaType, - fetcher = fetcher, + container = container, onCreatePublication = { + decryptor.encryptionData = (manifest.readingOrder + manifest.resources + manifest.links) + .flatten() + .mapNotNull { it.properties.encryption?.let { enc -> it.href to enc } } + .toMap() + servicesBuilder.contentProtectionServiceFactory = serviceFactory } ) @@ -131,30 +144,23 @@ internal class LcpContentProtection( ) } - val link = checkNotNull(licenseDoc.link(LicenseDocument.Rel.publication)) + val link = checkNotNull(licenseDoc.link(LicenseDocument.Rel.Publication)) val url = Url(link.url.toString()) ?: return Try.failure( Publication.OpeningException.ParsingFailed( ThrowableError( - LcpException.Parsing.Url(rel = LicenseDocument.Rel.publication.value) + LcpException.Parsing.Url(rel = LicenseDocument.Rel.Publication.value) ) ) ) - val resource = resourceFactory.create(url) - .getOrElse { return Try.failure(it.wrap()) } - - val container = archiveFactory.create(resource, password = null) - .getOrElse { return Try.failure(it.wrap()) } - - val publicationAsset = Asset.Container( - url.filename, - link.mediaType, - false, - container + return assetRetriever.retrieve( + url, + mediaType = link.mediaType, + assetType = AssetType.Archive ) - - return createResultAsset(publicationAsset, license) + .mapFailure { Publication.OpeningException.ParsingFailed(it) } + .flatMap { createResultAsset(it as Asset.Container, license) } } private fun ResourceFactory.Error.wrap(): Publication.OpeningException = diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt index 703db1bbd8..5c91e20432 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt @@ -16,29 +16,49 @@ import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.coerceFirstNonNegative import org.readium.r2.shared.extensions.inflate import org.readium.r2.shared.extensions.requireLengthFitInt -import org.readium.r2.shared.fetcher.* -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.encryption.encryption +import org.readium.r2.shared.publication.encryption.Encryption +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.FailureResource import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.TransformingResource +import org.readium.r2.shared.resource.flatMap +import org.readium.r2.shared.resource.flatMapCatching +import org.readium.r2.shared.resource.mapCatching +import org.readium.r2.shared.util.Url /** * Decrypts a resource protected with LCP. */ -internal class LcpDecryptor(val license: LcpLicense?) { - - fun transform(resource: Fetcher.Resource): Fetcher.Resource = LazyResource { - // Checks if the resource is encrypted and whether the encryption schemes of the resource - // and the DRM license are the same. - val link = resource.link() - val encryption = link.properties.encryption - if (encryption == null || encryption.scheme != "http://readium.org/2014/01/lcp") - return@LazyResource resource - - when { - license == null -> FailureResource(link, Resource.Exception.Forbidden()) - link.isDeflated || !link.isCbcEncrypted -> FullLcpResource(resource, license) - else -> CbcLcpResource(resource, license) +internal class LcpDecryptor( + val license: LcpLicense?, + var encryptionData: Map = emptyMap() +) { + + fun transform(resource: Resource): Resource { + if (resource !is Container.Entry) { + return resource + } + + return resource.flatMap { + val encryption = encryptionData[resource.path] + + // Checks if the resource is encrypted and whether the encryption schemes of the resource + // and the DRM license are the same. + if (encryption == null || encryption.scheme != "http://readium.org/2014/01/lcp") { + return@flatMap resource + } + + when { + license == null -> FailureResource(Resource.Exception.Forbidden()) + encryption.isDeflated || !encryption.isCbcEncrypted -> FullLcpResource( + resource, + encryption, + license + ) + + else -> CbcLcpResource(resource, encryption, license) + } } } @@ -49,16 +69,16 @@ internal class LcpDecryptor(val license: LcpLicense?) { * resource, for example when the resource is deflated before encryption. */ private class FullLcpResource( - resource: Fetcher.Resource, + resource: Resource, + private val encryption: Encryption, private val license: LcpLicense ) : TransformingResource(resource) { override suspend fun transform(data: ResourceTry): ResourceTry = - license.decryptFully(data, resource.link().isDeflated) + license.decryptFully(data, encryption.isDeflated) override suspend fun length(): ResourceTry = - resource.link().properties.encryption?.originalLength - ?.let { Try.success(it) } + encryption.originalLength?.let { Try.success(it) } ?: super.length() } @@ -68,9 +88,12 @@ internal class LcpDecryptor(val license: LcpLicense?) { * Supports random access for byte range requests, but the resource MUST NOT be deflated. */ private class CbcLcpResource( - private val resource: Fetcher.Resource, + private val resource: Resource, + private val encryption: Encryption, private val license: LcpLicense - ) : Fetcher.Resource { + ) : Resource by resource { + + override val source: Url? = null private class Cache( var startIndex: Int? = null, @@ -90,15 +113,13 @@ internal class LcpDecryptor(val license: LcpLicense?) { */ private val _cache: Cache = Cache() - override suspend fun link(): Link = resource.link() - /** Plain text size. */ override suspend fun length(): ResourceTry { - if (::_length.isInitialized) + if (::_length.isInitialized) { return _length + } - _length = resource.link().properties.encryption?.originalLength - ?.let { Try.success(it) } + _length = encryption.originalLength?.let { Try.success(it) } ?: lengthFromPadding() return _length @@ -114,7 +135,12 @@ internal class LcpDecryptor(val license: LcpLicense?) { resource.read(readOffset..length) .mapCatching { bytes -> val decryptedBytes = license.decrypt(bytes) - .getOrElse { throw Exception("Can't decrypt trailing size of CBC-encrypted stream", it) } + .getOrElse { + throw Exception( + "Can't decrypt trailing size of CBC-encrypted stream", + it + ) + } check(decryptedBytes.size == AES_BLOCK_SIZE) return@mapCatching length - @@ -124,16 +150,18 @@ internal class LcpDecryptor(val license: LcpLicense?) { } override suspend fun read(range: LongRange?): ResourceTry { - if (range == null) + if (range == null) { return license.decryptFully(resource.read(), isDeflated = false) + } @Suppress("NAME_SHADOWING") val range = range .coerceFirstNonNegative() .requireLengthFitInt() - if (range.isEmpty()) + if (range.isEmpty()) { return Try.success(ByteArray(0)) + } return resource.length().flatMapCatching { encryptedLength -> // encrypted data is shifted by AES_BLOCK_SIZE because of IV and @@ -150,7 +178,12 @@ internal class LcpDecryptor(val license: LcpLicense?) { } val bytes = license.decrypt(encryptedData) - .getOrElse { throw IOException("Can't decrypt the content at: ${link().href}", it) } + .getOrElse { + throw IOException( + "Can't decrypt the content for resource with key: ${resource.source}", + it + ) + } // exclude the bytes added to match a multiple of AES_BLOCK_SIZE val sliceStart = (range.first - encryptedStart).toInt() @@ -159,12 +192,13 @@ internal class LcpDecryptor(val license: LcpLicense?) { val lastBlockRead = encryptedLength - encryptedEndExclusive <= AES_BLOCK_SIZE val rangeLength = - if (lastBlockRead) - // use decrypted length to ensure range.last doesn't exceed decrypted length - 1 + if (lastBlockRead) { + // use decrypted length to ensure range.last doesn't exceed decrypted length - 1 range.last.coerceAtMost(length().getOrThrow() - 1) - range.first + 1 - else - // the last block won't be read, so there's no need to compute length + } else { + // the last block won't be read, so there's no need to compute length range.last - range.first + 1 + } // keep only enough bytes to fit the length corrected request in order to never include padding val sliceEnd = sliceStart + rangeLength.toInt() @@ -192,8 +226,6 @@ internal class LcpDecryptor(val license: LcpLicense?) { } } - override suspend fun close() = resource.close() - companion object { private const val AES_BLOCK_SIZE = 16 // bytes } @@ -206,8 +238,9 @@ private suspend fun LcpLicense.decryptFully(data: ResourceTry, isDefl var bytes = decrypt(encryptedData) .getOrElse { throw Exception("Failed to decrypt the resource", it) } - if (bytes.isEmpty()) + if (bytes.isEmpty()) { throw IllegalStateException("Lcp.nativeDecrypt returned an empty ByteArray") + } // Removes the padding. val padding = bytes.last().toInt() @@ -221,11 +254,11 @@ private suspend fun LcpLicense.decryptFully(data: ResourceTry, isDefl bytes } -private val Link.isDeflated: Boolean get() = - properties.encryption?.compression?.lowercase(java.util.Locale.ROOT) == "deflate" +private val Encryption.isDeflated: Boolean get() = + compression?.lowercase(java.util.Locale.ROOT) == "deflate" -private val Link.isCbcEncrypted: Boolean get() = - properties.encryption?.algorithm == "http://www.w3.org/2001/04/xmlenc#aes256-cbc" +private val Encryption.isCbcEncrypted: Boolean get() = + algorithm == "http://www.w3.org/2001/04/xmlenc#aes256-cbc" private fun Long.ceilMultipleOf(divisor: Long) = divisor * (this / divisor + if (this % divisor == 0L) 0 else 1) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt index f26674ed15..4f6b4b8772 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt @@ -13,14 +13,13 @@ import kotlin.math.ceil import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.coerceIn -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.mapCatching import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.mapCatching import org.readium.r2.shared.util.use import timber.log.Timber internal suspend fun Publication.checkDecryption() { - checkResourcesAreReadableInOneBlock(this) checkLengthComputationIsCorrect(this) @@ -70,7 +69,10 @@ internal suspend fun checkAllResourcesAreReadableByChunks(publication: Publicati for (chunkSize in listOf(4096L, 2050L)) { publication.get(link).use { resource -> resource.readByChunks(chunkSize, groundTruth).onFailure { - throw IllegalStateException("failed to read ${link.href} by chunks of size $chunkSize", it) + throw IllegalStateException( + "failed to read ${link.href} by chunks of size $chunkSize", + it + ) } } } @@ -86,20 +88,24 @@ internal suspend fun checkExceedingRangesAreAllowed(publication: Publication) { val length = resource.length().getOrThrow() val fullTruth = resource.read().getOrThrow() for ( - range in listOf( - 0 until length + 100, - 0 until length + 2048, - length - 500 until length + 200, - length until length + 5028, - length + 200 until length + 500 - ) + range in listOf( + 0 until length + 100, + 0 until length + 2048, + length - 500 until length + 200, + length until length + 5028, + length + 200 until length + 500 + ) ) { resource.read(range) .onFailure { - throw IllegalStateException("unable to decrypt range $range from ${link.href}") + throw IllegalStateException( + "unable to decrypt range $range from ${link.href}" + ) }.onSuccess { val coercedRange = range.coerceIn(0L until fullTruth.size) - val truth = fullTruth.sliceArray(coercedRange.first.toInt()..coercedRange.last.toInt()) + val truth = fullTruth.sliceArray( + coercedRange.first.toInt()..coercedRange.last.toInt() + ) check(it.contentEquals(truth)) { Timber.d("decrypted length: ${it.size}") Timber.d("expected length: ${truth.size}") @@ -111,7 +117,7 @@ internal suspend fun checkExceedingRangesAreAllowed(publication: Publication) { } } -internal suspend fun Fetcher.Resource.readByChunks( +internal suspend fun Resource.readByChunks( chunkSize: Long, groundTruth: ByteArray, shuffle: Boolean = true @@ -132,13 +138,18 @@ internal suspend fun Fetcher.Resource.readByChunks( blocks.forEach { Timber.d("block index ${it.first}: ${it.second}") val decryptedBytes = read(it.second).getOrElse { error -> - throw IllegalStateException("unable to decrypt chunk ${it.second} from ${link().href}", error) + throw IllegalStateException( + "unable to decrypt chunk ${it.second} from $source", + error + ) } check(decryptedBytes.isNotEmpty()) { "empty decrypted bytearray" } check(decryptedBytes.contentEquals(groundTruth.sliceArray(it.second.map(Long::toInt)))) { Timber.d("decrypted length: ${decryptedBytes.size}") - Timber.d("expected length: ${groundTruth.sliceArray(it.second.map(Long::toInt)).size}") - "decrypted chunk ${it.first}: ${it.second} seems to be wrong in ${link().href}" + Timber.d( + "expected length: ${groundTruth.sliceArray(it.second.map(Long::toInt)).size}" + ) + "decrypted chunk ${it.first}: ${it.second} seems to be wrong in $source" } Pair(it.first, decryptedBytes) } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpException.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpException.kt index c5f6fdd495..13c2e59801 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpException.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpException.kt @@ -18,7 +18,12 @@ public sealed class LcpException( quantity: Int? = null, cause: Throwable? = null ) : UserException(userMessageId, quantity, *args, cause = cause) { - protected constructor(@StringRes userMessageId: Int, vararg args: Any, cause: Throwable? = null) : this(userMessageId, *args, quantity = null, cause = cause) + protected constructor(@StringRes userMessageId: Int, vararg args: Any, cause: Throwable? = null) : this( + userMessageId, + *args, + quantity = null, + cause = cause + ) protected constructor( @PluralsRes userMessageId: Int, quantity: Int, @@ -27,25 +32,36 @@ public sealed class LcpException( ) : this(userMessageId, *args, quantity = quantity, cause = cause) /** The interaction is not available with this License. */ - public object LicenseInteractionNotAvailable : LcpException(R.string.readium_lcp_exception_license_interaction_not_available) + public object LicenseInteractionNotAvailable : LcpException( + R.string.readium_lcp_exception_license_interaction_not_available + ) /** This License's profile is not supported by liblcp. */ - public object LicenseProfileNotSupported : LcpException(R.string.readium_lcp_exception_license_profile_not_supported) + public object LicenseProfileNotSupported : LcpException( + R.string.readium_lcp_exception_license_profile_not_supported + ) /** Failed to retrieve the Certificate Revocation List. */ public object CrlFetching : LcpException(R.string.readium_lcp_exception_crl_fetching) /** A network request failed with the given exception. */ - public class Network(override val cause: Throwable?) : LcpException(R.string.readium_lcp_exception_network, cause = cause) + public class Network(override val cause: Throwable?) : LcpException( + R.string.readium_lcp_exception_network, + cause = cause + ) /** * An unexpected LCP exception occurred. Please post an issue on r2-lcp-kotlin with the error * message and how to reproduce it. */ - public class Runtime(override val message: String) : LcpException(R.string.readium_lcp_exception_runtime) + public class Runtime(override val message: String) : LcpException( + R.string.readium_lcp_exception_runtime + ) /** An unknown low-level exception was reported. */ - public class Unknown(override val cause: Throwable?) : LcpException(R.string.readium_lcp_exception_unknown) + public class Unknown(override val cause: Throwable?) : LcpException( + R.string.readium_lcp_exception_unknown + ) /** * Errors while checking the status of the License, using the Status Document. @@ -55,17 +71,41 @@ public sealed class LcpException( * time corresponding to the new status should be displayed (e.g. "The license expired on 01 * January 2018"). */ - public sealed class LicenseStatus(userMessageId: Int, vararg args: Any, quantity: Int? = null) : LcpException(userMessageId, *args, quantity = quantity) { - protected constructor(@StringRes userMessageId: Int, vararg args: Any) : this(userMessageId, *args, quantity = null) - protected constructor(@PluralsRes userMessageId: Int, quantity: Int, vararg args: Any) : this(userMessageId, *args, quantity = quantity) - - public class Cancelled(public val date: Date) : LicenseStatus(R.string.readium_lcp_exception_license_status_cancelled, date) - - public class Returned(public val date: Date) : LicenseStatus(R.string.readium_lcp_exception_license_status_returned, date) - - public class NotStarted(public val start: Date) : LicenseStatus(R.string.readium_lcp_exception_license_status_not_started, start) - - public class Expired(public val end: Date) : LicenseStatus(R.string.readium_lcp_exception_license_status_expired, end) + public sealed class LicenseStatus(userMessageId: Int, vararg args: Any, quantity: Int? = null) : LcpException( + userMessageId, + *args, + quantity = quantity + ) { + protected constructor(@StringRes userMessageId: Int, vararg args: Any) : this( + userMessageId, + *args, + quantity = null + ) + protected constructor(@PluralsRes userMessageId: Int, quantity: Int, vararg args: Any) : this( + userMessageId, + *args, + quantity = quantity + ) + + public class Cancelled(public val date: Date) : LicenseStatus( + R.string.readium_lcp_exception_license_status_cancelled, + date + ) + + public class Returned(public val date: Date) : LicenseStatus( + R.string.readium_lcp_exception_license_status_returned, + date + ) + + public class NotStarted(public val start: Date) : LicenseStatus( + R.string.readium_lcp_exception_license_status_not_started, + start + ) + + public class Expired(public val end: Date) : LicenseStatus( + R.string.readium_lcp_exception_license_status_expired, + end + ) /** * If the license has been revoked, the user message should display the number of devices which @@ -74,7 +114,12 @@ public sealed class LcpException( * appear (certainly not "The license was registered by 0 devices"). */ public class Revoked(public val date: Date, public val devicesCount: Int) : - LicenseStatus(R.plurals.readium_lcp_exception_license_status_revoked, devicesCount, date, devicesCount) + LicenseStatus( + R.plurals.readium_lcp_exception_license_status_revoked, + devicesCount, + date, + devicesCount + ) } /** @@ -86,10 +131,14 @@ public sealed class LcpException( public object RenewFailed : Renew(R.string.readium_lcp_exception_renew_renew_failed) /** Incorrect renewal period, your publication could not be renewed. */ - public class InvalidRenewalPeriod(public val maxRenewDate: Date?) : Renew(R.string.readium_lcp_exception_renew_invalid_renewal_period) + public class InvalidRenewalPeriod(public val maxRenewDate: Date?) : Renew( + R.string.readium_lcp_exception_renew_invalid_renewal_period + ) /** An unexpected error has occurred on the licensing server. */ - public object UnexpectedServerError : Renew(R.string.readium_lcp_exception_renew_unexpected_server_error) + public object UnexpectedServerError : Renew( + R.string.readium_lcp_exception_renew_unexpected_server_error + ) } /** @@ -102,10 +151,14 @@ public sealed class LcpException( /** Your publication has already been returned before or is expired. */ - public object AlreadyReturnedOrExpired : Return(R.string.readium_lcp_exception_return_already_returned_or_expired) + public object AlreadyReturnedOrExpired : Return( + R.string.readium_lcp_exception_return_already_returned_or_expired + ) /** An unexpected error has occurred on the licensing server. */ - public object UnexpectedServerError : Return(R.string.readium_lcp_exception_return_unexpected_server_error) + public object UnexpectedServerError : Return( + R.string.readium_lcp_exception_return_unexpected_server_error + ) } /** @@ -119,10 +172,14 @@ public sealed class LcpException( public object MalformedJSON : Parsing(R.string.readium_lcp_exception_parsing_malformed_json) /** The JSON is not representing a valid License Document. */ - public object LicenseDocument : Parsing(R.string.readium_lcp_exception_parsing_license_document) + public object LicenseDocument : Parsing( + R.string.readium_lcp_exception_parsing_license_document + ) /** The JSON is not representing a valid Status Document. */ - public object StatusDocument : Parsing(R.string.readium_lcp_exception_parsing_status_document) + public object StatusDocument : Parsing( + R.string.readium_lcp_exception_parsing_status_document + ) /** Invalid Link. */ public object Link : Parsing() @@ -146,36 +203,58 @@ public sealed class LcpException( public object OpenFailed : Container(R.string.readium_lcp_exception_container_open_failed) /** The file at given relative path is not found in the Container. */ - public class FileNotFound(public val path: String) : Container(R.string.readium_lcp_exception_container_file_not_found) + public class FileNotFound(public val path: String) : Container( + R.string.readium_lcp_exception_container_file_not_found + ) /** Can't read the file at given relative path in the Container. */ - public class ReadFailed(public val path: String) : Container(R.string.readium_lcp_exception_container_read_failed) + public class ReadFailed(public val path: String) : Container( + R.string.readium_lcp_exception_container_read_failed + ) /** Can't write the file at given relative path in the Container. */ - public class WriteFailed(public val path: String) : Container(R.string.readium_lcp_exception_container_write_failed) + public class WriteFailed(public val path: String) : Container( + R.string.readium_lcp_exception_container_write_failed + ) } /** * An error occurred while checking the integrity of the License, it can't be retrieved. */ - public sealed class LicenseIntegrity(@StringRes userMessageId: Int) : LcpException(userMessageId) { + public sealed class LicenseIntegrity(@StringRes userMessageId: Int) : LcpException( + userMessageId + ) { - public object CertificateRevoked : LicenseIntegrity(R.string.readium_lcp_exception_license_integrity_certificate_revoked) + public object CertificateRevoked : LicenseIntegrity( + R.string.readium_lcp_exception_license_integrity_certificate_revoked + ) - public object InvalidCertificateSignature : LicenseIntegrity(R.string.readium_lcp_exception_license_integrity_invalid_certificate_signature) + public object InvalidCertificateSignature : LicenseIntegrity( + R.string.readium_lcp_exception_license_integrity_invalid_certificate_signature + ) - public object InvalidLicenseSignatureDate : LicenseIntegrity(R.string.readium_lcp_exception_license_integrity_invalid_license_signature_date) + public object InvalidLicenseSignatureDate : LicenseIntegrity( + R.string.readium_lcp_exception_license_integrity_invalid_license_signature_date + ) - public object InvalidLicenseSignature : LicenseIntegrity(R.string.readium_lcp_exception_license_integrity_invalid_license_signature) + public object InvalidLicenseSignature : LicenseIntegrity( + R.string.readium_lcp_exception_license_integrity_invalid_license_signature + ) - public object InvalidUserKeyCheck : LicenseIntegrity(R.string.readium_lcp_exception_license_integrity_invalid_user_key_check) + public object InvalidUserKeyCheck : LicenseIntegrity( + R.string.readium_lcp_exception_license_integrity_invalid_user_key_check + ) } public sealed class Decryption(@StringRes userMessageId: Int) : LcpException(userMessageId) { - public object ContentKeyDecryptError : Decryption(R.string.readium_lcp_exception_decryption_content_key_decrypt_error) + public object ContentKeyDecryptError : Decryption( + R.string.readium_lcp_exception_decryption_content_key_decrypt_error + ) - public object ContentDecryptError : Decryption(R.string.readium_lcp_exception_decryption_content_decrypt_error) + public object ContentDecryptError : Decryption( + R.string.readium_lcp_exception_decryption_content_decrypt_error + ) } public companion object { @@ -188,8 +267,16 @@ public sealed class LcpException( } } -@Deprecated("Renamed to `LcpException`", replaceWith = ReplaceWith("LcpException"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpException`", + replaceWith = ReplaceWith("LcpException"), + level = DeprecationLevel.ERROR +) public typealias LCPError = LcpException -@Deprecated("Use `getUserMessage()` instead", replaceWith = ReplaceWith("getUserMessage(context)"), level = DeprecationLevel.ERROR) +@Deprecated( + "Use `getUserMessage()` instead", + replaceWith = ReplaceWith("getUserMessage(context)"), + level = DeprecationLevel.ERROR +) public val LcpException.errorDescription: String? get() = message diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt index 587bc6cc0f..a5afd352f7 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt @@ -105,27 +105,49 @@ public interface LcpLicense : ContentProtectionService.UserRights { public suspend fun openWebPage(url: URL) } - @Deprecated("Use `license.encryption.profile` instead", ReplaceWith("license.encryption.profile"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `license.encryption.profile` instead", + ReplaceWith("license.encryption.profile"), + level = DeprecationLevel.ERROR + ) public val encryptionProfile: String? get() = license.encryption.profile - @Deprecated("Use `decrypt()` with coroutines instead", ReplaceWith("decrypt(data)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `decrypt()` with coroutines instead", + ReplaceWith("decrypt(data)"), + level = DeprecationLevel.ERROR + ) public fun decipher(data: ByteArray): ByteArray? = runBlocking { decrypt(data) } .onFailure { Timber.e(it) } .getOrNull() - @Deprecated("Use `renewLoan` with `RenewListener` instead", ReplaceWith("renewLoan(LcpLicense.RenewListener)"), level = DeprecationLevel.ERROR) - public suspend fun renewLoan(end: DateTime?, urlPresenter: suspend (URL) -> Unit): Try = Try.success(Unit) - - @Deprecated("Use `renewLoan` with `RenewListener` instead", ReplaceWith("renewLoan(LcpLicense.RenewListener)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `renewLoan` with `RenewListener` instead", + ReplaceWith("renewLoan(LcpLicense.RenewListener)"), + level = DeprecationLevel.ERROR + ) + public suspend fun renewLoan(end: DateTime?, urlPresenter: suspend (URL) -> Unit): Try = Try.success( + Unit + ) + + @Deprecated( + "Use `renewLoan` with `RenewListener` instead", + ReplaceWith("renewLoan(LcpLicense.RenewListener)"), + level = DeprecationLevel.ERROR + ) public fun renewLoan( end: DateTime?, present: (URL, dismissed: () -> Unit) -> Unit, completion: (LcpException?) -> Unit ) {} - @Deprecated("Use `returnPublication()` with coroutines instead", ReplaceWith("returnPublication"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `returnPublication()` with coroutines instead", + ReplaceWith("returnPublication"), + level = DeprecationLevel.ERROR + ) @DelicateCoroutinesApi public fun returnPublication(completion: (LcpException?) -> Unit) { GlobalScope.launch { @@ -134,8 +156,16 @@ public interface LcpLicense : ContentProtectionService.UserRights { } } -@Deprecated("Renamed to `LcpService`", replaceWith = ReplaceWith("LcpService"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpService`", + replaceWith = ReplaceWith("LcpService"), + level = DeprecationLevel.ERROR +) public typealias LCPService = LcpService -@Deprecated("Renamed to `LcpLicense`", replaceWith = ReplaceWith("LcpLicense"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpLicense`", + replaceWith = ReplaceWith("LcpLicense"), + level = DeprecationLevel.ERROR +) public typealias LCPLicense = LcpLicense diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt index c5e758a669..61d9a27582 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt @@ -29,12 +29,9 @@ import org.readium.r2.lcp.service.NetworkService import org.readium.r2.lcp.service.PassphrasesRepository import org.readium.r2.lcp.service.PassphrasesService import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.protection.ContentProtection -import org.readium.r2.shared.resource.ArchiveFactory -import org.readium.r2.shared.resource.DefaultArchiveFactory -import org.readium.r2.shared.resource.FileResourceFactory -import org.readium.r2.shared.resource.ResourceFactory import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever @@ -69,7 +66,9 @@ public interface LcpService { * * @param onProgress Callback to follow the acquisition progress from 0.0 to 1.0. */ - public suspend fun acquirePublication(lcpl: File, onProgress: (Double) -> Unit = {}): Try = withContext(Dispatchers.IO) { + public suspend fun acquirePublication(lcpl: File, onProgress: (Double) -> Unit = {}): Try = withContext( + Dispatchers.IO + ) { try { acquirePublication(lcpl.readBytes(), onProgress) } catch (e: Exception) { @@ -125,7 +124,7 @@ public interface LcpService { * user to enter their passphrase. */ public fun contentProtection( - authentication: LcpAuthenticating = LcpDialogAuthentication(), + authentication: LcpAuthenticating = LcpDialogAuthentication() ): ContentProtection /** @@ -142,7 +141,11 @@ public interface LcpService { val mediaType: MediaType, val licenseDocument: LicenseDocument ) { - @Deprecated("Use `localFile` instead", replaceWith = ReplaceWith("localFile"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `localFile` instead", + replaceWith = ReplaceWith("localFile"), + level = DeprecationLevel.ERROR + ) val localURL: String get() = localFile.path } @@ -153,19 +156,23 @@ public interface LcpService { */ public operator fun invoke( context: Context, - mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), - resourceFactory: ResourceFactory = FileResourceFactory(), - archiveFactory: ArchiveFactory = DefaultArchiveFactory() + assetRetriever: AssetRetriever, + mediaTypeRetriever: MediaTypeRetriever ): LcpService? { - if (!LcpClient.isAvailable()) + if (!LcpClient.isAvailable()) { return null + } val db = LcpDatabase.getDatabase(context).lcpDao() val deviceRepository = DeviceRepository(db) val passphraseRepository = PassphrasesRepository(db) val licenseRepository = LicensesRepository(db) - val network = NetworkService(mediaTypeRetriever = mediaTypeRetriever) - val device = DeviceService(repository = deviceRepository, network = network, context = context) + val network = NetworkService(mediaTypeRetriever) + val device = DeviceService( + repository = deviceRepository, + network = network, + context = context + ) val crl = CRLService(network = network, context = context) val passphrases = PassphrasesService(repository = passphraseRepository) return LicensesService( @@ -175,17 +182,24 @@ public interface LcpService { network = network, passphrases = passphrases, context = context, - mediaTypeRetriever = mediaTypeRetriever, - resourceFactory = resourceFactory, - archiveFactory = archiveFactory + assetRetriever = assetRetriever ) } - @Deprecated("Use `LcpService()` instead", ReplaceWith("LcpService(context)"), level = DeprecationLevel.ERROR) - public fun create(context: Context): LcpService? = invoke(context) + @Suppress("UNUSED_PARAMETER") + @Deprecated( + "Use `LcpService()` instead", + ReplaceWith("LcpService(context, AssetRetriever(), MediaTypeRetriever())"), + level = DeprecationLevel.ERROR + ) + public fun create(context: Context): LcpService? = throw NotImplementedError() } - @Deprecated("Use `acquirePublication()` with coroutines instead", ReplaceWith("acquirePublication(lcpl)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `acquirePublication()` with coroutines instead", + ReplaceWith("acquirePublication(lcpl)"), + level = DeprecationLevel.ERROR + ) @DelicateCoroutinesApi public fun importPublication( lcpl: ByteArray, @@ -199,7 +213,13 @@ public interface LcpService { } } - @Deprecated("Use `retrieveLicense()` with coroutines instead", ReplaceWith("retrieveLicense(File(publication), authentication, allowUserInteraction = true)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `retrieveLicense()` with coroutines instead", + ReplaceWith( + "retrieveLicense(File(publication), authentication, allowUserInteraction = true)" + ), + level = DeprecationLevel.ERROR + ) @DelicateCoroutinesApi public fun retrieveLicense( publication: String, @@ -210,9 +230,18 @@ public interface LcpService { } } -@Deprecated("Renamed to `LcpService()`", replaceWith = ReplaceWith("LcpService(context)"), level = DeprecationLevel.ERROR) +@Suppress("UNUSED_PARAMETER") +@Deprecated( + "Renamed to `LcpService()`", + replaceWith = ReplaceWith("LcpService(context)"), + level = DeprecationLevel.ERROR +) public fun R2MakeLCPService(context: Context): LcpService = - LcpService(context) ?: throw Exception("liblcp is missing on the classpath") + throw NotImplementedError() -@Deprecated("Renamed to `LcpService.AcquiredPublication`", replaceWith = ReplaceWith("LcpService.AcquiredPublication"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpService.AcquiredPublication`", + replaceWith = ReplaceWith("LcpService.AcquiredPublication"), + level = DeprecationLevel.ERROR +) public typealias LCPImportedPublication = LcpService.AcquiredPublication diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/MaterialRenewListener.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/MaterialRenewListener.kt index 8748e50801..ea5d97329c 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/MaterialRenewListener.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/MaterialRenewListener.kt @@ -87,7 +87,9 @@ public class MaterialRenewListener( private var webPageContinuation: Continuation? = null - private val webPageLauncher = caller.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + private val webPageLauncher = caller.registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { webPageContinuation?.resume(Unit) } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDialogAuthentication.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDialogAuthentication.kt index 6f75000c4f..8ec6709645 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDialogAuthentication.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpDialogAuthentication.kt @@ -51,22 +51,36 @@ public class LcpDialogAuthentication : LcpAuthenticating { allowUserInteraction: Boolean, sender: Any? ): String? = - if (allowUserInteraction) withContext(Dispatchers.Main) { askPassphrase(license, reason, sender) } - else null + if (allowUserInteraction) { + withContext(Dispatchers.Main) { + askPassphrase( + license, + reason, + sender + ) + } + } else { + null + } private suspend fun askPassphrase( license: LcpAuthenticating.AuthenticatedLicense, reason: LcpAuthenticating.AuthenticationReason, sender: Any? ): String? { - val hostView = (sender as? View) ?: (sender as? Activity)?.findViewById(android.R.id.content)?.getChildAt(0) ?: (sender as? Fragment)?.view + val hostView = (sender as? View) ?: (sender as? Activity)?.findViewById( + android.R.id.content + )?.getChildAt(0) ?: (sender as? Fragment)?.view ?: run { - Timber.e("No valid [sender] was passed to `LcpDialogAuthentication::retrievePassphrase()`. Make sure it is an Activity, a Fragment or a View.") + Timber.e( + "No valid [sender] was passed to `LcpDialogAuthentication::retrievePassphrase()`. Make sure it is an Activity, a Fragment or a View." + ) return null } val context = hostView.context val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + @SuppressLint("InflateParams") // https://stackoverflow.com/q/26404951/1474476 val dialogView = inflater.inflate(R.layout.readium_lcp_auth_dialog, null) @@ -85,11 +99,15 @@ public class LcpDialogAuthentication : LcpAuthenticating { when (reason) { LcpAuthenticating.AuthenticationReason.PassphraseNotFound -> { - title.text = context.getString(R.string.readium_lcp_dialog_reason_passphraseNotFound) + title.text = context.getString( + R.string.readium_lcp_dialog_reason_passphraseNotFound + ) } LcpAuthenticating.AuthenticationReason.InvalidPassphrase -> { title.text = context.getString(R.string.readium_lcp_dialog_reason_invalidPassphrase) - passwordLayout.error = context.getString(R.string.readium_lcp_dialog_reason_invalidPassphrase) + passwordLayout.error = context.getString( + R.string.readium_lcp_dialog_reason_invalidPassphrase + ) } } @@ -99,7 +117,11 @@ public class LcpDialogAuthentication : LcpAuthenticating { hint.text = license.hint return suspendCoroutine { cont -> - val popupWindow = PopupWindow(dialogView, ListPopupWindow.MATCH_PARENT, ListPopupWindow.MATCH_PARENT).apply { + val popupWindow = PopupWindow( + dialogView, + ListPopupWindow.MATCH_PARENT, + ListPopupWindow.MATCH_PARENT + ).apply { isOutsideTouchable = false isFocusable = true elevation = 5.0f diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpPassphraseAuthentication.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpPassphraseAuthentication.kt index f05df57f5e..1ca09133ac 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpPassphraseAuthentication.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/auth/LcpPassphraseAuthentication.kt @@ -26,7 +26,12 @@ public class LcpPassphraseAuthentication( sender: Any? ): String? { if (reason != LcpAuthenticating.AuthenticationReason.PassphraseNotFound) { - return fallback?.retrievePassphrase(license, reason, allowUserInteraction = allowUserInteraction, sender = sender) + return fallback?.retrievePassphrase( + license, + reason, + allowUserInteraction = allowUserInteraction, + sender = sender + ) } return passphrase diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt index 6842b9062c..9975dad291 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt @@ -47,7 +47,9 @@ internal class License( override val status: StatusDocument? get() = documents.status - override suspend fun decrypt(data: ByteArray): Try = withContext(Dispatchers.Default) { + override suspend fun decrypt(data: ByteArray): Try = withContext( + Dispatchers.Default + ) { try { // LCP lib crashes if we call decrypt on an empty ByteArray if (data.isEmpty()) { @@ -132,13 +134,12 @@ internal class License( } override val canRenewLoan: Boolean - get() = status?.link(StatusDocument.Rel.renew) != null + get() = status?.link(StatusDocument.Rel.Renew) != null override val maxRenewDate: Date? get() = status?.potentialRights?.end override suspend fun renewLoan(listener: LcpLicense.RenewListener, prefersWebPage: Boolean): Try { - // Finds the renew link according to `prefersWebPage`. fun findRenewLink(): Link? { val status = documents.status ?: return null @@ -151,20 +152,22 @@ internal class License( } for (type in types) { - return status.link(StatusDocument.Rel.renew, type = type) + return status.link(StatusDocument.Rel.Renew, type = type) ?: continue } // Fallback on the first renew link with no media type set and assume it's a PUT action. - return status.linkWithNoType(StatusDocument.Rel.renew) + return status.linkWithNoType(StatusDocument.Rel.Renew) } // Programmatically renew the loan with a PUT request. suspend fun renewProgrammatically(link: Link): ByteArray { val endDate = - if (link.templateParameters.contains("end")) + if (link.templateParameters.contains("end")) { listener.preferredEndDate(maxRenewDate) - else null + } else { + null + } val parameters = this.device.asQueryParameters.toMutableMap() if (endDate != null) { @@ -177,7 +180,9 @@ internal class License( .getOrElse { error -> when (error.status) { HttpURLConnection.HTTP_BAD_REQUEST -> throw LcpException.Renew.RenewFailed - HttpURLConnection.HTTP_FORBIDDEN -> throw LcpException.Renew.InvalidRenewalPeriod(maxRenewDate = this.maxRenewDate) + HttpURLConnection.HTTP_FORBIDDEN -> throw LcpException.Renew.InvalidRenewalPeriod( + maxRenewDate = this.maxRenewDate + ) else -> throw LcpException.Renew.UnexpectedServerError } } @@ -189,10 +194,16 @@ internal class License( listener.openWebPage(link.url) val statusURL = tryOrNull { - license.url(LicenseDocument.Rel.status, preferredType = MediaType.LCP_STATUS_DOCUMENT) + license.url( + LicenseDocument.Rel.Status, + preferredType = MediaType.LCP_STATUS_DOCUMENT + ) } ?: throw LcpException.LicenseInteractionNotAvailable - return network.fetch(statusURL.toString(), headers = mapOf("Accept" to MediaType.LCP_STATUS_DOCUMENT.toString())).getOrThrow() + return network.fetch( + statusURL.toString(), + headers = mapOf("Accept" to MediaType.LCP_STATUS_DOCUMENT.toString()) + ).getOrThrow() } try { @@ -218,13 +229,17 @@ internal class License( } override val canReturnPublication: Boolean - get() = status?.link(StatusDocument.Rel.`return`) != null + get() = status?.link(StatusDocument.Rel.Return) != null override suspend fun returnPublication(): Try { try { val status = this.documents.status val url = try { - status?.url(StatusDocument.Rel.`return`, preferredType = null, parameters = device.asQueryParameters) + status?.url( + StatusDocument.Rel.Return, + preferredType = null, + parameters = device.asQueryParameters + ) } catch (e: Throwable) { null } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt index 594a30d723..32227057f7 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt @@ -32,7 +32,10 @@ internal sealed class Either { class Right(val right: B) : Either() } -private val supportedProfiles = listOf("http://readium.org/lcp/basic-profile", "http://readium.org/lcp/profile-1.0") +private val supportedProfiles = listOf( + "http://readium.org/lcp/basic-profile", + "http://readium.org/lcp/profile-1.0" +) internal typealias Context = Either @@ -41,8 +44,8 @@ internal typealias Observer = (ValidatedDocuments?, Exception?) -> Unit private var observers: MutableList> = mutableListOf() internal enum class ObserverPolicy { - once, - always + Once, + Always } internal data class ValidatedDocuments constructor( @@ -207,8 +210,14 @@ internal class LicenseValidation( state { on { it.error?.let { error -> - if (DEBUG) Timber.d("State.valid(ValidatedDocuments(license, Either.Right(error), status))") - transitionTo(State.valid(ValidatedDocuments(license, Either.Right(error), status))) + if (DEBUG) { + Timber.d( + "State.valid(ValidatedDocuments(license, Either.Right(error), status))" + ) + } + transitionTo( + State.valid(ValidatedDocuments(license, Either.Right(error), status)) + ) } ?: run { if (DEBUG) Timber.d("State.requestPassphrase(license, status)") transitionTo(State.retrievePassphrase(license, status)) @@ -232,7 +241,7 @@ internal class LicenseValidation( state { on { val documents = ValidatedDocuments(license, Either.Left(it.context), status) - val link = status?.link(StatusDocument.Rel.register) + val link = status?.link(StatusDocument.Rel.Register) link?.let { if (DEBUG) Timber.d("State.registerDevice(documents, link)") transitionTo(State.registerDevice(documents, link)) @@ -296,7 +305,11 @@ internal class LicenseValidation( is State.fetchStatus -> fetchStatus(state.license) is State.validateStatus -> validateStatus(state.data) is State.fetchLicense -> fetchLicense(state.status) - is State.checkLicenseStatus -> checkLicenseStatus(state.license, state.status, state.statusDocumentTakesPrecedence) + is State.checkLicenseStatus -> checkLicenseStatus( + state.license, + state.status, + state.statusDocumentTakesPrecedence + ) is State.retrievePassphrase -> requestPassphrase(state.license) is State.validateIntegrity -> validateIntegrity(state.license, state.passphrase) is State.registerDevice -> registerDevice(state.documents.license, state.link) @@ -313,7 +326,7 @@ internal class LicenseValidation( private fun observe(event: Event, observer: Observer) { raise(event) - Companion.observe(this, ObserverPolicy.once, observer) + Companion.observe(this, ObserverPolicy.Once, observer) } private fun notifyObservers(documents: ValidatedDocuments?, error: Exception?) { @@ -322,7 +335,7 @@ internal class LicenseValidation( observer.first(documents, error) } // Timber.d("observers $observers") - observers = (observers.filter { it.second != ObserverPolicy.once }).toMutableList() + observers = (observers.filter { it.second != ObserverPolicy.Once }).toMutableList() // Timber.d("observers $observers") } @@ -336,10 +349,17 @@ internal class LicenseValidation( } private suspend fun fetchStatus(license: LicenseDocument) { - val url = license.url(LicenseDocument.Rel.status, preferredType = MediaType.LCP_STATUS_DOCUMENT).toString() + val url = license.url( + LicenseDocument.Rel.Status, + preferredType = MediaType.LCP_STATUS_DOCUMENT + ).toString() // Short timeout to avoid blocking the License, when the LSD is optional. val timeout = 5.seconds.takeIf { ignoreInternetErrors } - val data = network.fetch(url, timeout = timeout, headers = mapOf("Accept" to MediaType.LCP_STATUS_DOCUMENT.toString())) + val data = network.fetch( + url, + timeout = timeout, + headers = mapOf("Accept" to MediaType.LCP_STATUS_DOCUMENT.toString()) + ) .getOrElse { throw LcpException.Network(it) } raise(Event.retrievedStatusData(data)) @@ -351,7 +371,10 @@ internal class LicenseValidation( } private suspend fun fetchLicense(status: StatusDocument) { - val url = status.url(StatusDocument.Rel.license, preferredType = MediaType.LCP_LICENSE_DOCUMENT).toString() + val url = status.url( + StatusDocument.Rel.License, + preferredType = MediaType.LCP_LICENSE_DOCUMENT + ).toString() // Short timeout to avoid blocking the License, since it can be updated next time. val data = network.fetch(url, timeout = 5.seconds) .getOrElse { throw LcpException.Network(it) } @@ -369,7 +392,11 @@ internal class LicenseValidation( val start = license.rights.start ?: now val end = license.rights.end ?: now val isLicenseExpired = (start > now || now > end) - val isStatusValid = status?.status in listOf(null, StatusDocument.Status.active, StatusDocument.Status.ready) + val isStatusValid = status?.status in listOf( + null, + StatusDocument.Status.Active, + StatusDocument.Status.Ready + ) // We only check the Status Document's status if the License itself is expired, to get a proper status error message. // But in the case where the Status Document takes precedence (eg. after a failed License update), @@ -378,18 +405,20 @@ internal class LicenseValidation( error = if (status != null) { val date = status.statusUpdated when (status.status) { - StatusDocument.Status.ready, StatusDocument.Status.active, StatusDocument.Status.expired -> + StatusDocument.Status.Ready, StatusDocument.Status.Active, StatusDocument.Status.Expired -> if (start > now) { LcpException.LicenseStatus.NotStarted(start) } else { LcpException.LicenseStatus.Expired(end) } - StatusDocument.Status.returned -> LcpException.LicenseStatus.Returned(date) - StatusDocument.Status.revoked -> { - val devicesCount = status.events(org.readium.r2.lcp.license.model.components.lsd.Event.EventType.register).size + StatusDocument.Status.Returned -> LcpException.LicenseStatus.Returned(date) + StatusDocument.Status.Revoked -> { + val devicesCount = status.events( + org.readium.r2.lcp.license.model.components.lsd.Event.EventType.Register + ).size LcpException.LicenseStatus.Revoked(date, devicesCount = devicesCount) } - StatusDocument.Status.cancelled -> LcpException.LicenseStatus.Cancelled(date) + StatusDocument.Status.Cancelled -> LcpException.LicenseStatus.Cancelled(date) } } else { if (start > now) { @@ -405,10 +434,11 @@ internal class LicenseValidation( private suspend fun requestPassphrase(license: LicenseDocument) { if (DEBUG) Timber.d("requestPassphrase") val passphrase = passphrases.request(license, authentication, allowUserInteraction, sender) - if (passphrase == null) + if (passphrase == null) { raise(Event.cancelled) - else + } else { raise(Event.retrievedPassphrase(passphrase)) + } } private suspend fun validateIntegrity(license: LicenseDocument, passphrase: String) { @@ -430,17 +460,23 @@ internal class LicenseValidation( companion object { fun observe( licenseValidation: LicenseValidation, - policy: ObserverPolicy = ObserverPolicy.always, + policy: ObserverPolicy = ObserverPolicy.Always, observer: Observer ) { var notified = true when (licenseValidation.stateMachine.state) { - is State.valid -> observer((licenseValidation.stateMachine.state as State.valid).documents, null) - is State.failure -> observer(null, (licenseValidation.stateMachine.state as State.failure).error) + is State.valid -> observer( + (licenseValidation.stateMachine.state as State.valid).documents, + null + ) + is State.failure -> observer( + null, + (licenseValidation.stateMachine.state as State.failure).error + ) is State.cancelled -> observer(null, null) else -> notified = false } - if (notified && policy != ObserverPolicy.always) { + if (notified && policy != ObserverPolicy.Always) { return } observers.add(Pair(observer, policy)) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/StateMachine.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/StateMachine.kt index 6a2b7df110..569084c3ff 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/StateMachine.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/StateMachine.kt @@ -165,7 +165,11 @@ internal class StateMachine private constructor( } fun build(): Graph { - return Graph(requireNotNull(initialState), stateDefinitions.toMap(), onTransitionListeners.toList()) + return Graph( + requireNotNull(initialState), + stateDefinitions.toMap(), + onTransitionListeners.toList() + ) } inner class StateDefinitionBuilder { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt index 502a0f4a10..70d9d5e45d 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt @@ -18,17 +18,19 @@ import org.readium.r2.shared.resource.Resource */ internal class ContainerLicenseContainer( private val container: Container, - private val entryPath: String, + private val entryPath: String ) : LicenseContainer { override fun read(): ByteArray { return runBlocking { container - .entry(entryPath) + .get(entryPath) .read() .mapFailure { when (it) { - is Resource.Exception.NotFound -> LcpException.Container.FileNotFound(entryPath) + is Resource.Exception.NotFound -> LcpException.Container.FileNotFound( + entryPath + ) else -> LcpException.Container.ReadFailed(entryPath) } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt index 52fcce6347..a9b3893e01 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt @@ -43,7 +43,7 @@ internal fun createLicenseContainer( } internal fun createLicenseContainer( - asset: Asset, + asset: Asset ): LicenseContainer = when (asset) { is Asset.Resource -> createLicenseContainer(asset.resource, asset.mediaType) @@ -62,7 +62,7 @@ internal fun createLicenseContainer( internal fun createLicenseContainer( container: Container, - mediaType: MediaType, + mediaType: MediaType ): LicenseContainer { val licensePath = when (mediaType) { MediaType.EPUB -> LICENSE_IN_EPUB.addPrefix("/") diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt index 5405bb3cc8..85f9ee42be 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt @@ -20,11 +20,10 @@ import org.zeroturnaround.zip.ZipUtil */ internal class ZIPLicenseContainer( private val zip: String, - private val pathInZIP: String, + private val pathInZIP: String ) : LicenseContainer { override fun read(): ByteArray { - val archive = try { ZipFile(zip) } catch (e: Exception) { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt index 34cf6f76b0..ea3b6d7733 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt @@ -38,11 +38,11 @@ public class LicenseDocument(public val data: ByteArray) { public val json: JSONObject public enum class Rel(public val value: String) { - hint("hint"), - publication("publication"), - self("self"), - support("support"), - status("status"); + Hint("hint"), + Publication("publication"), + Self("self"), + Support("support"), + Status("status"); @Deprecated("Use [value] instead", ReplaceWith("value"), level = DeprecationLevel.ERROR) public val rawValue: String get() = value @@ -69,7 +69,7 @@ public class LicenseDocument(public val data: ByteArray) { user = User(json.optJSONObject("user") ?: JSONObject()) rights = Rights(json.optJSONObject("rights") ?: JSONObject()) - if (link(Rel.hint) == null || link(Rel.publication) == null) { + if (link(Rel.Hint) == null || link(Rel.Publication) == null) { throw LcpException.Parsing.LicenseDocument } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/StatusDocument.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/StatusDocument.kt index fc0e03e1c3..48e19582ff 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/StatusDocument.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/StatusDocument.kt @@ -37,12 +37,12 @@ public class StatusDocument(public val data: ByteArray) { public val json: JSONObject public enum class Status(public val value: String) { - ready("ready"), - active("active"), - revoked("revoked"), - returned("returned"), - cancelled("cancelled"), - expired("expired"); + Ready("ready"), + Active("active"), + Revoked("revoked"), + Returned("returned"), + Cancelled("cancelled"), + Expired("expired"); @Deprecated("Use [value] instead", ReplaceWith("value"), level = DeprecationLevel.ERROR) public val rawValue: String get() = value @@ -53,10 +53,10 @@ public class StatusDocument(public val data: ByteArray) { } public enum class Rel(public val value: String) { - register("register"), - license("license"), - `return`("return"), - renew("renew"); + Register("register"), + License("license"), + Return("return"), + Renew("renew"); @Deprecated("Use [value] instead", ReplaceWith("value"), level = DeprecationLevel.ERROR) public val rawValue: String get() = value diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/Link.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/Link.kt index da669629c6..ce3cec3932 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/Link.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/Link.kt @@ -69,15 +69,16 @@ public data class Link(val json: JSONObject) { get() = url(parameters = emptyMap()) val mediaType: MediaType - get() = type?.let { MediaType.parse(it) } ?: MediaType.BINARY + get() = type?.let { MediaType(it) } ?: MediaType.BINARY /** * List of URI template parameter keys, if the [Link] is templated. */ internal val templateParameters: List by lazy { - if (!templated) + if (!templated) { emptyList() - else + } else { URITemplate(href).parameters + } } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/lsd/Event.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/lsd/Event.kt index c87ce9e63c..8664ca9836 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/lsd/Event.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/lsd/Event.kt @@ -21,11 +21,11 @@ public data class Event(val json: JSONObject) { val date: Date? = json.optNullableString("timestamp")?.iso8601ToDate() public enum class EventType(public val value: String) { - register("register"), - renew("renew"), - `return`("return"), - revoke("revoke"), - cancel("cancel"); + Register("register"), + Renew("renew"), + Return("return"), + Revoke("revoke"), + Cancel("cancel"); @Deprecated("Use [value] instead", ReplaceWith("value"), level = DeprecationLevel.ERROR) public val rawValue: String get() = value diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDao.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDao.kt index 0bc65434d3..de37fe0473 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDao.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/persistence/LcpDao.kt @@ -12,10 +12,14 @@ internal interface LcpDao { * Retrieve passphrase * @return Passphrase */ - @Query("SELECT ${Passphrase.PASSPHRASE} FROM ${Passphrase.TABLE_NAME} WHERE ${Passphrase.PROVIDER} = :licenseId") + @Query( + "SELECT ${Passphrase.PASSPHRASE} FROM ${Passphrase.TABLE_NAME} WHERE ${Passphrase.PROVIDER} = :licenseId" + ) suspend fun passphrase(licenseId: String): String? - @Query("SELECT ${Passphrase.PASSPHRASE} FROM ${Passphrase.TABLE_NAME} WHERE ${Passphrase.USERID} = :userId") + @Query( + "SELECT ${Passphrase.PASSPHRASE} FROM ${Passphrase.TABLE_NAME} WHERE ${Passphrase.USERID} = :userId" + ) suspend fun passphrases(userId: String): List @Query("SELECT ${Passphrase.PASSPHRASE} FROM ${Passphrase.TABLE_NAME}") @@ -24,27 +28,41 @@ internal interface LcpDao { @Insert(onConflict = OnConflictStrategy.IGNORE) suspend fun addPassphrase(passphrase: Passphrase) - @Query("SELECT ${License.LICENSE_ID} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId") + @Query( + "SELECT ${License.LICENSE_ID} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId" + ) suspend fun exists(licenseId: String): String? - @Query("SELECT ${License.REGISTERED} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId") + @Query( + "SELECT ${License.REGISTERED} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId" + ) suspend fun isDeviceRegistered(licenseId: String): Boolean - @Query("UPDATE ${License.TABLE_NAME} SET ${License.REGISTERED} = 1 WHERE ${License.LICENSE_ID} = :licenseId") + @Query( + "UPDATE ${License.TABLE_NAME} SET ${License.REGISTERED} = 1 WHERE ${License.LICENSE_ID} = :licenseId" + ) suspend fun registerDevice(licenseId: String) @Insert(onConflict = OnConflictStrategy.IGNORE) suspend fun addLicense(license: License) - @Query("SELECT ${License.RIGHTCOPY} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId") + @Query( + "SELECT ${License.RIGHTCOPY} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId" + ) fun getCopiesLeft(licenseId: String): Int? - @Query("UPDATE ${License.TABLE_NAME} SET ${License.RIGHTCOPY} = :quantity WHERE ${License.LICENSE_ID} = :licenseId") + @Query( + "UPDATE ${License.TABLE_NAME} SET ${License.RIGHTCOPY} = :quantity WHERE ${License.LICENSE_ID} = :licenseId" + ) fun setCopiesLeft(quantity: Int, licenseId: String) - @Query("SELECT ${License.RIGHTPRINT} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId") + @Query( + "SELECT ${License.RIGHTPRINT} FROM ${License.TABLE_NAME} WHERE ${License.LICENSE_ID} = :licenseId" + ) fun getPrintsLeft(licenseId: String): Int? - @Query("UPDATE ${License.TABLE_NAME} SET ${License.RIGHTPRINT} = :quantity WHERE ${License.LICENSE_ID} = :licenseId") + @Query( + "UPDATE ${License.TABLE_NAME} SET ${License.RIGHTPRINT} = :quantity WHERE ${License.LICENSE_ID} = :licenseId" + ) fun setPrintsLeft(quantity: Int, licenseId: String) } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/public/Deprecated.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/public/Deprecated.kt index 18dd684d5e..b76f1bf63b 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/public/Deprecated.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/public/Deprecated.kt @@ -15,27 +15,66 @@ import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.LcpLicense import org.readium.r2.lcp.LcpService -@Deprecated("Renamed to `LcpService`", ReplaceWith("org.readium.r2.lcp.LcpService"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpService`", + ReplaceWith("org.readium.r2.lcp.LcpService"), + level = DeprecationLevel.ERROR +) public typealias LCPService = LcpService -@Deprecated("Renamed to `LcpService.AcquiredPublication`", ReplaceWith("org.readium.r2.lcp.LcpService.AcquiredPublication"), level = DeprecationLevel.ERROR) + +@Deprecated( + "Renamed to `LcpService.AcquiredPublication`", + ReplaceWith("org.readium.r2.lcp.LcpService.AcquiredPublication"), + level = DeprecationLevel.ERROR +) public typealias LCPImportedPublication = LcpService.AcquiredPublication + @Deprecated("Not used anymore", level = DeprecationLevel.ERROR) public typealias URLPresenter = () -> Unit -@Deprecated("Renamed to `LcpLicense`", ReplaceWith("org.readium.r2.lcp.LcpLicense"), level = DeprecationLevel.ERROR) + +@Deprecated( + "Renamed to `LcpLicense`", + ReplaceWith("org.readium.r2.lcp.LcpLicense"), + level = DeprecationLevel.ERROR +) public typealias LCPLicense = LcpLicense -@Deprecated("Renamed to `LcpAuthenticating`", ReplaceWith("org.readium.r2.lcp.LcpAuthenticating"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpAuthenticating`", + ReplaceWith("org.readium.r2.lcp.LcpAuthenticating"), + level = DeprecationLevel.ERROR +) public typealias LCPAuthenticating = LcpAuthenticating + @Deprecated("Not used anymore", level = DeprecationLevel.ERROR) public interface LCPAuthenticationDelegate -@Deprecated("Renamed to `LcpAuthenticating.AuthenticationReason`", ReplaceWith("org.readium.r2.lcp.LcpAuthenticating.AuthenticationReason"), level = DeprecationLevel.ERROR) + +@Deprecated( + "Renamed to `LcpAuthenticating.AuthenticationReason`", + ReplaceWith("org.readium.r2.lcp.LcpAuthenticating.AuthenticationReason"), + level = DeprecationLevel.ERROR +) public typealias LCPAuthenticationReason = LcpAuthenticating.AuthenticationReason -@Deprecated("Renamed to `LcpAuthenticating.AuthenticatedLicense`", ReplaceWith("org.readium.r2.lcp.LcpAuthenticating.AuthenticatedLicense"), level = DeprecationLevel.ERROR) + +@Deprecated( + "Renamed to `LcpAuthenticating.AuthenticatedLicense`", + ReplaceWith("org.readium.r2.lcp.LcpAuthenticating.AuthenticatedLicense"), + level = DeprecationLevel.ERROR +) public typealias LCPAuthenticatedLicense = LcpAuthenticating.AuthenticatedLicense -@Deprecated("Renamed to `LcpException", ReplaceWith("org.readium.r2.lcp.LcpException"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpException", + ReplaceWith("org.readium.r2.lcp.LcpException"), + level = DeprecationLevel.ERROR +) public typealias LCPError = LcpException -@Deprecated("Renamed to `LcpService()`", ReplaceWith("LcpService()"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed to `LcpService()`", + ReplaceWith("LcpService()"), + level = DeprecationLevel.ERROR +) +@Suppress("UNUSED_PARAMETER") public fun R2MakeLCPService(context: Context): LcpService? = - LcpService(context) + throw NotImplementedError() diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt index 053f49ea50..176331767c 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt @@ -24,7 +24,10 @@ import timber.log.Timber @OptIn(ExperimentalTime::class) internal class CRLService(val network: NetworkService, val context: Context) { - private val preferences: SharedPreferences = context.getSharedPreferences("org.readium.r2.lcp", Context.MODE_PRIVATE) + private val preferences: SharedPreferences = context.getSharedPreferences( + "org.readium.r2.lcp", + Context.MODE_PRIVATE + ) companion object { const val expiration = 7 @@ -55,7 +58,10 @@ internal class CRLService(val network: NetworkService, val context: Context) { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { "-----BEGIN X509 CRL-----${Base64.getEncoder().encodeToString(data)}-----END X509 CRL-----" } else { - "-----BEGIN X509 CRL-----${android.util.Base64.encodeToString(data, android.util.Base64.DEFAULT)}-----END X509 CRL-----" + "-----BEGIN X509 CRL-----${android.util.Base64.encodeToString( + data, + android.util.Base64.DEFAULT + )}-----END X509 CRL-----" } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/DeviceService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/DeviceService.kt index cde7889faf..29c22ad7c6 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/DeviceService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/DeviceService.kt @@ -29,7 +29,10 @@ internal class DeviceService( val context: Context ) : Serializable { - private val preferences: SharedPreferences = context.getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) + private val preferences: SharedPreferences = context.getSharedPreferences( + "org.readium.r2.settings", + Context.MODE_PRIVATE + ) val id: String get() { diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt index 39d90c3944..2a544d9fb0 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LcpClient.kt @@ -26,7 +26,12 @@ internal object LcpClient { fun toDRMContext(): Any = Class.forName("org.readium.lcp.sdk.DRMContext") - .getConstructor(String::class.java, String::class.java, String::class.java, String::class.java) + .getConstructor( + String::class.java, + String::class.java, + String::class.java, + String::class.java + ) .newInstance(hashedPassphrase, encryptedContentKey, token, profile) } @@ -46,7 +51,12 @@ internal object LcpClient { fun createContext(jsonLicense: String, hashedPassphrases: String, pemCrl: String): Context = try { val drmContext = klass - .getMethod("createContext", String::class.java, String::class.java, String::class.java) + .getMethod( + "createContext", + String::class.java, + String::class.java, + String::class.java + ) .invoke(instance, jsonLicense, hashedPassphrases, pemCrl)!! Context.fromDRMContext(drmContext) @@ -57,7 +67,11 @@ internal object LcpClient { fun decrypt(context: Context, encryptedData: ByteArray): ByteArray = try { klass - .getMethod("decrypt", Class.forName("org.readium.lcp.sdk.DRMContext"), ByteArray::class.java) + .getMethod( + "decrypt", + Class.forName("org.readium.lcp.sdk.DRMContext"), + ByteArray::class.java + ) .invoke(instance, context.toDRMContext(), encryptedData) as ByteArray } catch (e: InvocationTargetException) { @@ -74,11 +88,11 @@ internal object LcpClient { } private fun mapException(e: Throwable): LcpException { - val drmExceptionClass = Class.forName("org.readium.lcp.sdk.DRMException") - if (!drmExceptionClass.isInstance(e)) + if (!drmExceptionClass.isInstance(e)) { return LcpException.Runtime("the Lcp client threw an unhandled exception") + } val drmError = drmExceptionClass .getMethod("getDrmError") diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index 03e88852ad..b0e0b6d78a 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -30,13 +30,11 @@ import org.readium.r2.lcp.license.container.LicenseContainer import org.readium.r2.lcp.license.container.createLicenseContainer import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.tryOr import org.readium.r2.shared.publication.protection.ContentProtection -import org.readium.r2.shared.resource.ArchiveFactory -import org.readium.r2.shared.resource.ResourceFactory import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber internal class LicensesService( @@ -46,17 +44,13 @@ internal class LicensesService( private val network: NetworkService, private val passphrases: PassphrasesService, private val context: Context, - private val mediaTypeRetriever: MediaTypeRetriever, - private val resourceFactory: ResourceFactory, - private val archiveFactory: ArchiveFactory + private val assetRetriever: AssetRetriever ) : LcpService, CoroutineScope by MainScope() { - override suspend fun isLcpProtected(file: File): Boolean = - tryOr(false) { - val mediaType = mediaTypeRetriever.retrieve(file) ?: return false - createLicenseContainer(file, mediaType).read() - true - } + override suspend fun isLcpProtected(file: File): Boolean { + val asset = assetRetriever.retrieve(file) ?: return false + return isLcpProtected(asset) + } override suspend fun isLcpProtected(asset: Asset): Boolean = tryOr(false) { @@ -71,9 +65,9 @@ internal class LicensesService( } override fun contentProtection( - authentication: LcpAuthenticating, + authentication: LcpAuthenticating ): ContentProtection = - LcpContentProtection(this, authentication, mediaTypeRetriever, resourceFactory, archiveFactory) + LcpContentProtection(this, authentication, assetRetriever) override suspend fun acquirePublication(lcpl: ByteArray, onProgress: (Double) -> Unit): Try = try { @@ -93,7 +87,13 @@ internal class LicensesService( ): Try = try { val container = createLicenseContainer(file, mediaType) - val license = retrieveLicense(container, authentication, allowUserInteraction, true, sender) + val license = retrieveLicense( + container, + authentication, + allowUserInteraction, + true, + sender + ) Try.success(license) } catch (e: Exception) { Try.failure(LcpException.wrap(e)) @@ -107,7 +107,13 @@ internal class LicensesService( ): Try = try { val licenseContainer = createLicenseContainer(asset) - val license = retrieveLicense(licenseContainer, authentication, allowUserInteraction, false, sender) + val license = retrieveLicense( + licenseContainer, + authentication, + allowUserInteraction, + false, + sender + ) Try.success(license) } catch (e: Exception) { Try.failure(LcpException.wrap(e)) @@ -167,7 +173,6 @@ internal class LicensesService( sender: Any?, completion: (License) -> Unit ) { - var initialData = container.read() Timber.d("license ${LicenseDocument(data = initialData).json}") @@ -203,7 +208,15 @@ internal class LicensesService( Timber.d("validated documents $it") try { documents.getContext() - completion(License(documents = it, validation = validation, licenses = this.licenses, device = this.device, network = this.network)) + completion( + License( + documents = it, + validation = validation, + licenses = this.licenses, + device = this.device, + network = this.network + ) + ) } catch (e: Exception) { throw e } @@ -218,18 +231,21 @@ internal class LicensesService( } private suspend fun fetchPublication(license: LicenseDocument, onProgress: (Double) -> Unit): LcpService.AcquiredPublication { - val link = license.link(LicenseDocument.Rel.publication) + val link = license.link(LicenseDocument.Rel.Publication) val url = link?.url - ?: throw LcpException.Parsing.Url(rel = LicenseDocument.Rel.publication.value) + ?: throw LcpException.Parsing.Url(rel = LicenseDocument.Rel.Publication.value) val destination = withContext(Dispatchers.IO) { File.createTempFile("lcp-${System.currentTimeMillis()}", ".tmp") } Timber.i("LCP destination $destination") - val mediaType = network.download(url, destination, mediaType = link.type, onProgress = onProgress) - ?: mediaTypeRetriever.retrieve(mediaType = link.type) - ?: MediaType.EPUB + val mediaType = network.download( + url, + destination, + mediaType = link.type, + onProgress = onProgress + ) ?: link.mediaType // Saves the License Document into the downloaded publication val container = createLicenseContainer(destination, mediaType) @@ -242,4 +258,14 @@ internal class LicensesService( licenseDocument = license ) } + + private val MediaType.fileExtension: String get() = + when { + matches(MediaType.DIVINA) -> "divina" + matches(MediaType.EPUB) -> "epub" + matches(MediaType.LCP_PROTECTED_PDF) -> "pdf" + matches(MediaType.READIUM_AUDIOBOOK) -> "audiobook" + matches(MediaType.READIUM_WEBPUB) -> "webpub" + else -> "epub" + } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt index 1de9ddf4e7..cae98e3152 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt @@ -21,14 +21,18 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.lcp.LcpException import org.readium.r2.shared.error.Try -import org.readium.r2.shared.util.http.retrieve +import org.readium.r2.shared.util.http.invoke import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeHints import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber internal typealias URLParameters = Map -internal class NetworkException(val status: Int?, cause: Throwable? = null) : Exception("Network failure with status $status", cause) +internal class NetworkException(val status: Int?, cause: Throwable? = null) : Exception( + "Network failure with status $status", + cause +) internal class NetworkService( private val mediaTypeRetriever: MediaTypeRetriever @@ -51,7 +55,9 @@ internal class NetworkService( withContext(Dispatchers.IO) { try { @Suppress("NAME_SHADOWING") - val url = URL(Uri.parse(url).buildUpon().appendQueryParameters(parameters).build().toString()) + val url = URL( + Uri.parse(url).buildUpon().appendQueryParameters(parameters).build().toString() + ) val connection = url.openConnection() as HttpURLConnection connection.requestMethod = method.value @@ -133,10 +139,7 @@ internal class NetworkService( } } - mediaTypeRetriever.retrieve( - connection = connection, - mediaType = mediaType - ) + mediaTypeRetriever.retrieve(MediaTypeHints(connection, mediaType = mediaType)) } catch (e: Exception) { Timber.e(e) throw LcpException.Network(e) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/PassphrasesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/PassphrasesService.kt index bc9be10499..5e3cd53012 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/PassphrasesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/PassphrasesService.kt @@ -29,7 +29,13 @@ internal class PassphrasesService(private val repository: PassphrasesRepository) } return when { passphrase != null -> passphrase - authentication != null -> this@PassphrasesService.authenticate(license, LcpAuthenticating.AuthenticationReason.PassphraseNotFound, authentication, allowUserInteraction, sender) + authentication != null -> this@PassphrasesService.authenticate( + license, + LcpAuthenticating.AuthenticationReason.PassphraseNotFound, + authentication, + allowUserInteraction, + sender + ) else -> null } } @@ -42,7 +48,12 @@ internal class PassphrasesService(private val repository: PassphrasesRepository) sender: Any? ): String? { val authenticatedLicense = LcpAuthenticating.AuthenticatedLicense(document = license) - val clearPassphrase = authentication.retrievePassphrase(authenticatedLicense, reason, allowUserInteraction, sender) + val clearPassphrase = authentication.retrievePassphrase( + authenticatedLicense, + reason, + allowUserInteraction, + sender + ) ?: return null val hashedPassphrase = HASH.sha256(clearPassphrase) val passphrases = mutableListOf(hashedPassphrase) @@ -57,7 +68,13 @@ internal class PassphrasesService(private val repository: PassphrasesRepository) addPassphrase(passphrase, true, license.id, license.provider, license.user.id) passphrase } catch (e: Exception) { - authenticate(license, LcpAuthenticating.AuthenticationReason.InvalidPassphrase, authentication, allowUserInteraction, sender) + authenticate( + license, + LcpAuthenticating.AuthenticationReason.InvalidPassphrase, + authentication, + allowUserInteraction, + sender + ) } } diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt index 06e3073c23..24be368a33 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt @@ -19,20 +19,28 @@ import com.google.android.exoplayer2.upstream.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.buffered import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.buffered -public sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException(message, cause) { +public sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException( + message, + cause +) { public class NotOpened(message: String) : ExoPlayerDataSourceException(message, null) public class NotFound(message: String) : ExoPlayerDataSourceException(message, null) - public class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : ExoPlayerDataSourceException("Failed to read $readLength bytes of URI $uri at offset $offset.", cause) + public class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : ExoPlayerDataSourceException( + "Failed to read $readLength bytes of URI $uri at offset $offset.", + cause + ) } /** * An ExoPlayer's [DataSource] which retrieves resources from a [Publication]. */ -public class ExoPlayerDataSource internal constructor(private val publication: Publication) : BaseDataSource(/* isNetwork = */ true) { +public class ExoPlayerDataSource internal constructor(private val publication: Publication) : BaseDataSource(/* isNetwork = */ + true +) { public class Factory( private val publication: Publication, @@ -48,16 +56,18 @@ public class ExoPlayerDataSource internal constructor(private val publication: P } private data class OpenedResource( - val resource: Fetcher.Resource, + val resource: Resource, val uri: Uri, - var position: Long, + var position: Long ) private var openedResource: OpenedResource? = null override fun open(dataSpec: DataSpec): Long { val link = publication.linkWithHref(dataSpec.uri.toString()) - ?: throw ExoPlayerDataSourceException.NotFound("Can't find a [Link] for URI: ${dataSpec.uri}. Make sure you only request resources declared in the manifest.") + ?: throw ExoPlayerDataSourceException.NotFound( + "Can't find a [Link] for URI: ${dataSpec.uri}. Make sure you only request resources declared in the manifest." + ) val resource = publication.get(link) // Significantly improves performances, in particular with deflated ZIP entries. @@ -66,7 +76,7 @@ public class ExoPlayerDataSource internal constructor(private val publication: P openedResource = OpenedResource( resource = resource, uri = dataSpec.uri, - position = dataSpec.position, + position = dataSpec.position ) val bytesToRead = @@ -84,7 +94,7 @@ public class ExoPlayerDataSource internal constructor(private val publication: P /** Cached content lengths indexed by their URL. */ private var cachedLengths: MutableMap = mutableMapOf() - private fun contentLengthOf(uri: Uri, resource: Fetcher.Resource): Long? { + private fun contentLengthOf(uri: Uri, resource: Resource): Long? { cachedLengths[uri.toString()]?.let { return it } val length = runBlocking { resource.length() }.getOrNull() @@ -99,7 +109,9 @@ public class ExoPlayerDataSource internal constructor(private val publication: P return 0 } - val openedResource = openedResource ?: throw ExoPlayerDataSourceException.NotOpened("No opened resource to read from. Did you call open()?") + val openedResource = openedResource ?: throw ExoPlayerDataSourceException.NotOpened( + "No opened resource to read from. Did you call open()?" + ) try { val data = runBlocking { diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt index 9453e48bbb..8b6cc4f60f 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt @@ -127,15 +127,18 @@ public class MediaNavigator private constructor( this.playerFacade.playlist!!.metadata.durations?.sum() private fun computeLocator( - item: ItemState, + item: ItemState ): Locator { val playlist = this.playerFacade.playlist!!.map { it.metadata!! } val position = item.position val link = publication.readingOrder[item.index] val itemStartPosition = playlist.slice(0 until item.index).durations?.sum() val totalProgression = - if (itemStartPosition == null) null - else totalDuration?.let { (itemStartPosition + position) / it } + if (itemStartPosition == null) { + null + } else { + totalDuration?.let { (itemStartPosition + position) / it } + } val locator = requireNotNull(publication.locatorFromLink(link)) return locator.copyWithLocations( @@ -317,7 +320,7 @@ public class MediaNavigator private constructor( public data class Configuration( val positionRefreshRate: Double = 2.0, // Hz val skipForwardInterval: Duration = 30.seconds, - val skipBackwardInterval: Duration = 30.seconds, + val skipBackwardInterval: Duration = 30.seconds ) @ExperimentalTime @@ -394,7 +397,6 @@ public class MediaNavigator private constructor( player: SessionPlayer = createPlayer(context, publication), metadataFactory: MediaMetadataFactory = DefaultMetadataFactory(publication) ): Try { - val positionRefreshDelay = (1.0 / configuration.positionRefreshRate).seconds val seekCompletedChannel = Channel(Channel.UNLIMITED) val callback = SessionPlayerCallback(positionRefreshDelay, seekCompletedChannel) @@ -462,9 +464,10 @@ public class MediaNavigator private constructor( } internal fun SessionPlayerResult.toNavigatorResult(): Try = - if (isSuccess) + if (isSuccess) { Try.success(Unit) - else + } else { this.mapFailure { Exception.SessionPlayer(it.error) } + } } } diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/OptIn.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/OptIn.kt index a7a8d423e5..cb209b8ed3 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/OptIn.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/OptIn.kt @@ -13,5 +13,10 @@ package org.readium.navigator.media2 message = "The new Audiobook navigator is still experimental. The API may be changed in the future without notice." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class ExperimentalMedia2 diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt index 89f7e085ec..5a267e6c78 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt @@ -44,7 +44,7 @@ import timber.log.Timber internal class SessionPlayerFacade( private val sessionPlayer: SessionPlayer, private val seekCompletedReceiver: ReceiveChannel, - playerStateFlow: Flow, + playerStateFlow: Flow ) { private val coroutineScope = MainScope() diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt index 70e19e83c2..7941b5e349 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt @@ -106,7 +106,7 @@ internal data class ItemState( val index: Int, val position: Duration, val buffered: Duration, - val duration: Duration?, + val duration: Duration? ) @OptIn(ExperimentalTime::class) @@ -149,10 +149,11 @@ internal val SessionPlayer.currentDuration: Duration? @ExperimentalTime private fun msToDuration(ms: Long): Duration? = - if (ms == SessionPlayer.UNKNOWN_TIME) + if (ms == SessionPlayer.UNKNOWN_TIME) { null - else + } else { ms.milliseconds + } @ExperimentalTime internal val MediaMetadata.duration: Duration? diff --git a/readium/navigator-media2/src/test/java/org/readium/navigator/media2/SmartSeekerTest.kt b/readium/navigator-media2/src/test/java/org/readium/navigator/media2/SmartSeekerTest.kt index 52713327b7..6337faadeb 100644 --- a/readium/navigator-media2/src/test/java/org/readium/navigator/media2/SmartSeekerTest.kt +++ b/readium/navigator-media2/src/test/java/org/readium/navigator/media2/SmartSeekerTest.kt @@ -10,7 +10,14 @@ import org.junit.Test class SmartSeekerTest { private val playlist: List = listOf( - 10, 20, 15, 800, 10, 230, 20, 10 + 10, + 20, + 15, + 800, + 10, + 230, + 20, + 10 ).map { it.seconds } private val forwardOffset = 50.seconds diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/DecorableNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/DecorableNavigator.kt index 4cdfe7f5d9..01c48ce8c7 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/DecorableNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/DecorableNavigator.kt @@ -118,6 +118,7 @@ public data class Decoration( @ColorInt override val tint: Int, override val isActive: Boolean = false ) : Style, Tinted, Activable + @Parcelize public data class Underline( @ColorInt override val tint: Int, @@ -161,7 +162,9 @@ public sealed class DecorationChange { * The changes need to be applied in the same order, one by one. */ @ExperimentalDecorator -public suspend fun List.changesByHref(target: List): Map> = withContext(Dispatchers.Default) { +public suspend fun List.changesByHref(target: List): Map> = withContext( + Dispatchers.Default +) { val source = this@changesByHref val result = DiffUtil.calculateDiff(object : DiffUtil.Callback() { override fun getOldListSize(): Int = source.size @@ -203,7 +206,14 @@ public suspend fun List.changesByHref(target: List): Map override fun onMoved(fromPosition: Int, toPosition: Int) { val decoration = target[toPosition] - registerChange(DecorationChange.Moved(decoration.id, fromPosition = fromPosition, toPosition = toPosition), decoration.locator) + registerChange( + DecorationChange.Moved( + decoration.id, + fromPosition = fromPosition, + toPosition = toPosition + ), + decoration.locator + ) } override fun onChanged(position: Int, count: Int, payload: Any?) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt index c3cc78c5e9..d38b00fdb2 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt @@ -89,9 +89,18 @@ public interface Navigator { public fun onJumpToLocator(locator: Locator) {} } - @Deprecated("Use [currentLocator.value] instead", ReplaceWith("currentLocator.value"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [currentLocator.value] instead", + ReplaceWith("currentLocator.value"), + level = DeprecationLevel.ERROR + ) public val currentLocation: Locator? get() = currentLocator.value - @Deprecated("Use [VisualNavigator.Listener] instead", ReplaceWith("VisualNavigator.Listener"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [VisualNavigator.Listener] instead", + ReplaceWith("VisualNavigator.Listener"), + level = DeprecationLevel.ERROR + ) public interface VisualListener : VisualNavigator.Listener } @@ -159,10 +168,13 @@ public interface VisualNavigator : Navigator { public interface Listener : Navigator.Listener { @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) public fun onTap(point: PointF): Boolean = false + @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) public fun onDragStart(startPoint: PointF, offset: PointF): Boolean = false + @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) public fun onDragMove(startPoint: PointF, offset: PointF): Boolean = false + @Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR) public fun onDragEnd(startPoint: PointF, offset: PointF): Boolean = false } @@ -170,7 +182,11 @@ public interface VisualNavigator : Navigator { /** * Current reading progression direction. */ - @Deprecated("Use `presentation.value.readingProgression` instead", ReplaceWith("presentation.value.readingProgression"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `presentation.value.readingProgression` instead", + ReplaceWith("presentation.value.readingProgression"), + level = DeprecationLevel.ERROR + ) public val readingProgression: PublicationReadingProgression } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/OptIn.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/OptIn.kt index 8f6a6bcc0d..f0b7e67406 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/OptIn.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/OptIn.kt @@ -11,7 +11,12 @@ package org.readium.r2.navigator message = "Support for the Decorator API is still experimental. The API may be changed in the future without notice." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class ExperimentalDecorator @RequiresOptIn( @@ -19,7 +24,12 @@ public annotation class ExperimentalDecorator message = "The new Audiobook navigator is still experimental. The API may be changed in the future without notice." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class ExperimentalAudiobook @RequiresOptIn( @@ -27,5 +37,10 @@ public annotation class ExperimentalAudiobook message = "The new dragging gesture is still experimental. The API may be changed in the future without notice." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class ExperimentalDragGesture diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt index d11ca5f146..4034ac1942 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt @@ -45,9 +45,9 @@ import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.optNullableString import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.use @@ -79,12 +79,15 @@ internal open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebV @InternalReadiumApi fun javascriptInterfacesForResource(link: Link): Map = emptyMap() + @InternalReadiumApi fun shouldOverrideUrlLoading(webView: WebView, request: WebResourceRequest): Boolean = false + @InternalReadiumApi fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? = null + @InternalReadiumApi - fun resourceAtUrl(url: String): Fetcher.Resource? = null + fun resourceAtUrl(url: String): Resource? = null /** * Requests to load the next resource in the reading order. @@ -94,13 +97,16 @@ internal open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebV */ @InternalReadiumApi fun goToNextResource(jump: Boolean, animated: Boolean): Boolean = false + @InternalReadiumApi fun goToPreviousResource(jump: Boolean, animated: Boolean): Boolean = false @Deprecated("Not available anymore", level = DeprecationLevel.ERROR) fun onScroll() {} + @Deprecated("Not available anymore", level = DeprecationLevel.ERROR) fun onHighlightActivated(id: String) {} + @Deprecated("Not available anymore", level = DeprecationLevel.ERROR) fun onHighlightAnnotationMarkActivated(id: String) {} } @@ -637,7 +643,10 @@ internal open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebV ?: return super.startActionMode(callback, type) val parent = parent ?: return null - val wrapper = Callback2Wrapper(customCallback, callback2 = callback as? ActionMode.Callback2) + val wrapper = Callback2Wrapper( + customCallback, + callback2 = callback as? ActionMode.Callback2 + ) return parent.startActionModeForChild(this, wrapper, type) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt index d552d3259b..4f3b9be446 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt @@ -131,6 +131,7 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView * Determines speed during touch scrolling */ private var mVelocityTracker: VelocityTracker? = null + /** Initial velocity of the current movement. */ private var mInitialVelocity: Int? = null private var mMinimumVelocity: Int = 0 @@ -246,7 +247,9 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView val count = childCount while (i < count) { val childInsets = ViewCompat - .dispatchApplyWindowInsets(getChildAt(i), applied).getInsets(WindowInsetsCompat.Type.systemBars()) + .dispatchApplyWindowInsets(getChildAt(i), applied).getInsets( + WindowInsetsCompat.Type.systemBars() + ) // Now keep track of any consumed by tracking each dimension's min // value res.left = min( @@ -270,7 +273,10 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView // Now return a new WindowInsets, using the consumed window insets return WindowInsetsCompat.Builder(applied) - .setInsets(WindowInsetsCompat.Type.systemBars(), Insets.of(res.left, res.top, res.right, res.bottom)) + .setInsets( + WindowInsetsCompat.Type.systemBars(), + Insets.of(res.left, res.top, res.right, res.bottom) + ) .build() } } @@ -429,7 +435,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } private fun infoForPosition(position: Int): ItemInfo { - val ii = ItemInfo() ii.position = position ii.offset = (position * (1 / numPages)).toFloat() @@ -529,7 +534,8 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } childLeft += scrollX child.layout( - childLeft, childTop, + childLeft, + childTop, childLeft + child.measuredWidth, childTop + child.measuredHeight ) @@ -681,7 +687,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } override fun onTouchEvent(ev: MotionEvent): Boolean { - if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain() } @@ -689,7 +694,6 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView val action = ev.action when (action and MotionEvent.ACTION_MASK) { - MotionEvent.ACTION_DOWN -> { mScroller?.let { scroller -> mHasAbortedScroller = !scroller.isFinished @@ -717,10 +721,11 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView if (xDiff > mTouchSlop) { if (DEBUG) Timber.v("Starting drag!") mIsBeingDragged = true - mLastMotionX = if (x - mInitialMotionX > 0) + mLastMotionX = if (x - mInitialMotionX > 0) { mInitialMotionX + mTouchSlop - else + } else { mInitialMotionX - mTouchSlop + } setScrollState(SCROLL_STATE_DRAGGING) } } @@ -856,8 +861,11 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView val isCancelled = (initialVelocity * currentVelocity) <= 0 return if (!isCancelled && abs(deltaX) > mFlingDistance && abs(currentVelocity) > mMinimumVelocity) { - if (currentVelocity >= 0) currentPage - 1 - else currentPage + 1 + if (currentVelocity >= 0) { + currentPage - 1 + } else { + currentPage + 1 + } } else { currentPage } @@ -898,7 +906,10 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } else { arrowScroll(View.FOCUS_LEFT) } - KeyEvent.KEYCODE_DPAD_RIGHT -> handled = if (event.hasModifiers(KeyEvent.META_ALT_ON)) { + KeyEvent.KEYCODE_DPAD_RIGHT -> handled = if (event.hasModifiers( + KeyEvent.META_ALT_ON + ) + ) { pageRight() } else { arrowScroll(View.FOCUS_RIGHT) @@ -945,7 +956,12 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView sb.append(" => ").append(parent.javaClass.simpleName) parent = parent.parent } - if (DEBUG) Timber.e("arrowScroll tried to find focus based on non-child current focused view %s", sb.toString()) + if (DEBUG) { + Timber.e( + "arrowScroll tried to find focus based on non-child current focused view %s", + sb.toString() + ) + } currentFocused = null } } @@ -953,7 +969,8 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView var handled = false val nextFocused = FocusFinder.getInstance().findNextFocus( - this, currentFocused, + this, + currentFocused, direction ) if (nextFocused != null && nextFocused !== currentFocused) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/SelectableNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/SelectableNavigator.kt index 7a4de33621..47db897f81 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/SelectableNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/SelectableNavigator.kt @@ -30,5 +30,5 @@ public interface SelectableNavigator : Navigator { */ public data class Selection( val locator: Locator, - val rect: RectF?, + val rect: RectF? ) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/SimplePresentation.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/SimplePresentation.kt index 2ed0701376..bae45376ad 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/SimplePresentation.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/SimplePresentation.kt @@ -16,5 +16,5 @@ import org.readium.r2.shared.InternalReadiumApi public data class SimplePresentation( override val readingProgression: ReadingProgression, override val scroll: Boolean, - override val axis: Axis, + override val axis: Axis ) : VisualNavigator.Presentation diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt index 30bf2164f3..2ccdf23ce4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt @@ -19,20 +19,28 @@ import com.google.android.exoplayer2.upstream.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.buffered import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.buffered -internal sealed class PublicationDataSourceException(message: String, cause: Throwable?) : IOException(message, cause) { +internal sealed class PublicationDataSourceException(message: String, cause: Throwable?) : IOException( + message, + cause +) { class NotOpened(message: String) : PublicationDataSourceException(message, null) class NotFound(message: String) : PublicationDataSourceException(message, null) - class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : PublicationDataSourceException("Failed to read $readLength bytes of URI $uri at offset $offset.", cause) + class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : PublicationDataSourceException( + "Failed to read $readLength bytes of URI $uri at offset $offset.", + cause + ) } /** * An ExoPlayer's [DataSource] which retrieves resources from a [Publication]. */ -internal class PublicationDataSource(private val publication: Publication) : BaseDataSource(/* isNetwork = */ true) { +internal class PublicationDataSource(private val publication: Publication) : BaseDataSource(/* isNetwork = */ + true +) { class Factory( private val publication: Publication, @@ -48,16 +56,18 @@ internal class PublicationDataSource(private val publication: Publication) : Bas } private data class OpenedResource( - val resource: Fetcher.Resource, + val resource: Resource, val uri: Uri, - var position: Long, + var position: Long ) private var openedResource: OpenedResource? = null override fun open(dataSpec: DataSpec): Long { val link = publication.linkWithHref(dataSpec.uri.toString()) - ?: throw PublicationDataSourceException.NotFound("Can't find a [Link] for URI: ${dataSpec.uri}. Make sure you only request resources declared in the manifest.") + ?: throw PublicationDataSourceException.NotFound( + "Can't find a [Link] for URI: ${dataSpec.uri}. Make sure you only request resources declared in the manifest." + ) val resource = publication.get(link) // Significantly improves performances, in particular with deflated ZIP entries. @@ -66,7 +76,7 @@ internal class PublicationDataSource(private val publication: Publication) : Bas openedResource = OpenedResource( resource = resource, uri = dataSpec.uri, - position = dataSpec.position, + position = dataSpec.position ) val bytesToRead = @@ -84,7 +94,7 @@ internal class PublicationDataSource(private val publication: Publication) : Bas /** Cached content lengths indexed by their URL. */ private var cachedLengths: MutableMap = mutableMapOf() - private fun contentLengthOf(uri: Uri, resource: Fetcher.Resource): Long? { + private fun contentLengthOf(uri: Uri, resource: Resource): Long? { cachedLengths[uri.toString()]?.let { return it } val length = runBlocking { resource.length() }.getOrNull() @@ -99,7 +109,9 @@ internal class PublicationDataSource(private val publication: Publication) : Bas return 0 } - val openedResource = openedResource ?: throw PublicationDataSourceException.NotOpened("No opened resource to read from. Did you call open()?") + val openedResource = openedResource ?: throw PublicationDataSourceException.NotOpened( + "No opened resource to read from. Did you call open()?" + ) try { val data = runBlocking { @@ -125,7 +137,12 @@ internal class PublicationDataSource(private val publication: Publication) : Bas if (e is InterruptedException) { return 0 } - throw PublicationDataSourceException.ReadFailed(uri = openedResource.uri, offset = offset, readLength = length, cause = e) + throw PublicationDataSourceException.ReadFailed( + uri = openedResource.uri, + offset = offset, + readLength = length, + cause = e + ) } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt similarity index 71% rename from readium/navigator/src/main/java/org/readium/r2/navigator/cbz/Deprecated.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt index d211019076..4cb2af80f1 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/Deprecated.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/cbz/R2CbzActivity.kt @@ -9,8 +9,8 @@ package org.readium.r2.navigator.cbz -@Deprecated("Use ImageNavigatorFragment in your own activity instead.", level = DeprecationLevel.ERROR) +@Deprecated( + "Use ImageNavigatorFragment in your own activity instead.", + level = DeprecationLevel.ERROR +) public open class R2CbzActivity - -// This is for lint to pass. -private val fake = null diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/divina/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/divina/R2DiViNaActivity.kt similarity index 90% rename from readium/navigator/src/main/java/org/readium/r2/navigator/divina/Deprecated.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/divina/R2DiViNaActivity.kt index 7e29966515..e4c655e3fb 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/divina/Deprecated.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/divina/R2DiViNaActivity.kt @@ -14,6 +14,3 @@ package org.readium.r2.navigator.divina level = DeprecationLevel.ERROR ) public open class R2DiViNaActivity - -// This is for lint to pass. -private val fake = null diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/Deprecated.kt index 85772e8a3e..356baf0bd9 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/Deprecated.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/Deprecated.kt @@ -8,7 +8,10 @@ package org.readium.r2.navigator.epub import org.readium.r2.shared.publication.Locator -@Deprecated("Use EpubNavigatorFragment in your own activity instead.", level = DeprecationLevel.ERROR) +@Deprecated( + "Use EpubNavigatorFragment in your own activity instead.", + level = DeprecationLevel.ERROR +) public open class R2EpubActivity @Deprecated("Use Decorator API instead.", level = DeprecationLevel.ERROR) @@ -21,7 +24,7 @@ public data class Highlight( @Deprecated("Use Decorator API instead.", level = DeprecationLevel.ERROR) public enum class Style { - highlight, underline, strikethrough + Highlight, Underline, Strikethrough } @Deprecated("Use navigator fragments.", level = DeprecationLevel.ERROR) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt index 56f0437459..180d23d3b0 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFactory.kt @@ -32,7 +32,7 @@ public class EpubNavigatorFactory( * @param defaults navigator fallbacks for some preferences */ public data class Configuration( - val defaults: EpubDefaults = EpubDefaults(), + val defaults: EpubDefaults = EpubDefaults() ) private val layout: EpubLayout = @@ -44,7 +44,7 @@ public class EpubNavigatorFactory( initialPreferences: EpubPreferences = EpubPreferences(), listener: EpubNavigatorFragment.Listener? = null, paginationListener: EpubNavigatorFragment.PaginationListener? = null, - configuration: EpubNavigatorFragment.Configuration = EpubNavigatorFragment.Configuration(), + configuration: EpubNavigatorFragment.Configuration = EpubNavigatorFragment.Configuration() ): FragmentFactory = org.readium.r2.navigator.util.createFragmentFactory { EpubNavigatorFragment( publication = publication, @@ -59,7 +59,7 @@ public class EpubNavigatorFactory( } public fun createPreferencesEditor( - currentPreferences: EpubPreferences, + currentPreferences: EpubPreferences ): EpubPreferencesEditor = EpubPreferencesEditor( initialPreferences = currentPreferences, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt index 218129766e..7607939b78 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt @@ -42,7 +42,15 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.json.JSONObject -import org.readium.r2.navigator.* +import org.readium.r2.navigator.DecorableNavigator +import org.readium.r2.navigator.Decoration +import org.readium.r2.navigator.DecorationId +import org.readium.r2.navigator.ExperimentalDecorator +import org.readium.r2.navigator.R +import org.readium.r2.navigator.R2BasicWebView +import org.readium.r2.navigator.SelectableNavigator +import org.readium.r2.navigator.Selection +import org.readium.r2.navigator.VisualNavigator import org.readium.r2.navigator.databinding.ReadiumNavigatorViewpagerBinding import org.readium.r2.navigator.epub.EpubNavigatorViewModel.RunScriptCommand import org.readium.r2.navigator.epub.css.FontFamilyDeclaration @@ -68,7 +76,6 @@ import org.readium.r2.navigator.preferences.ReadingProgression import org.readium.r2.shared.DelicateReadiumApi import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.extensions.tryOrLog -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication @@ -77,6 +84,7 @@ import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.publication.presentation.presentation import org.readium.r2.shared.publication.services.isRestricted import org.readium.r2.shared.publication.services.positionsByReadingOrder +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.launchWebBrowser import org.readium.r2.shared.util.mediatype.MediaType @@ -101,7 +109,7 @@ public class EpubNavigatorFragment internal constructor( internal val paginationListener: PaginationListener?, epubLayout: EpubLayout, private val defaults: EpubDefaults, - configuration: Configuration, + configuration: Configuration ) : Fragment(), VisualNavigator, SelectableNavigator, DecorableNavigator, Configurable { // Make a copy to prevent the user from modifying the configuration after initialization. @@ -189,7 +197,7 @@ public class EpubNavigatorFragment internal constructor( readiumCssRsProperties: RsProperties = RsProperties(), decorationTemplates: HtmlDecorationTemplates = HtmlDecorationTemplates.defaultTemplates(), selectionActionModeCallback: ActionMode.Callback? = null, - shouldApplyInsetsPadding: Boolean? = true, + shouldApplyInsetsPadding: Boolean? = true ) : this( servedAssets = servedAssets, readiumCssRsProperties = readiumCssRsProperties, @@ -269,7 +277,8 @@ public class EpubNavigatorFragment internal constructor( private val viewModel: EpubNavigatorViewModel by viewModels { EpubNavigatorViewModel.createFactory( - requireActivity().application, publication, + requireActivity().application, + publication, config = this.config, initialPreferences = initialPreferences, layout = epubLayout, @@ -285,11 +294,12 @@ public class EpubNavigatorFragment internal constructor( private lateinit var resourcesSingle: List private lateinit var resourcesDouble: List - @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) + @Deprecated( + "Migrate to the new Settings API (see migration guide)", + level = DeprecationLevel.ERROR + ) public val preferences: SharedPreferences get() = throw NotImplementedError() - private lateinit var publicationIdentifier: String - internal var currentPagerPosition: Int = 0 internal lateinit var adapter: R2PagerAdapter private lateinit var currentActivity: FragmentActivity @@ -308,7 +318,6 @@ public class EpubNavigatorFragment internal constructor( positionsByReadingOrder = runBlocking { publication.positionsByReadingOrder() } positions = positionsByReadingOrder.flatten() - publicationIdentifier = publication.metadata.identifier ?: publication.metadata.title when (viewModel.layout) { EpubLayout.REFLOWABLE -> { @@ -347,7 +356,7 @@ public class EpubNavigatorFragment internal constructor( leftLink = doublePageLeft, leftUrl = viewModel.urlTo(doublePageLeft), rightLink = doublePageRight, - rightUrl = viewModel.urlTo(doublePageRight), + rightUrl = viewModel.urlTo(doublePageRight) ) ) doublePageLeft = null @@ -483,7 +492,13 @@ public class EpubNavigatorFragment internal constructor( withStarted { // Restore the last locator before a configuration change (e.g. screen rotation), or the // initial locator when given. - val locator = savedInstanceState?.let { BundleCompat.getParcelable(it, "locator", Locator::class.java) } + val locator = savedInstanceState?.let { + BundleCompat.getParcelable( + it, + "locator", + Locator::class.java + ) + } ?: initialLocator if (locator != null) { go(locator) @@ -583,7 +598,6 @@ public class EpubNavigatorFragment internal constructor( if (publication.metadata.presentation.layout != EpubLayout.FIXED) { setCurrent(resourcesSingle) } else { - when (viewModel.dualPageMode) { // FIXME: Properly implement DualPage.AUTO depending on the device orientation. DualPage.OFF, DualPage.AUTO -> { @@ -793,7 +807,7 @@ public class EpubNavigatorFragment internal constructor( override fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? = viewModel.shouldInterceptRequest(request) - override fun resourceAtUrl(url: String): Fetcher.Resource? = + override fun resourceAtUrl(url: String): Resource? = viewModel.internalLinkFromUrl(url) ?.let { publication.get(it) } } @@ -892,8 +906,11 @@ public class EpubNavigatorFragment internal constructor( ?.let { publication.locatorFromLink(it) } private val r2PagerAdapter: R2PagerAdapter? - get() = if (::resourcePager.isInitialized) resourcePager.adapter as? R2PagerAdapter - else null + get() = if (::resourcePager.isInitialized) { + resourcePager.adapter as? R2PagerAdapter + } else { + null + } private val currentReflowablePageFragment: R2EpubPageFragment? get() = currentFragment as? R2EpubPageFragment @@ -938,7 +955,7 @@ public class EpubNavigatorFragment internal constructor( return currentReflowablePageFragment?.webView?.findFirstVisibleLocator() ?.copy( href = resource.href, - type = resource.type ?: MediaType.XHTML.toString() + type = (resource.mediaType ?: MediaType.XHTML).toString() ) } @@ -994,9 +1011,13 @@ public class EpubNavigatorFragment internal constructor( } ?: 0.0 val link = when (val pageResource = adapter.getResource(resourcePager.currentItem)) { - is PageResource.EpubFxl -> checkNotNull(pageResource.leftLink ?: pageResource.rightLink) + is PageResource.EpubFxl -> checkNotNull( + pageResource.leftLink ?: pageResource.rightLink + ) is PageResource.EpubReflowable -> pageResource.link - else -> throw IllegalStateException("Expected EpubFxl or EpubReflowable page resources") + else -> throw IllegalStateException( + "Expected EpubFxl or EpubReflowable page resources" + ) } val positionLocator = publication.positionsByResource[link.href]?.let { positions -> val index = ceil(progression * (positions.size - 1)).toInt() @@ -1005,7 +1026,7 @@ public class EpubNavigatorFragment internal constructor( val currentLocator = Locator( href = link.href, - type = link.type ?: MediaType.XHTML.toString(), + type = (link.mediaType ?: MediaType.XHTML).toString(), title = tableOfContentsTitleByHref[link.href] ?: positionLocator?.title ?: link.title, locations = (positionLocator?.locations ?: Locator.Locations()).copy( progression = progression @@ -1039,7 +1060,10 @@ public class EpubNavigatorFragment internal constructor( * @param listener Optional listener to implement to observe events, such as user taps. * @param config Additional configuration. */ - @Deprecated("Use `EpubNavigatorFactory().createFragmentFactory()` instead", level = DeprecationLevel.ERROR) + @Deprecated( + "Use `EpubNavigatorFactory().createFragmentFactory()` instead", + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun createFactory( publication: Publication, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt index 5e3335797e..5e41a1e8c1 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt @@ -67,6 +67,7 @@ internal class EpubNavigatorViewModel( sealed class Event { data class GoTo(val target: Link) : Event() data class OpenExternalLink(val url: Uri) : Event() + /** Refreshes all the resources in the view pager. */ object InvalidateViewPager : Event() data class RunScript(val command: RunScriptCommand) : Event() @@ -88,8 +89,11 @@ internal class EpubNavigatorViewModel( SimplePresentation( readingProgression = settings.readingProgression, scroll = settings.scroll, - axis = if (settings.scroll && !settings.verticalText) Axis.VERTICAL - else Axis.HORIZONTAL + axis = if (settings.scroll && !settings.verticalText) { + Axis.VERTICAL + } else { + Axis.HORIZONTAL + } ) } @@ -324,7 +328,10 @@ internal class EpubNavigatorViewModel( ?: return false val event = DecorableNavigator.OnActivatedEvent( - decoration = decoration, group = group, rect = rect, point = point + decoration = decoration, + group = group, + rect = rect, + point = point ) for (listener in listeners) { if (listener.onDecorationActivated(event)) { @@ -346,10 +353,15 @@ internal class EpubNavigatorViewModel( initialPreferences: EpubPreferences ) = createViewModelFactory { EpubNavigatorViewModel( - application, publication, config, initialPreferences, layout, + application, + publication, + config, + initialPreferences, + layout, defaults = defaults, server = WebViewServer( - application, publication, + application, + publication, servedAssets = config.servedAssets, disableSelectionWhenProtected = config.disableSelectionWhenProtected ) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferences.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferences.kt index 32f0472bc4..7eaf181bd0 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferences.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferences.kt @@ -133,11 +133,16 @@ public data class EpubPreferences( context: Context, sharedPreferencesName: String = "org.readium.r2.settings", fontFamilies: List = listOf( - "Original", "PT Serif", "Roboto", "Source Sans Pro", "Vollkorn", "OpenDyslexic", - "AccessibleDfA", "IA Writer Duospace" + "Original", + "PT Serif", + "Roboto", + "Source Sans Pro", + "Vollkorn", + "OpenDyslexic", + "AccessibleDfA", + "IA Writer Duospace" ) ): EpubPreferences { - val sp: SharedPreferences = context.getSharedPreferences(sharedPreferencesName, Context.MODE_PRIVATE) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt index 53ccc74139..04b4772f29 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesEditor.kt @@ -62,9 +62,13 @@ public class EpubPreferencesEditor internal constructor( public val backgroundColor: Preference = PreferenceDelegate( getValue = { preferences.backgroundColor }, - getEffectiveValue = { state.settings.backgroundColor ?: Color((theme.value ?: theme.effectiveValue).backgroundColor) }, + getEffectiveValue = { + state.settings.backgroundColor ?: Color( + (theme.value ?: theme.effectiveValue).backgroundColor + ) + }, getIsEffective = { preferences.backgroundColor != null }, - updateValue = { value -> updateValues { it.copy(backgroundColor = value) } }, + updateValue = { value -> updateValues { it.copy(backgroundColor = value) } } ) /** @@ -80,7 +84,7 @@ public class EpubPreferencesEditor internal constructor( getEffectiveValue = { state.settings.columnCount }, getIsEffective = { layout == EpubLayout.REFLOWABLE && !state.settings.scroll }, updateValue = { value -> updateValues { it.copy(columnCount = value) } }, - supportedValues = listOf(ColumnCount.AUTO, ColumnCount.ONE, ColumnCount.TWO), + supportedValues = listOf(ColumnCount.AUTO, ColumnCount.ONE, ColumnCount.TWO) ) /** @@ -111,7 +115,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(fontSize = value) } }, supportedRange = 0.1..5.0, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = percentFormatter(), + valueFormatter = percentFormatter() ) /** @@ -149,7 +153,7 @@ public class EpubPreferencesEditor internal constructor( ?: (state.settings.textAlign == TextAlign.JUSTIFY) }, getIsEffective = ::isHyphensEffective, - updateValue = { value -> updateValues { it.copy(hyphens = value) } }, + updateValue = { value -> updateValues { it.copy(hyphens = value) } } ) /** @@ -165,7 +169,7 @@ public class EpubPreferencesEditor internal constructor( getEffectiveValue = { state.settings.imageFilter }, getIsEffective = { state.settings.theme == Theme.DARK }, updateValue = { value -> updateValues { it.copy(imageFilter = value) } }, - supportedValues = listOf(ImageFilter.DARKEN, ImageFilter.INVERT), + supportedValues = listOf(ImageFilter.DARKEN, ImageFilter.INVERT) ) /** @@ -178,7 +182,7 @@ public class EpubPreferencesEditor internal constructor( getValue = { preferences.language }, getEffectiveValue = { state.settings.language }, getIsEffective = { true }, - updateValue = { value -> updateValues { it.copy(language = value) } }, + updateValue = { value -> updateValues { it.copy(language = value) } } ) /** @@ -197,7 +201,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(letterSpacing = value) } }, supportedRange = 0.0..1.0, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = percentFormatter(), + valueFormatter = percentFormatter() ) /** @@ -213,7 +217,7 @@ public class EpubPreferencesEditor internal constructor( getValue = { preferences.ligatures }, getEffectiveValue = { state.settings.ligatures ?: false }, getIsEffective = ::isLigaturesEffective, - updateValue = { value -> updateValues { it.copy(ligatures = value) } }, + updateValue = { value -> updateValues { it.copy(ligatures = value) } } ) /** @@ -231,7 +235,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(lineHeight = value) } }, supportedRange = 1.0..2.0, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = { it.format(5) }, + valueFormatter = { it.format(5) } ) /** @@ -247,7 +251,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(pageMargins = value) } }, supportedRange = 0.0..4.0, progressionStrategy = DoubleIncrement(0.3), - valueFormatter = { it.format(5) }, + valueFormatter = { it.format(5) } ) /** @@ -266,7 +270,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(paragraphIndent = value) } }, supportedRange = 0.0..3.0, progressionStrategy = DoubleIncrement(0.2), - valueFormatter = percentFormatter(), + valueFormatter = percentFormatter() ) /** @@ -284,7 +288,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(paragraphSpacing = value) } }, supportedRange = 0.0..2.0, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = percentFormatter(), + valueFormatter = percentFormatter() ) /** @@ -298,7 +302,7 @@ public class EpubPreferencesEditor internal constructor( getValue = { preferences.publisherStyles }, getEffectiveValue = { state.settings.publisherStyles }, getIsEffective = { layout == EpubLayout.REFLOWABLE }, - updateValue = { value -> updateValues { it.copy(publisherStyles = value) } }, + updateValue = { value -> updateValues { it.copy(publisherStyles = value) } } ) /** @@ -312,7 +316,7 @@ public class EpubPreferencesEditor internal constructor( getEffectiveValue = { state.settings.readingProgression }, getIsEffective = { true }, updateValue = { value -> updateValues { it.copy(readingProgression = value) } }, - supportedValues = listOf(ReadingProgression.LTR, ReadingProgression.RTL), + supportedValues = listOf(ReadingProgression.LTR, ReadingProgression.RTL) ) /** @@ -326,7 +330,7 @@ public class EpubPreferencesEditor internal constructor( getValue = { preferences.scroll }, getEffectiveValue = { state.settings.scroll }, getIsEffective = { layout == EpubLayout.REFLOWABLE }, - updateValue = { value -> updateValues { it.copy(scroll = value) } }, + updateValue = { value -> updateValues { it.copy(scroll = value) } } ) /** @@ -341,7 +345,7 @@ public class EpubPreferencesEditor internal constructor( getEffectiveValue = { state.settings.spread }, getIsEffective = { layout == EpubLayout.FIXED }, updateValue = { value -> updateValues { it.copy(spread = value) } }, - supportedValues = listOf(Spread.NEVER, Spread.ALWAYS), + supportedValues = listOf(Spread.NEVER, Spread.ALWAYS) ) /** @@ -358,7 +362,12 @@ public class EpubPreferencesEditor internal constructor( getEffectiveValue = { state.settings.textAlign }, getIsEffective = ::isTextAlignEffective, updateValue = { value -> updateValues { it.copy(textAlign = value) } }, - supportedValues = listOf(TextAlign.START, TextAlign.LEFT, TextAlign.RIGHT, TextAlign.JUSTIFY), + supportedValues = listOf( + TextAlign.START, + TextAlign.LEFT, + TextAlign.RIGHT, + TextAlign.JUSTIFY + ) ) /** @@ -370,7 +379,11 @@ public class EpubPreferencesEditor internal constructor( public val textColor: Preference = PreferenceDelegate( getValue = { preferences.textColor }, - getEffectiveValue = { state.settings.textColor ?: Color((theme.value ?: theme.effectiveValue).contentColor) }, + getEffectiveValue = { + state.settings.textColor ?: Color( + (theme.value ?: theme.effectiveValue).contentColor + ) + }, getIsEffective = { layout == EpubLayout.REFLOWABLE && preferences.textColor != null }, updateValue = { value -> updateValues { it.copy(textColor = value) } } ) @@ -399,7 +412,7 @@ public class EpubPreferencesEditor internal constructor( getEffectiveValue = { state.settings.theme }, getIsEffective = { layout == EpubLayout.REFLOWABLE }, updateValue = { value -> updateValues { it.copy(theme = value) } }, - supportedValues = listOf(Theme.LIGHT, Theme.DARK, Theme.SEPIA), + supportedValues = listOf(Theme.LIGHT, Theme.DARK, Theme.SEPIA) ) /** @@ -417,7 +430,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(typeScale = value) } }, valueFormatter = { it.format(5) }, supportedRange = 1.0..2.0, - progressionStrategy = StepsProgression(1.0, 1.067, 1.125, 1.2, 1.25, 1.333, 1.414, 1.5, 1.618), + progressionStrategy = StepsProgression(1.0, 1.067, 1.125, 1.2, 1.25, 1.333, 1.414, 1.5, 1.618) ) /** @@ -431,7 +444,7 @@ public class EpubPreferencesEditor internal constructor( getValue = { preferences.verticalText }, getEffectiveValue = { state.settings.verticalText }, getIsEffective = { layout == EpubLayout.REFLOWABLE }, - updateValue = { value -> updateValues { it.copy(verticalText = value) } }, + updateValue = { value -> updateValues { it.copy(verticalText = value) } } ) /** @@ -449,7 +462,7 @@ public class EpubPreferencesEditor internal constructor( updateValue = { value -> updateValues { it.copy(wordSpacing = value) } }, supportedRange = 0.0..1.0, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = percentFormatter(), + valueFormatter = percentFormatter() ) private fun percentFormatter(): (Double) -> String = diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesFilters.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesFilters.kt index e97321aad5..795f405f4b 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesFilters.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesFilters.kt @@ -20,7 +20,7 @@ public object EpubSharedPreferencesFilter : PreferencesFilter { readingProgression = null, language = null, spread = null, - verticalText = null, + verticalText = null ) } @@ -35,6 +35,6 @@ public object EpubPublicationPreferencesFilter : PreferencesFilter = buildList { add(fontFamily) @@ -109,8 +108,11 @@ internal fun ReadiumCss.update(settings: EpubSettings, useReadiumCssFontSize: Bo backgroundColor = backgroundColor?.toCss(), fontOverride = (fontFamily != null || textNormalization), fontFamily = fontFamily?.toCss(), - fontSize = if (useReadiumCssFontSize) Length.Percent(fontSize) - else null, + fontSize = if (useReadiumCssFontSize) { + Length.Percent(fontSize) + } else { + null + }, advancedSettings = !publisherStyles, typeScale = typeScale, textAlign = when (textAlign) { @@ -130,9 +132,11 @@ internal fun ReadiumCss.update(settings: EpubSettings, useReadiumCssFontSize: Bo a11yNormalize = textNormalization, overrides = mapOf( "font-weight" to - if (fontWeight != null) + if (fontWeight != null) { (FontWeight.NORMAL.value * fontWeight).toInt().coerceIn(1, 1000).toString() - else "" + } else { + "" + } ) ) ) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt index 9d764431ac..a4e3286fac 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubSettingsResolver.kt @@ -53,7 +53,7 @@ internal class EpubSettingsResolver( theme = theme, typeScale = preferences.typeScale ?: defaults.typeScale, verticalText = verticalText, - wordSpacing = preferences.wordSpacing ?: defaults.wordSpacing, + wordSpacing = preferences.wordSpacing ?: defaults.wordSpacing ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt index e6165e9d0a..3fcb00034c 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt @@ -8,12 +8,15 @@ package org.readium.r2.navigator.epub import org.readium.r2.navigator.epub.css.ReadiumCss import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.TransformingResource +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.publication.presentation.presentation import org.readium.r2.shared.publication.services.isProtected +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.TransformingResource import timber.log.Timber /** @@ -22,17 +25,21 @@ import timber.log.Timber * @param baseHref Base URL where the Readium CSS and scripts are served. */ @OptIn(ExperimentalReadiumApi::class) -internal fun Fetcher.Resource.injectHtml( +internal fun Resource.injectHtml( publication: Publication, css: ReadiumCss, baseHref: String, disableSelectionWhenProtected: Boolean -): Fetcher.Resource = +): Resource = TransformingResource(this) { bytes -> - val link = link() - check(link.mediaType.isHtml) + val mediaType = mediaType() + .getOrElse { + return@TransformingResource ResourceTry.failure(it) + } + .takeIf { it.isHtml } + ?: return@TransformingResource ResourceTry.success(bytes) - var content = bytes.toString(link.mediaType.charset ?: Charsets.UTF_8).trim() + var content = bytes.toString(mediaType.charset ?: Charsets.UTF_8).trim() val injectables = mutableListOf() val baseUri = baseHref.removeSuffix("/") @@ -60,14 +67,14 @@ internal fun Fetcher.Resource.injectHtml( val headEndIndex = content.indexOf("", 0, true) if (headEndIndex == -1) { - Timber.e(" closing tag not found in ${link.href}") + Timber.e(" closing tag not found in resource with href: $source") } else { content = StringBuilder(content) .insert(headEndIndex, "\n" + injectables.joinToString("\n") + "\n") .toString() } - content.toByteArray() + Try.success(content.toByteArray()) } private fun script(src: String): String = diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt index 29643b2baa..e223348c0c 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt @@ -16,13 +16,13 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.navigator.epub.css.ReadiumCss import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.StringResource -import org.readium.r2.shared.fetcher.fallback +import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceInputStream +import org.readium.r2.shared.resource.StringResource +import org.readium.r2.shared.resource.fallback import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.http.HttpHeaders import org.readium.r2.shared.util.http.HttpRange @@ -39,8 +39,8 @@ internal class WebViewServer( private val disableSelectionWhenProtected: Boolean ) { companion object { - val publicationBaseHref = "https://readium/publication/" - val assetsBaseHref = "https://readium/assets/" + const val publicationBaseHref = "https://readium/publication/" + const val assetsBaseHref = "https://readium/assets/" fun assetUrl(path: String): String = Href(path, baseHref = assetsBaseHref).percentEncodedString @@ -90,20 +90,28 @@ internal class WebViewServer( var resource = publication.get(linkWithoutAnchor) .fallback { errorResource(link, error = it) } - if (link.mediaType.isHtml) { + if (link.mediaType?.isHtml == true) { resource = resource.injectHtml( - publication, css, + publication, + css, baseHref = assetsBaseHref, disableSelectionWhenProtected = disableSelectionWhenProtected ) } val headers = mutableMapOf( - "Accept-Ranges" to "bytes", + "Accept-Ranges" to "bytes" ) if (range == null) { - return WebResourceResponse(link.type, null, 200, "OK", headers, ResourceInputStream(resource)) + return WebResourceResponse( + link.mediaType?.toString(), + null, + 200, + "OK", + headers, + ResourceInputStream(resource) + ) } else { // Byte range request val stream = ResourceInputStream(resource) val length = stream.available() @@ -111,18 +119,27 @@ internal class WebViewServer( headers["Content-Range"] = "bytes ${longRange.first}-${longRange.last}/$length" // Content-Length will automatically be filled by the WebView using the Content-Range header. // headers["Content-Length"] = (longRange.last - longRange.first + 1).toString() - return WebResourceResponse(link.type, null, 206, "Partial Content", headers, stream) + return WebResourceResponse( + link.mediaType?.toString(), + null, + 206, + "Partial Content", + headers, + stream + ) } } - private fun errorResource(link: Link, error: Resource.Exception): Fetcher.Resource = - StringResource(link.copy(type = MediaType.XHTML.toString())) { + private fun errorResource(link: Link, error: Resource.Exception): Resource = + StringResource(mediaType = MediaType.XHTML) { withContext(Dispatchers.IO) { - assetManager - .open("readium/error.xhtml").bufferedReader() - .use { it.readText() } - .replace("\${error}", error.getUserMessage(application)) - .replace("\${href}", link.href) + Try.success( + assetManager + .open("readium/error.xhtml").bufferedReader() + .use { it.readText() } + .replace("\${error}", error.getUserMessage(application)) + .replace("\${href}", link.href) + ) } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/FontFamilyDeclaration.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/FontFamilyDeclaration.kt index af9c309a49..3fc5428833 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/FontFamilyDeclaration.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/FontFamilyDeclaration.kt @@ -44,7 +44,7 @@ internal data class FontFaceDeclaration( val fontFamily: String, val sources: List, var fontStyle: FontStyle? = null, - var fontWeight: Either>? = null, + var fontWeight: Either>? = null ) { fun links(urlNormalizer: (String) -> String): List = diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Layout.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Layout.kt index 2b638ec17e..420be17e12 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Layout.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Layout.kt @@ -21,7 +21,7 @@ import org.readium.r2.shared.util.Language internal data class Layout( val language: Language? = null, val stylesheets: Stylesheets = Stylesheets.Default, - val readingProgression: ReadingProgression = ReadingProgression.LTR, + val readingProgression: ReadingProgression = ReadingProgression.LTR ) { /** * Readium CSS stylesheet variants. @@ -29,8 +29,10 @@ internal data class Layout( enum class Stylesheets(val folder: String?, val htmlDir: HtmlDir) { /** Left to right */ Default(null, HtmlDir.Ltr), + /** Right to left */ Rtl("rtl", HtmlDir.Rtl), + /** * Asian language, laid out vertically. * @@ -38,6 +40,7 @@ internal data class Layout( * https://github.com/readium/readium-css/tree/master/css/dist#vertical */ CjkVertical("cjk-vertical", HtmlDir.Unspecified), + /** Asian language, laid out horizontally */ CjkHorizontal("cjk-horizontal", HtmlDir.Ltr); } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Properties.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Properties.kt index 14f94ca163..88ba71e686 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Properties.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/css/Properties.kt @@ -127,7 +127,7 @@ public data class UserProperties( // Accessibility val a11yNormalize: Boolean? = null, - val overrides: Map = emptyMap(), + val overrides: Map = emptyMap() ) : Properties { override fun toCssProperties(): Map = buildMap { @@ -282,7 +282,7 @@ public data class RsProperties( val compFontFamily: List? = null, val codeFontFamily: List? = null, - val overrides: Map = emptyMap(), + val overrides: Map = emptyMap() ) : Properties { override fun toCssProperties(): Map = buildMap { @@ -560,8 +560,11 @@ private fun MutableMap.putCss(name: String, strings: List body, :root > body { overflow: visible !important; } - """.trimMargin() + """.trimMargin() ) if (!hasStyles) { @@ -142,7 +146,9 @@ internal data class ReadiumCss( private fun CharSequence.hasStyles(): Boolean { return indexOf("", setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)).containsMatchIn(this) + Regex("", setOf(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)).containsMatchIn( + this + ) } private fun stylesheetLink(href: String): String = @@ -206,7 +212,10 @@ internal data class ReadiumCss( val body = document.body() if (body.hasLang()) { - content.insert(content.indexForTagAttributes("html"), " xml:lang=\"${body.lang() ?: language}\"") + content.insert( + content.indexForTagAttributes("html"), + " xml:lang=\"${body.lang() ?: language}\"" + ) } else { val injectable = " xml:lang=\"$language\"" content.insert(content.indexForTagAttributes("html"), injectable) @@ -234,4 +243,7 @@ internal data class ReadiumCss( ) + tag.length + 1 } -private val dirRegex = Regex("""(<(?:html|body)[^\>]*)\s+dir=[\"']\w*[\"']""", setOf(RegexOption.IGNORE_CASE, RegexOption.MULTILINE)) +private val dirRegex = Regex( + """(<(?:html|body)[^\>]*)\s+dir=[\"']\w*[\"']""", + setOf(RegexOption.IGNORE_CASE, RegexOption.MULTILINE) +) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt index 3de827f990..ec130cc2df 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLLayout.kt @@ -67,8 +67,10 @@ internal class R2FXLLayout : FrameLayout { // allow parent views to intercept any touch events that we do not consume var isAllowParentInterceptOnEdge = true + // allow parent views to intercept any touch events that we do not consume even if we are in a scaled state var isAllowParentInterceptOnScaled = false + // minimum scale of the content var minScale = 1.0f set(minScale) { @@ -77,6 +79,7 @@ internal class R2FXLLayout : FrameLayout { maxScale = this.minScale } } + // maximum scale of the content var maxScale = 3.0f set(maxScale) { @@ -181,7 +184,11 @@ internal class R2FXLLayout : FrameLayout { init(context) } - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) { init(context) } @@ -242,7 +249,9 @@ internal class R2FXLLayout : FrameLayout { override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { return if (isScrollingAllowed) { super.onInterceptTouchEvent(ev) - } else isAllowZoom + } else { + isAllowZoom + } } @SuppressLint("ClickableViewAccessibility") @@ -365,8 +374,9 @@ internal class R2FXLLayout : FrameLayout { override fun onScale(detector: ScaleGestureDetector): Boolean { val scale = scale * detector.scaleFactor val scaleFactor = detector.scaleFactor - if (java.lang.Float.isNaN(scaleFactor) || java.lang.Float.isInfinite(scaleFactor)) + if (java.lang.Float.isNaN(scaleFactor) || java.lang.Float.isInfinite(scaleFactor)) { return false + } internalScale(scale, focusX, focusY) zoomDispatcher.onZoom(scale) @@ -484,7 +494,13 @@ internal class R2FXLLayout : FrameLayout { val child = getChildAt(0) if (child != null) { - R2FXLUtils.setRect(drawRect, child.left.toFloat(), child.top.toFloat(), child.right.toFloat(), child.bottom.toFloat()) + R2FXLUtils.setRect( + drawRect, + child.left.toFloat(), + child.top.toFloat(), + child.right.toFloat(), + child.bottom.toFloat() + ) scaledPointsToScreenPoints(drawRect) } else { // If no child is added, then center the drawrect, and let it be empty @@ -565,7 +581,12 @@ internal class R2FXLLayout : FrameLayout { mTargetX = p.x mTargetY = p.y if (scale) { - scaleMatrix.setScale(mZoomStart, mZoomStart, this@R2FXLLayout.focusX, this@R2FXLLayout.focusY) + scaleMatrix.setScale( + mZoomStart, + mZoomStart, + this@R2FXLLayout.focusX, + this@R2FXLLayout.focusY + ) matrixUpdated() } if (doTranslate()) { @@ -593,7 +614,6 @@ internal class R2FXLLayout : FrameLayout { } override fun run() { - if (mCancelled || !doScale() && !doTranslate()) { return } @@ -633,7 +653,6 @@ internal class R2FXLLayout : FrameLayout { private var mFinished = false internal fun fling(velocityX: Int, velocityY: Int) { - val startX = viewPortRect.left.roundToInt() val minX: Int val maxX: Int @@ -681,7 +700,6 @@ internal class R2FXLLayout : FrameLayout { override fun run() { if (!mScroller.isFinished && mScroller.computeScrollOffset()) { - val newX = mScroller.currX val newY = mScroller.currY diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLUtils.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLUtils.kt index a6c66ea5f1..542ba17036 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLUtils.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/fxl/R2FXLUtils.kt @@ -43,7 +43,12 @@ internal object R2FXLUtils { * @param bottom bottom */ fun setRect(rect: RectF, left: Float, top: Float, right: Float, bottom: Float) { - rect.set(left.roundToLong().toFloat(), top.roundToLong().toFloat(), right.roundToLong().toFloat(), bottom.roundToLong().toFloat()) + rect.set( + left.roundToLong().toFloat(), + top.roundToLong().toFloat(), + right.roundToLong().toFloat(), + bottom.roundToLong().toFloat() + ) } /** diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/html/HtmlDecorationTemplate.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/html/HtmlDecorationTemplate.kt index 6cc1286d96..e3600596b6 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/html/HtmlDecorationTemplate.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/html/HtmlDecorationTemplate.kt @@ -41,7 +41,7 @@ public data class HtmlDecorationTemplate( val layout: Layout, val width: Width = Width.WRAP, val element: (Decoration) -> String = { "
" }, - val stylesheet: String? = null, + val stylesheet: String? = null ) : JSONable { /** @@ -52,6 +52,7 @@ public data class HtmlDecorationTemplate( public enum class Layout(public val value: String) : Parcelable { /** A single HTML element covering the smallest region containing all CSS border boxes. */ BOUNDS("bounds"), + /** One HTML element for each CSS border box (e.g. line of text). */ BOXES("boxes"); } @@ -63,10 +64,13 @@ public data class HtmlDecorationTemplate( public enum class Width(public val value: String) : Parcelable { /** Smallest width fitting the CSS border box. */ WRAP("wrap"), + /** Fills the bounds layout. */ BOUNDS("bounds"), + /** Fills the anchor page, useful for dual page. */ VIEWPORT("viewport"), + /** Fills the whole viewport. */ PAGE("page"); } @@ -93,7 +97,13 @@ public data class HtmlDecorationTemplate( cornerRadius: Int, alpha: Double ): HtmlDecorationTemplate = - createTemplate(asHighlight = true, defaultTint = defaultTint, lineWeight = lineWeight, cornerRadius = cornerRadius, alpha = alpha) + createTemplate( + asHighlight = true, + defaultTint = defaultTint, + lineWeight = lineWeight, + cornerRadius = cornerRadius, + alpha = alpha + ) /** Creates a new decoration template for the underline style. */ public fun underline( @@ -102,7 +112,13 @@ public data class HtmlDecorationTemplate( cornerRadius: Int, alpha: Double ): HtmlDecorationTemplate = - createTemplate(asHighlight = false, defaultTint = defaultTint, lineWeight = lineWeight, cornerRadius = cornerRadius, alpha = alpha) + createTemplate( + asHighlight = false, + defaultTint = defaultTint, + lineWeight = lineWeight, + cornerRadius = cornerRadius, + alpha = alpha + ) /** * @param asHighlight When true, the non active style is of an highlight. Otherwise, it is @@ -185,8 +201,24 @@ public class HtmlDecorationTemplates private constructor( cornerRadius: Int = 3, alpha: Double = 0.3 ): HtmlDecorationTemplates = HtmlDecorationTemplates { - set(Style.Highlight::class, HtmlDecorationTemplate.highlight(defaultTint = defaultTint, lineWeight = lineWeight, cornerRadius = cornerRadius, alpha = alpha)) - set(Style.Underline::class, HtmlDecorationTemplate.underline(defaultTint = defaultTint, lineWeight = lineWeight, cornerRadius = cornerRadius, alpha = alpha)) + set( + Style.Highlight::class, + HtmlDecorationTemplate.highlight( + defaultTint = defaultTint, + lineWeight = lineWeight, + cornerRadius = cornerRadius, + alpha = alpha + ) + ) + set( + Style.Underline::class, + HtmlDecorationTemplate.underline( + defaultTint = defaultTint, + lineWeight = lineWeight, + cornerRadius = cornerRadius, + alpha = alpha + ) + ) } } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt index d08354be5b..389fc765a4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt @@ -84,7 +84,12 @@ public class ImageNavigatorFragment private constructor( override fun onCreate(savedInstanceState: Bundle?) { childFragmentManager.fragmentFactory = createFragmentFactory { - R2CbzPageFragment(publication) { x, y -> inputListener.onTap(this, TapEvent(PointF(x, y))) } + R2CbzPageFragment(publication) { x, y -> + inputListener.onTap( + this, + TapEvent(PointF(x, y)) + ) + } } super.onCreate(savedInstanceState) } @@ -98,7 +103,10 @@ public class ImageNavigatorFragment private constructor( _binding = ReadiumNavigatorViewpagerBinding.inflate(inflater, container, false) val view = binding.root - preferences = requireContext().getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) + preferences = requireContext().getSharedPreferences( + "org.readium.r2.settings", + Context.MODE_PRIVATE + ) resourcePager = binding.resourcePager resourcePager.publicationType = R2ViewPager.PublicationType.CBZ @@ -148,13 +156,21 @@ public class ImageNavigatorFragment private constructor( _binding = null } - @Deprecated("Use goForward instead", replaceWith = ReplaceWith("goForward()"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use goForward instead", + replaceWith = ReplaceWith("goForward()"), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun nextResource(v: View?) { goForward() } - @Deprecated("Use goBackward instead", replaceWith = ReplaceWith("goBackward()"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use goBackward instead", + replaceWith = ReplaceWith("goBackward()"), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun previousResource(v: View?) { goBackward() diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt index ca360ee114..65779f9de4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/ExoMediaPlayer.kt @@ -121,7 +121,9 @@ public class ExoMediaPlayer( MEDIA_CHANNEL_ID ) .setChannelNameResourceId(R.string.readium_media_notification_channel_name) - .setChannelDescriptionResourceId(R.string.readium_media_notification_channel_description) + .setChannelDescriptionResourceId( + R.string.readium_media_notification_channel_description + ) .setMediaDescriptionAdapter(DescriptionAdapter(mediaSession.controller, media)) .setNotificationListener(NotificationListener()) .setRewindActionIconResourceId(R.drawable.readium_media_notification_rewind) @@ -130,7 +132,9 @@ public class ExoMediaPlayer( .apply { setMediaSessionToken(mediaSession.sessionToken) setPlayer(player) - setSmallIcon(com.google.android.exoplayer2.ui.R.drawable.exo_notification_small_icon) + setSmallIcon( + com.google.android.exoplayer2.ui.R.drawable.exo_notification_small_icon + ) setUsePlayPauseActions(true) setUseStopAction(false) setUseChronometer(false) @@ -238,7 +242,9 @@ public class ExoMediaPlayer( override fun onPrepareFromUri(uri: Uri, playWhenReady: Boolean, extras: Bundle?) {} } - private inner class QueueNavigator(mediaSession: MediaSessionCompat) : TimelineQueueNavigator(mediaSession) { + private inner class QueueNavigator(mediaSession: MediaSessionCompat) : TimelineQueueNavigator( + mediaSession + ) { override fun getMediaDescription(player: Player, windowIndex: Int): MediaDescriptionCompat = createMediaMetadata(publication.readingOrder[windowIndex]).description @@ -272,10 +278,10 @@ public class ExoMediaPlayer( controller.sessionActivity override fun getCurrentContentText(player: Player): CharSequence = - publication.metadata.title + publication.metadata.title ?: "" override fun getCurrentContentTitle(player: Player): CharSequence = - controller.metadata.description.title ?: publication.metadata.title + controller.metadata.description.title ?: publication.metadata.title ?: "" override fun getCurrentLargeIcon( player: Player, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt index 9025277b30..05d01cbdea 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaService.kt @@ -153,13 +153,21 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by return null } - val locator = extras?.let { BundleCompat.getParcelable(it, EXTRA_LOCATOR, Locator::class.java) } + val locator = extras?.let { + BundleCompat.getParcelable( + it, + EXTRA_LOCATOR, + Locator::class.java + ) + } ?: href ?.let { navigator.publication.linkWithHref(it) } ?.let { navigator.publication.locatorFromLink(it) } if (locator != null && href != null && locator.href != href) { - Timber.e("Ambiguous playback location provided. HREF `$href` doesn't match locator $locator.") + Timber.e( + "Ambiguous playback location provided. HREF `$href` doesn't match locator $locator." + ) } return locator @@ -251,7 +259,10 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by startForeground(id, note) } } else { - ServiceCompat.stopForeground(this@MediaService, ServiceCompat.STOP_FOREGROUND_DETACH) + ServiceCompat.stopForeground( + this@MediaService, + ServiceCompat.STOP_FOREGROUND_DETACH + ) } } } @@ -289,6 +300,7 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by internal const val EXTRA_PUBLICATION_ID = "org.readium.r2.navigator.EXTRA_PUBLICATION_ID" @Volatile private var connection: Connection? = null + @Volatile private var mediaSession: MediaSessionCompat? = null private val currentNavigator = MutableStateFlow(null) @@ -337,7 +349,11 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by ?.takeIf { it.publicationId == publicationId } ?.let { return it } - val navigator = MediaSessionNavigator(publication, publicationId, getMediaSession(context, serviceClass).controller) + val navigator = MediaSessionNavigator( + publication, + publicationId, + getMediaSession(context, serviceClass).controller + ) pendingNavigator.trySend( PendingNavigator( navigator = navigator, @@ -345,7 +361,9 @@ public open class MediaService : MediaBrowserServiceCompat(), CoroutineScope by publication = publication, publicationId = publicationId, locator = initialLocator - ?: requireNotNull(publication.locatorFromLink(publication.readingOrder.first())) + ?: requireNotNull( + publication.locatorFromLink(publication.readingOrder.first()) + ) ) ) ) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt index 193e7eef0b..efc6c4f0e4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt @@ -142,7 +142,10 @@ public class MediaSessionNavigator( override fun onSessionEvent(event: String?, extras: Bundle?) { super.onSessionEvent(event, extras) - if (event == MediaService.EVENT_PUBLICATION_CHANGED && extras?.getString(MediaService.EXTRA_PUBLICATION_ID) == publicationId && playWhenReady && needsPlaying) { + if (event == MediaService.EVENT_PUBLICATION_CHANGED && extras?.getString( + MediaService.EXTRA_PUBLICATION_ID + ) == publicationId && playWhenReady && needsPlaying + ) { play() } } @@ -224,7 +227,11 @@ public class MediaSessionNavigator( // See https://github.com/Kotlin/kotlinx.coroutines/issues/2353 val position = positionMs.milliseconds - val index = metadata.resourceHref?.let { publication.readingOrder.indexOfFirstWithHref(it) } + val index = metadata.resourceHref?.let { + publication.readingOrder.indexOfFirstWithHref( + it + ) + } if (index == null) { Timber.e("Can't find resource index in publication for media ID `${metadata.id}`.") } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt index 17ce648442..bc500ae8f5 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/api/DefaultMediaMetadataFactory.kt @@ -32,7 +32,7 @@ internal class DefaultMediaMetadataFactory( private val coroutineScope = CoroutineScope(Dispatchers.Default) - private val title: String = + private val title: String? = title ?: publication.metadata.title private val author: String? = diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt index f44c2c91bb..12b1cc0c82 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/AudioNavigator.kt @@ -33,7 +33,7 @@ import timber.log.Timber public class AudioNavigator> private constructor( override val publication: Publication, private val audioEngine: AudioEngine, - override val readingOrder: ReadingOrder, + override val readingOrder: ReadingOrder ) : MediaNavigator, TimeBasedMediaNavigator, @@ -47,13 +47,18 @@ public class AudioNavigator, readingOrder: List = publication.readingOrder, initialLocator: Locator? = null, - initialPreferences: P? = null, + initialPreferences: P? = null ): AudioNavigator? { if (readingOrder.isEmpty()) { return null } - val items = readingOrder.map { ReadingOrder.Item(Href(it.href), duration(it, publication)) } + val items = readingOrder.map { + ReadingOrder.Item( + Href(it.href), + duration(it, publication) + ) + } val totalDuration = publication.metadata.duration?.seconds ?: items.mapNotNull { it.duration } .takeIf { it.size == items.size } @@ -91,7 +96,7 @@ public class AudioNavigator, E : PreferencesEditor

> private constructor( private val publication: Publication, - private val audioEngineProvider: AudioEngineProvider, + private val audioEngineProvider: AudioEngineProvider ) { public companion object { @@ -25,7 +25,7 @@ public class AudioNavigatorFactory, E : PreferencesEditor

> invoke( publication: Publication, - audioEngineProvider: AudioEngineProvider, + audioEngineProvider: AudioEngineProvider ): AudioNavigatorFactory? { if (!publication.conformsTo(Publication.Profile.AUDIOBOOK)) { return null @@ -36,24 +36,25 @@ public class AudioNavigatorFactory? { return AudioNavigator( publication = publication, audioEngineProvider = audioEngineProvider, initialLocator = initialLocator, - initialPreferences = initialPreferences, + initialPreferences = initialPreferences ) } public fun createAudioPreferencesEditor( - currentPreferences: P, + currentPreferences: P ): E = audioEngineProvider.createPreferenceEditor(publication, currentPreferences) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt index 3815cb0ddb..18db248abe 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt @@ -16,11 +16,12 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.runBlocking import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.fetcher.Fetcher +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.resource.Resource @RequiresApi(Build.VERSION_CODES.M) internal class MetadataRetriever( - resource: Fetcher.Resource + resource: Resource ) { private val retriever: MediaMetadataRetriever = @@ -36,11 +37,13 @@ internal class MetadataRetriever( ?.milliseconds fun close() { - retriever.close() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + tryOrLog { retriever.close() } + } } - class ResourceMediaDataSource( - private val resource: Fetcher.Resource + private class ResourceMediaDataSource( + private val resource: Resource ) : MediaDataSource() { override fun readAt(position: Long, buffer: ByteArray, offset: Int, size: Int): Int { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt index 57902d17e7..0c8b874ae1 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoAudiobookPlayer.kt @@ -23,7 +23,7 @@ internal class ExoAudiobookPlayer( private val player: ExoPlayer, private val itemDurations: List?, private val seekForwardIncrement: Duration, - private val seekBackwardIncrement: Duration, + private val seekBackwardIncrement: Duration ) : ForwardingPlayer(player) { fun seekBy(offset: Duration) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt index da366df023..7d20db4ebe 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt @@ -16,15 +16,20 @@ import androidx.media3.datasource.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.buffered import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.buffered -public sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException(message, cause) { +public sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException( + message, + cause +) { public class NotOpened(message: String) : ExoPlayerDataSourceException(message, null) public class NotFound(message: String) : ExoPlayerDataSourceException(message, null) - public class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : ExoPlayerDataSourceException("Failed to read $readLength bytes of URI $uri at offset $offset.", cause) + public class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : ExoPlayerDataSourceException( + "Failed to read $readLength bytes of URI $uri at offset $offset.", + cause + ) } /** @@ -49,16 +54,18 @@ internal class ExoPlayerDataSource internal constructor( } private data class OpenedResource( - val resource: Fetcher.Resource, + val resource: Resource, val uri: Uri, - var position: Long, + var position: Long ) private var openedResource: OpenedResource? = null override fun open(dataSpec: DataSpec): Long { val link = publication.linkWithHref(dataSpec.uri.toString()) - ?: throw ExoPlayerDataSourceException.NotFound("Can't find a [Link] for URI: ${dataSpec.uri}. Make sure you only request resources declared in the manifest.") + ?: throw ExoPlayerDataSourceException.NotFound( + "Can't find a [Link] for URI: ${dataSpec.uri}. Make sure you only request resources declared in the manifest." + ) val resource = publication.get(link) // Significantly improves performances, in particular with deflated ZIP entries. @@ -67,7 +74,7 @@ internal class ExoPlayerDataSource internal constructor( openedResource = OpenedResource( resource = resource, uri = dataSpec.uri, - position = dataSpec.position, + position = dataSpec.position ) val bytesToRead = @@ -100,7 +107,9 @@ internal class ExoPlayerDataSource internal constructor( return 0 } - val openedResource = openedResource ?: throw ExoPlayerDataSourceException.NotOpened("No opened resource to read from. Did you call open()?") + val openedResource = openedResource ?: throw ExoPlayerDataSourceException.NotOpened( + "No opened resource to read from. Did you call open()?" + ) try { val data = runBlocking { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt index c2e6344f14..aefcee2c21 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerEngine.kt @@ -231,7 +231,8 @@ public class ExoPlayerEngine private constructor( override fun submitPreferences(preferences: ExoPlayerPreferences) { val newSettings = settingsResolver.settings(preferences) exoPlayer.playbackParameters = PlaybackParameters( - newSettings.speed.toFloat(), newSettings.pitch.toFloat() + newSettings.speed.toFloat(), + newSettings.pitch.toFloat() ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt index dd01b76aa5..e8b59e229d 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferences.kt @@ -19,12 +19,12 @@ import org.readium.r2.shared.ExperimentalReadiumApi @kotlinx.serialization.Serializable public data class ExoPlayerPreferences( val pitch: Double? = null, - val speed: Double? = null, + val speed: Double? = null ) : Configurable.Preferences { override fun plus(other: ExoPlayerPreferences): ExoPlayerPreferences = ExoPlayerPreferences( pitch = other.pitch ?: pitch, - speed = other.speed ?: speed, + speed = other.speed ?: speed ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt index 00727b833a..5a95dce985 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerPreferencesEditor.kt @@ -25,7 +25,7 @@ import org.readium.r2.shared.publication.Metadata public class ExoPlayerPreferencesEditor( initialPreferences: ExoPlayerPreferences, @Suppress("UNUSED_PARAMETER") publicationMetadata: Metadata, - defaults: ExoPlayerDefaults, + defaults: ExoPlayerDefaults ) : PreferencesEditor { private data class State( @@ -54,7 +54,7 @@ public class ExoPlayerPreferencesEditor( updateValue = { value -> updateValues { it.copy(pitch = value) } }, supportedRange = 0.1..Double.MAX_VALUE, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = { "${it.format(2)}x" }, + valueFormatter = { "${it.format(2)}x" } ) public val speed: RangePreference = @@ -65,7 +65,7 @@ public class ExoPlayerPreferencesEditor( updateValue = { value -> updateValues { it.copy(speed = value) } }, supportedRange = 0.1..Double.MAX_VALUE, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = { "${it.format(2)}x" }, + valueFormatter = { "${it.format(2)}x" } ) private fun updateValues(updater: (ExoPlayerPreferences) -> ExoPlayerPreferences) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt index 6dcb2aabbc..7165ee3bda 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerSettingsResolver.kt @@ -14,10 +14,9 @@ internal class ExoPlayerSettingsResolver( ) : ExoPlayerEngine.SettingsResolver { override fun settings(preferences: ExoPlayerPreferences): ExoPlayerSettings { - return ExoPlayerSettings( pitch = preferences.pitch ?: defaults.pitch ?: 1.0, - speed = preferences.speed ?: defaults.speed ?: 1.0, + speed = preferences.speed ?: defaults.speed ?: 1.0 ) } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedMediaNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedMediaNavigator.kt index 7d02baf5c7..971c6a9fa0 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedMediaNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/syncmedia/GuidedMediaNavigator.kt @@ -23,7 +23,7 @@ import org.readium.r2.shared.util.Href @ExperimentalReadiumApi public class GuidedMediaNavigator>( - private val audioNavigator: AudioNavigator, + private val audioNavigator: AudioNavigator ) : MediaNavigator, TimeBasedMediaNavigator, @@ -40,7 +40,7 @@ public class GuidedMediaNavigator { fun utterance(text: String, locator: Locator, language: Language? = null): Utterance? { - if (!text.any { it.isLetterOrDigit() }) + if (!text.any { it.isLetterOrDigit() }) { return null + } val resourceIndex = publication.readingOrder.indexOfFirstWithHref(locator.href) ?: throw IllegalStateException("Content Element cannot be found in readingOrder.") @@ -191,7 +192,7 @@ internal class TtsContentIterator( text = text, textBefore = locator.text.before, textAfter = locator.text.after, - language = language, + language = language ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt index 257149fff0..7365403c34 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt @@ -39,7 +39,7 @@ public class TtsNavigator, coroutineScope: CoroutineScope, override val publication: Publication, private val player: TtsPlayer, - private val sessionAdapter: TtsSessionAdapter, + private val sessionAdapter: TtsSessionAdapter ) : MediaNavigator, TextAwareMediaNavigator, @@ -57,9 +57,8 @@ public class TtsNavigator, metadataProvider: MediaMetadataProvider, listener: Listener, initialLocator: Locator? = null, - initialPreferences: P? = null, + initialPreferences: P? = null ): TtsNavigator? { - if (publication.findService(ContentService::class) == null) { return null } @@ -137,7 +136,7 @@ public class TtsNavigator, override val textBefore: String?, override val textAfter: String?, override val utteranceLocator: Locator, - override val tokenLocator: Locator?, + override val tokenLocator: Locator? ) : TextAwareMediaNavigator.Location public data class Playback( @@ -145,7 +144,7 @@ public class TtsNavigator, override val playWhenReady: Boolean, override val index: Int, override val utterance: String, - override val range: IntRange?, + override val range: IntRange? ) : TextAwareMediaNavigator.Playback public data class ReadingOrder( @@ -278,7 +277,6 @@ public class TtsNavigator, } private fun TtsPlayer.Utterance.toPosition(): Location { - val currentLink = publication.readingOrder[position.resourceIndex] val utteranceHighlight = publication diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt index 879bea99ba..250be30a5d 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigatorFactory.kt @@ -42,7 +42,6 @@ public class TtsNavigatorFactory) -> AndroidTtsEngine.Voice? = defaultVoiceSelector ): AndroidTtsNavigatorFactory? { - val engineProvider = AndroidTtsEngineProvider( context = application, defaults = defaults, @@ -66,7 +65,6 @@ public class TtsNavigatorFactory TextTokenizer = defaultTokenizerFactory, metadataProvider: MediaMetadataProvider = defaultMediaMetadataProvider ): TtsNavigatorFactory? { - return createNavigatorFactory( application, publication, @@ -84,7 +82,6 @@ public class TtsNavigatorFactory TextTokenizer, metadataProvider: MediaMetadataProvider ): TtsNavigatorFactory? { - publication.content() ?.iterator() ?.takeIf { it.hasNext() } @@ -116,7 +113,7 @@ public class TtsNavigatorFactory? { return TtsNavigator( application, @@ -126,7 +123,7 @@ public class TtsNavigatorFactory, E : TtsEngine.Error, V : TtsEngine.Voice> invoke( engine: TtsEngine, contentIterator: TtsContentIterator, - initialPreferences: P, + initialPreferences: P ): TtsPlayer? { - val initialContext = tryOrNull { contentIterator.startContext() } ?: return null @@ -118,7 +117,7 @@ internal class TtsPlayer, data class Playback( val state: State, - val playWhenReady: Boolean, + val playWhenReady: Boolean ) data class Utterance( @@ -131,7 +130,7 @@ internal class TtsPlayer, val resourceIndex: Int, val locations: Locator.Locations, val textBefore: String?, - val textAfter: String?, + val textAfter: String? ) } @@ -481,7 +480,7 @@ internal class TtsPlayer, private fun onEndReached() { playbackMutable.value = playbackMutable.value.copy( - state = State.Ended, + state = State.Ended ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt index 45207578be..b3f0453aa0 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsEngine.kt @@ -206,7 +206,7 @@ public class AndroidTtsEngine private constructor( val id: Id, override val language: Language, val quality: Quality = Quality.Normal, - val requiresNetwork: Boolean = false, + val requiresNetwork: Boolean = false ) : TtsEngine.Voice { @kotlinx.serialization.Serializable @@ -231,7 +231,7 @@ public class AndroidTtsEngine private constructor( ) : State() data class WaitingForService( - val pendingRequests: MutableList = mutableListOf(), + val pendingRequests: MutableList = mutableListOf() ) : State() data class Error( @@ -467,7 +467,11 @@ public class AndroidTtsEngine private constructor( listener?.onDone(TtsEngine.RequestId(utteranceId)) } - @Deprecated("Deprecated in the interface", ReplaceWith("onError(utteranceId, -1)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Deprecated in the interface", + ReplaceWith("onError(utteranceId, -1)"), + level = DeprecationLevel.ERROR + ) override fun onError(utteranceId: String) { onError(utteranceId, -1) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferences.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferences.kt index 8fc062db7d..290035d4f4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferences.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferences.kt @@ -25,7 +25,7 @@ public data class AndroidTtsPreferences( override val language: Language? = null, val pitch: Double? = null, val speed: Double? = null, - val voices: Map? = null, + val voices: Map? = null ) : TtsEngine.Preferences { init { @@ -38,6 +38,6 @@ public data class AndroidTtsPreferences( language = other.language ?: language, pitch = other.pitch ?: pitch, speed = other.speed ?: speed, - voices = other.voices ?: voices, + voices = other.voices ?: voices ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferencesEditor.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferencesEditor.kt index 1c80f75a50..4dfea8b5a8 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferencesEditor.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsPreferencesEditor.kt @@ -23,7 +23,7 @@ import org.readium.r2.shared.util.Language public class AndroidTtsPreferencesEditor( initialPreferences: AndroidTtsPreferences, publicationMetadata: Metadata, - defaults: AndroidTtsDefaults, + defaults: AndroidTtsDefaults ) : PreferencesEditor { private data class State( @@ -49,7 +49,7 @@ public class AndroidTtsPreferencesEditor( getValue = { preferences.language }, getEffectiveValue = { state.settings.language }, getIsEffective = { true }, - updateValue = { value -> updateValues { it.copy(language = value) } }, + updateValue = { value -> updateValues { it.copy(language = value) } } ) public val pitch: RangePreference = @@ -60,7 +60,7 @@ public class AndroidTtsPreferencesEditor( updateValue = { value -> updateValues { it.copy(pitch = value) } }, supportedRange = 0.1..Double.MAX_VALUE, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = { "${it.format(2)}x" }, + valueFormatter = { "${it.format(2)}x" } ) public val speed: RangePreference = @@ -71,7 +71,7 @@ public class AndroidTtsPreferencesEditor( updateValue = { value -> updateValues { it.copy(speed = value) } }, supportedRange = 0.1..Double.MAX_VALUE, progressionStrategy = DoubleIncrement(0.1), - valueFormatter = { "${it.format(2)}x" }, + valueFormatter = { "${it.format(2)}x" } ) public val voices: Preference> = @@ -79,7 +79,7 @@ public class AndroidTtsPreferencesEditor( getValue = { preferences.voices }, getEffectiveValue = { state.settings.voices }, getIsEffective = { true }, - updateValue = { value -> updateValues { it.copy(voices = value) } }, + updateValue = { value -> updateValues { it.copy(voices = value) } } ) private fun updateValues(updater: (AndroidTtsPreferences) -> AndroidTtsPreferences) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettings.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettings.kt index b39ec92288..988739d617 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettings.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/android/AndroidTtsSettings.kt @@ -21,5 +21,5 @@ public data class AndroidTtsSettings( override val overrideContentLanguage: Boolean, val pitch: Double, val speed: Double, - val voices: Map, + val voices: Map ) : TtsEngine.Settings diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioBecomingNoisyManager.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioBecomingNoisyManager.kt index 57df1b096d..3db95c148f 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioBecomingNoisyManager.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioBecomingNoisyManager.kt @@ -50,7 +50,8 @@ internal class AudioBecomingNoisyManager( fun setEnabled(enabled: Boolean) { if (enabled && !receiverRegistered) { context.registerReceiver( - receiver, IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY) + receiver, + IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY) ) receiverRegistered = true } else if (!enabled && receiverRegistered) { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioFocusManager.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioFocusManager.kt index 1532391955..99853ad115 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioFocusManager.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/AudioFocusManager.kt @@ -68,7 +68,9 @@ internal class AudioFocusManager( @MustBeDocumented @Retention(AnnotationRetention.SOURCE) @IntDef( - PLAYER_COMMAND_DO_NOT_PLAY, PLAYER_COMMAND_WAIT_FOR_CALLBACK, PLAYER_COMMAND_PLAY_WHEN_READY + PLAYER_COMMAND_DO_NOT_PLAY, + PLAYER_COMMAND_WAIT_FOR_CALLBACK, + PLAYER_COMMAND_PLAY_WHEN_READY ) annotation class PlayerCommand @@ -218,12 +220,13 @@ internal class AudioFocusManager( private fun requestAudioFocusV26(): Int { if (!::audioFocusRequest.isInitialized || rebuildAudioFocusRequest) { val builder = - if (!::audioFocusRequest.isInitialized) + if (!::audioFocusRequest.isInitialized) { AudioFocusRequest.Builder(focusGainToRequest) - else + } else { AudioFocusRequest.Builder( audioFocusRequest ) + } val willPauseWhenDucked = willPauseWhenDucked() audioFocusRequest = builder .setAudioAttributes( @@ -259,10 +262,11 @@ internal class AudioFocusManager( } this.audioFocusState = audioFocusState val volumeMultiplier = - if (audioFocusState == AUDIO_FOCUS_STATE_LOSS_TRANSIENT_DUCK) + if (audioFocusState == AUDIO_FOCUS_STATE_LOSS_TRANSIENT_DUCK) { VOLUME_MULTIPLIER_DUCK - else + } else { VOLUME_MULTIPLIER_DEFAULT + } if (this.volumeMultiplier == volumeMultiplier) { return } @@ -382,38 +386,42 @@ internal class AudioFocusManager( // Don't handle audio focus. It may be either video only contents or developers // want to have more finer grained control. (e.g. adding audio focus listener) AUDIOFOCUS_NONE - } else when (audioAttributes.usage) { - C.USAGE_VOICE_COMMUNICATION_SIGNALLING -> AUDIOFOCUS_NONE - C.USAGE_GAME, C.USAGE_MEDIA -> AUDIOFOCUS_GAIN - C.USAGE_UNKNOWN -> { - Log.w( - TAG, - "Specify a proper usage in the audio attributes for audio focus" + - " handling. Using AUDIOFOCUS_GAIN by default." - ) - AUDIOFOCUS_GAIN - } - C.USAGE_ALARM, C.USAGE_VOICE_COMMUNICATION -> AUDIOFOCUS_GAIN_TRANSIENT - C.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, C.USAGE_ASSISTANCE_SONIFICATION, - C.USAGE_NOTIFICATION, C.USAGE_NOTIFICATION_COMMUNICATION_DELAYED, - C.USAGE_NOTIFICATION_COMMUNICATION_INSTANT, C.USAGE_NOTIFICATION_COMMUNICATION_REQUEST, - C.USAGE_NOTIFICATION_EVENT, C.USAGE_NOTIFICATION_RINGTONE -> - AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK - C.USAGE_ASSISTANT -> - if (Util.SDK_INT >= 19) { - AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE - } else { - AUDIOFOCUS_GAIN_TRANSIENT + } else { + when (audioAttributes.usage) { + C.USAGE_VOICE_COMMUNICATION_SIGNALLING -> AUDIOFOCUS_NONE + C.USAGE_GAME, C.USAGE_MEDIA -> AUDIOFOCUS_GAIN + C.USAGE_UNKNOWN -> { + Log.w( + TAG, + "Specify a proper usage in the audio attributes for audio focus" + + " handling. Using AUDIOFOCUS_GAIN by default." + ) + AUDIOFOCUS_GAIN + } + C.USAGE_ALARM, C.USAGE_VOICE_COMMUNICATION -> AUDIOFOCUS_GAIN_TRANSIENT + C.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, C.USAGE_ASSISTANCE_SONIFICATION, + C.USAGE_NOTIFICATION, C.USAGE_NOTIFICATION_COMMUNICATION_DELAYED, + C.USAGE_NOTIFICATION_COMMUNICATION_INSTANT, C.USAGE_NOTIFICATION_COMMUNICATION_REQUEST, + C.USAGE_NOTIFICATION_EVENT, C.USAGE_NOTIFICATION_RINGTONE -> + AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK + C.USAGE_ASSISTANT -> + if (Util.SDK_INT >= 19) { + AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE + } else { + AUDIOFOCUS_GAIN_TRANSIENT + } + C.USAGE_ASSISTANCE_ACCESSIBILITY -> { + if (audioAttributes.contentType == C.AUDIO_CONTENT_TYPE_SPEECH) { + // Voice shouldn't be interrupted by other playback. + AUDIOFOCUS_GAIN_TRANSIENT + } else { + AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK + } + } + else -> { + Log.w(TAG, "Unidentified audio usage: " + audioAttributes.usage) + AUDIOFOCUS_NONE } - C.USAGE_ASSISTANCE_ACCESSIBILITY -> { - if (audioAttributes.contentType == C.AUDIO_CONTENT_TYPE_SPEECH) { - // Voice shouldn't be interrupted by other playback. - AUDIOFOCUS_GAIN_TRANSIENT - } else AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK - } - else -> { - Log.w(TAG, "Unidentified audio usage: " + audioAttributes.usage) - AUDIOFOCUS_NONE } } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/StreamVolumeManager.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/StreamVolumeManager.kt index 1190643074..a035d4e2f5 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/StreamVolumeManager.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/StreamVolumeManager.kt @@ -199,7 +199,8 @@ internal class StreamVolumeManager(context: Context, eventHandler: Handler, list } catch (e: RuntimeException) { Log.w( TAG, - "Could not retrieve stream volume for stream type $streamType", e + "Could not retrieve stream volume for stream type $streamType", + e ) audioManager.getStreamMaxVolume(streamType) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt index 55af1f64c2..194a75b365 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsSessionAdapter.kt @@ -114,7 +114,10 @@ internal class TtsSessionAdapter( .onEach { playback -> notifyListenersPlaybackChanged(lastPlayback, playback) lastPlayback = playback - audioFocusManager.updateAudioFocus(playback.playWhenReady, playback.state.playerCode) + audioFocusManager.updateAudioFocus( + playback.playWhenReady, + playback.state.playerCode + ) }.launchIn(coroutineScope) playbackParametersState @@ -127,7 +130,7 @@ internal class TtsSessionAdapter( private var listeners: ListenerSet = ListenerSet( applicationLooper, - Clock.DEFAULT, + Clock.DEFAULT ) { listener: Listener, flags: FlagSet -> listener.onEvents(this, Events(flags)) } @@ -482,10 +485,11 @@ internal class TtsSessionAdapter( override fun getCurrentManifest(): Any? { val timeline = currentTimeline - return if (timeline.isEmpty) + return if (timeline.isEmpty) { null - else + } else { timeline.getWindow(currentMediaItemIndex, window).manifest + } } override fun getCurrentTimeline(): Timeline { @@ -513,14 +517,15 @@ internal class TtsSessionAdapter( override fun getNextMediaItemIndex(): Int { val timeline = currentTimeline - return if (timeline.isEmpty) + return if (timeline.isEmpty) { INDEX_UNSET - else + } else { timeline.getNextWindowIndex( currentMediaItemIndex, getRepeatModeForNavigation(), shuffleModeEnabled ) + } } @Deprecated("Deprecated in Java", ReplaceWith("previousMediaItemIndex")) @@ -530,20 +535,24 @@ internal class TtsSessionAdapter( override fun getPreviousMediaItemIndex(): Int { val timeline = currentTimeline - return if (timeline.isEmpty) + return if (timeline.isEmpty) { INDEX_UNSET - else + } else { timeline.getPreviousWindowIndex( - currentMediaItemIndex, getRepeatModeForNavigation(), shuffleModeEnabled + currentMediaItemIndex, + getRepeatModeForNavigation(), + shuffleModeEnabled ) + } } override fun getCurrentMediaItem(): MediaItem? { val timeline = currentTimeline - return if (timeline.isEmpty) + return if (timeline.isEmpty) { null - else + } else { timeline.getWindow(currentMediaItemIndex, window).mediaItem + } } override fun getMediaItemCount(): Int { @@ -569,15 +578,17 @@ internal class TtsSessionAdapter( override fun getBufferedPercentage(): Int { val position = bufferedPosition val duration = duration - return if (position == TIME_UNSET || duration == TIME_UNSET) + return if (position == TIME_UNSET || duration == TIME_UNSET) { 0 - else if (duration == 0L) + } else if (duration == 0L) { 100 - else Util.constrainValue( - (position * 100 / duration).toInt(), - 0, - 100 - ) + } else { + Util.constrainValue( + (position * 100 / duration).toInt(), + 0, + 100 + ) + } } override fun getTotalBufferedDuration(): Long { @@ -612,7 +623,9 @@ internal class TtsSessionAdapter( val windowStartTimeMs = timeline.getWindow(currentMediaItemIndex, window).windowStartTimeMs return if (windowStartTimeMs == TIME_UNSET) { TIME_UNSET - } else window.currentUnixTimeMs - window.windowStartTimeMs - contentPosition + } else { + window.currentUnixTimeMs - window.windowStartTimeMs - contentPosition + } } @Deprecated("Deprecated in Java", ReplaceWith("isCurrentMediaItemSeekable")) @@ -639,10 +652,11 @@ internal class TtsSessionAdapter( override fun getContentDuration(): Long { val timeline = currentTimeline - return if (timeline.isEmpty) + return if (timeline.isEmpty) { TIME_UNSET - else + } else { timeline.getWindow(currentMediaItemIndex, window).durationMs + } } override fun getContentPosition(): Long { @@ -753,7 +767,7 @@ internal class TtsSessionAdapter( private fun notifyListenersPlaybackChanged( previousPlaybackInfo: TtsPlayer.Playback, - playbackInfo: TtsPlayer.Playback, + playbackInfo: TtsPlayer.Playback // playWhenReadyChangeReason: @Player.PlayWhenReadyChangeReason Int, ) { if (previousPlaybackInfo.state as? TtsPlayer.State.Error != playbackInfo.state as? Error) { @@ -905,11 +919,23 @@ internal class TtsSessionAdapter( is Resource.Exception.NotFound -> PlaybackException(exception.message, exception.cause, ERROR_CODE_IO_BAD_HTTP_STATUS) is Resource.Exception.Forbidden -> - PlaybackException(exception.message, exception.cause, ERROR_CODE_DRM_DISALLOWED_OPERATION) + PlaybackException( + exception.message, + exception.cause, + ERROR_CODE_DRM_DISALLOWED_OPERATION + ) is Resource.Exception.Unavailable -> - PlaybackException(exception.message, exception.cause, ERROR_CODE_IO_NETWORK_CONNECTION_FAILED) + PlaybackException( + exception.message, + exception.cause, + ERROR_CODE_IO_NETWORK_CONNECTION_FAILED + ) is Resource.Exception.Offline -> - PlaybackException(exception.message, exception.cause, ERROR_CODE_IO_NETWORK_CONNECTION_FAILED) + PlaybackException( + exception.message, + exception.cause, + ERROR_CODE_IO_NETWORK_CONNECTION_FAILED + ) is Resource.Exception.OutOfMemory -> PlaybackException(exception.message, exception.cause, ERROR_CODE_UNSPECIFIED) is Resource.Exception.Other -> diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt index 14cb1b1980..22609a9987 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/session/TtsTimeline.kt @@ -13,7 +13,7 @@ import java.util.* @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) internal class TtsTimeline( - private val mediaItems: List, + private val mediaItems: List ) : Timeline() { private val uuids = mediaItems.indices diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt index 85aab5db2b..d058449e72 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2CbzPageFragment.kt @@ -52,7 +52,6 @@ internal class R2CbzPageFragment( container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = ReadiumNavigatorViewpagerFragmentCbzBinding.inflate(inflater, container, false) containerView = binding.root photoView = binding.imageView diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt index b475930231..4ec03e41b1 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt @@ -63,7 +63,9 @@ internal class R2EpubPageFragment : Fragment() { private lateinit var containerView: View private lateinit var preferences: SharedPreferences - private val viewModel: EpubNavigatorViewModel by viewModels(ownerProducer = { requireParentFragment() }) + private val viewModel: EpubNavigatorViewModel by viewModels( + ownerProducer = { requireParentFragment() } + ) private var _binding: ReadiumNavigatorViewpagerFragmentEpubBinding? = null private val binding get() = _binding!! @@ -119,7 +121,11 @@ internal class R2EpubPageFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - pendingLocator = BundleCompat.getParcelable(requireArguments(), "initialLocator", Locator::class.java) + pendingLocator = BundleCompat.getParcelable( + requireArguments(), + "initialLocator", + Locator::class.java + ) } @SuppressLint("SetJavaScriptEnabled", "JavascriptInterface") @@ -130,7 +136,10 @@ internal class R2EpubPageFragment : Fragment() { ): View { _binding = ReadiumNavigatorViewpagerFragmentEpubBinding.inflate(inflater, container, false) containerView = binding.root - preferences = activity?.getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE)!! + preferences = activity?.getSharedPreferences( + "org.readium.r2.settings", + Context.MODE_PRIVATE + )!! val webView = binding.webView this.webView = webView @@ -403,8 +412,11 @@ internal class R2EpubPageFragment : Fragment() { // We need to reverse the progression with RTL because the Web View // always scrolls from left to right, no matter the reading direction. progression = - if (webView.scrollMode || readingProgression == ReadingProgression.LTR) progression - else 1 - progression + if (webView.scrollMode || readingProgression == ReadingProgression.LTR) { + progression + } else { + 1 - progression + } if (webView.scrollMode) { webView.scrollToPosition(progression) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt index ae015c2e30..c6a6494369 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FXLPageFragment.kt @@ -48,7 +48,9 @@ internal class R2FXLPageFragment : Fragment() { private val navigator: EpubNavigatorFragment? get() = parentFragment as? EpubNavigatorFragment - private val viewModel: EpubNavigatorViewModel by viewModels(ownerProducer = { requireParentFragment() }) + private val viewModel: EpubNavigatorViewModel by viewModels( + ownerProducer = { requireParentFragment() } + ) @SuppressLint("SetJavaScriptEnabled") override fun onCreateView( @@ -56,9 +58,12 @@ internal class R2FXLPageFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - secondResourceUrl?.let { - _doubleBinding = ReadiumNavigatorFragmentFxllayoutDoubleBinding.inflate(inflater, container, false) + _doubleBinding = ReadiumNavigatorFragmentFxllayoutDoubleBinding.inflate( + inflater, + container, + false + ) val view: View = doubleBinding.root view.setPadding(0, 0, 0, 0) @@ -80,7 +85,11 @@ internal class R2FXLPageFragment : Fragment() { return view } ?: run { - _singleBinding = ReadiumNavigatorFragmentFxllayoutSingleBinding.inflate(inflater, container, false) + _singleBinding = ReadiumNavigatorFragmentFxllayoutSingleBinding.inflate( + inflater, + container, + false + ) val view: View = singleBinding.root view.setPadding(0, 0, 0, 0) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt index d024e1b313..2c1c3df999 100755 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2FragmentPagerAdapter.kt @@ -23,7 +23,10 @@ import androidx.viewpager.widget.PagerAdapter // This class will be going away when the navigator is rewritten @Suppress("DEPRECATION") -internal abstract class R2FragmentPagerAdapter(private val mFragmentManager: FragmentManager) : androidx.fragment.app.FragmentStatePagerAdapter(mFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { +internal abstract class R2FragmentPagerAdapter(private val mFragmentManager: FragmentManager) : androidx.fragment.app.FragmentStatePagerAdapter( + mFragmentManager, + BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT +) { val mFragments = LongSparseArray() private val mSavedStates = LongSparseArray() @@ -119,7 +122,6 @@ internal abstract class R2FragmentPagerAdapter(private val mFragmentManager: Fra override fun saveState(): Parcelable? { var state: Bundle? = null if (mSavedStates.size() > 0) { - state = Bundle() val stateIds = LongArray(mSavedStates.size()) for (i in 0 until mSavedStates.size()) { @@ -151,7 +153,14 @@ internal abstract class R2FragmentPagerAdapter(private val mFragmentManager: Fra mFragments.clear() if (fss != null) { for (fs in fss) { - mSavedStates.put(fs, BundleCompat.getParcelable(bundle, fs.toString(), Fragment.SavedState::class.java)) + mSavedStates.put( + fs, + BundleCompat.getParcelable( + bundle, + fs.toString(), + Fragment.SavedState::class.java + ) + ) } } val keys = bundle.keySet() diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFactory.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFactory.kt index d195bac703..827d8693d7 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFactory.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFactory.kt @@ -38,7 +38,7 @@ public class PdfNavigatorFactory ): FragmentFactory = createFragmentFactory { PdfNavigatorFragment( - publication, initialLocator, + publication, + initialLocator, preferences ?: pdfEngineProvider.createEmptyPreferences(), - listener, pdfEngineProvider + listener, + pdfEngineProvider ) } } @@ -109,7 +111,7 @@ public class PdfNavigatorFragment? { - val link = publication.linkWithHref(locator.href) ?: return null + val link = viewModel.findLink(locator) ?: return null return try { val pageIndex = (locator.locations.page ?: 1) - 1 diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorViewModel.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorViewModel.kt index e67c11608e..4fb8a05973 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorViewModel.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorViewModel.kt @@ -17,6 +17,7 @@ import org.readium.r2.navigator.preferences.Configurable import org.readium.r2.navigator.preferences.PreferencesEditor import org.readium.r2.navigator.util.createViewModelFactory import org.readium.r2.shared.ExperimentalReadiumApi +import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.positions @@ -51,6 +52,25 @@ internal class PdfNavigatorViewModel, E : PreferencesEditor

> createFactory( application: Application, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/Deprecated.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/R2PdfActivity.kt similarity index 74% rename from readium/navigator/src/main/java/org/readium/r2/navigator/pdf/Deprecated.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/pdf/R2PdfActivity.kt index 6808d89a24..e81ede51af 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/Deprecated.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/pdf/R2PdfActivity.kt @@ -11,8 +11,8 @@ package org.readium.r2.navigator.pdf import androidx.appcompat.app.AppCompatActivity -@Deprecated("Use `PdfNavigatorFragment` in your own activity instead", level = DeprecationLevel.ERROR) +@Deprecated( + "Use `PdfNavigatorFragment` in your own activity instead", + level = DeprecationLevel.ERROR +) public abstract class R2PdfActivity : AppCompatActivity() - -// This is for lint to pass. -private val fake = null diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/MappedPreference.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/MappedPreference.kt index a1dd3a976e..412e57bdc9 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/MappedPreference.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/MappedPreference.kt @@ -71,10 +71,12 @@ public fun , V : Comparable> RangePreference.map( supportedRange: (ClosedRange) -> ClosedRange = { from(it.start)..from(it.endInclusive) }, formatValue: ((V) -> String)? = null, increment: (RangePreference.() -> Unit)? = null, - decrement: (RangePreference.() -> Unit)? = null, + decrement: (RangePreference.() -> Unit)? = null ): RangePreference = MappedRangePreference( - this, from, to, + this, + from, + to, transformSupportedRange = supportedRange, valueFormatter = formatValue, incrementer = increment, @@ -90,10 +92,12 @@ public fun > RangePreference.map( supportedRange: (ClosedRange) -> ClosedRange = { it }, formatValue: ((T) -> String)? = null, increment: (RangePreference.() -> Unit)? = null, - decrement: (RangePreference.() -> Unit)? = null, + decrement: (RangePreference.() -> Unit)? = null ): RangePreference = MappedRangePreference( - this, { it }, { it }, + this, + { it }, + { it }, transformSupportedRange = supportedRange, valueFormatter = formatValue, incrementer = increment, @@ -143,7 +147,7 @@ private open class MappedPreference( @ExperimentalReadiumApi private class PreferenceWithSupportedValues( override val original: Preference, - override val supportedValues: List, + override val supportedValues: List ) : MappedPreference(original, from = { it }, to = { it }), EnumPreference @ExperimentalReadiumApi diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/PreferenceDelegate.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/PreferenceDelegate.kt index ff9915f5d8..15543e2a00 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/PreferenceDelegate.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/PreferenceDelegate.kt @@ -16,7 +16,7 @@ public open class PreferenceDelegate( private val getValue: () -> T?, private val getEffectiveValue: () -> T, private val getIsEffective: () -> Boolean, - private val updateValue: (T?) -> Unit, + private val updateValue: (T?) -> Unit ) : Preference { override val value: T? @@ -39,7 +39,7 @@ public class EnumPreferenceDelegate( getEffectiveValue: () -> T, getIsEffective: () -> Boolean, updateValue: (T?) -> Unit, - override val supportedValues: List, + override val supportedValues: List ) : PreferenceDelegate(getValue, getEffectiveValue, getIsEffective, updateValue), EnumPreference { @@ -57,7 +57,7 @@ public class RangePreferenceDelegate>( updateValue: (T?) -> Unit, private val valueFormatter: (T) -> String, override val supportedRange: ClosedRange, - private val progressionStrategy: ProgressionStrategy, + private val progressionStrategy: ProgressionStrategy ) : PreferenceDelegate(getValue, getEffectiveValue, getIsEffective, updateValue), RangePreference { diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/Types.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/Types.kt index 74ff7a9e5e..f2f4856c67 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/Types.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/preferences/Types.kt @@ -14,12 +14,17 @@ import org.readium.r2.shared.ExperimentalReadiumApi // https://github.com/readium/readium-css/blob/master/css/src/modules/ReadiumCSS-day_mode.css @ColorInt private val dayContentColor: Int = AndroidColor.parseColor("#121212") + @ColorInt private val dayBackgroundColor: Int = AndroidColor.parseColor("#FFFFFF") + // https://github.com/readium/readium-css/blob/master/css/src/modules/ReadiumCSS-night_mode.css @ColorInt private val nightContentColor: Int = AndroidColor.parseColor("#FEFEFE") + @ColorInt private val nightBackgroundColor: Int = AndroidColor.parseColor("#000000") + // https://github.com/readium/readium-css/blob/master/css/src/modules/ReadiumCSS-sepia_mode.css @ColorInt private val sepiaContentColor: Int = AndroidColor.parseColor("#121212") + @ColorInt private val sepiaBackgroundColor: Int = AndroidColor.parseColor("#faf4e8") @ExperimentalReadiumApi @@ -28,41 +33,65 @@ public enum class Theme( @ColorInt public val contentColor: Int, @ColorInt public val backgroundColor: Int ) { - @SerialName("light") LIGHT(contentColor = dayContentColor, backgroundColor = dayBackgroundColor), - @SerialName("dark") DARK(contentColor = nightContentColor, backgroundColor = nightBackgroundColor), - @SerialName("sepia") SEPIA(contentColor = sepiaContentColor, backgroundColor = sepiaBackgroundColor); + @SerialName("light") + LIGHT(contentColor = dayContentColor, backgroundColor = dayBackgroundColor), + + @SerialName("dark") + DARK(contentColor = nightContentColor, backgroundColor = nightBackgroundColor), + + @SerialName("sepia") + SEPIA(contentColor = sepiaContentColor, backgroundColor = sepiaBackgroundColor); } @ExperimentalReadiumApi @Serializable public enum class TextAlign { /** Align the text in the center of the page. */ - @SerialName("center") CENTER, + @SerialName("center") + CENTER, + /** Stretch lines of text that end with a soft line break to fill the width of the page. */ - @SerialName("justify") JUSTIFY, + @SerialName("justify") + JUSTIFY, + /** Align the text on the leading edge of the page. */ - @SerialName("start") START, + @SerialName("start") + START, + /** Align the text on the trailing edge of the page. */ - @SerialName("end") END, + @SerialName("end") + END, + /** Align the text on the left edge of the page. */ - @SerialName("left") LEFT, + @SerialName("left") + LEFT, + /** Align the text on the right edge of the page. */ - @SerialName("right") RIGHT; + @SerialName("right") + RIGHT; } @ExperimentalReadiumApi @Serializable public enum class ColumnCount { - @SerialName("auto") AUTO, - @SerialName("1") ONE, - @SerialName("2") TWO; + @SerialName("auto") + AUTO, + + @SerialName("1") + ONE, + + @SerialName("2") + TWO; } @ExperimentalReadiumApi @Serializable public enum class ImageFilter { - @SerialName("darken") DARKEN, - @SerialName("invert") INVERT; + @SerialName("darken") + DARKEN, + + @SerialName("invert") + INVERT; } /** @@ -105,8 +134,11 @@ public value class Color(@ColorInt public val int: Int) @ExperimentalReadiumApi @Serializable public enum class Axis(public val value: String) { - @SerialName("horizontal") HORIZONTAL("horizontal"), - @SerialName("vertical") VERTICAL("vertical"); + @SerialName("horizontal") + HORIZONTAL("horizontal"), + + @SerialName("vertical") + VERTICAL("vertical"); } /** @@ -115,9 +147,14 @@ public enum class Axis(public val value: String) { @ExperimentalReadiumApi @Serializable public enum class Spread(public val value: String) { - @SerialName("auto") AUTO("auto"), - @SerialName("never") NEVER("never"), - @SerialName("always") ALWAYS("always"); + @SerialName("auto") + AUTO("auto"), + + @SerialName("never") + NEVER("never"), + + @SerialName("always") + ALWAYS("always"); } /** @@ -126,8 +163,11 @@ public enum class Spread(public val value: String) { @ExperimentalReadiumApi @Serializable public enum class ReadingProgression(public val value: String) { - @SerialName("ltr") LTR("ltr"), - @SerialName("rtl") RTL("rtl"); + @SerialName("ltr") + LTR("ltr"), + + @SerialName("rtl") + RTL("rtl"); } /** @@ -136,8 +176,15 @@ public enum class ReadingProgression(public val value: String) { @ExperimentalReadiumApi @Serializable public enum class Fit(public val value: String) { - @SerialName("cover") COVER("cover"), - @SerialName("contain") CONTAIN("contain"), - @SerialName("width") WIDTH("width"), - @SerialName("height") HEIGHT("height"); + @SerialName("cover") + COVER("cover"), + + @SerialName("contain") + CONTAIN("contain"), + + @SerialName("width") + WIDTH("width"), + + @SerialName("height") + HEIGHT("height"); } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt index b4d05761a1..1e32ad90d9 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/util/EdgeTapNavigation.kt @@ -1,4 +1,8 @@ package org.readium.r2.navigator.util -@Deprecated("Replaced by [DirectionalNavigationAdapter].", replaceWith = ReplaceWith("DirectionalNavigationAdapter"), level = DeprecationLevel.ERROR) +@Deprecated( + "Replaced by [DirectionalNavigationAdapter].", + replaceWith = ReplaceWith("DirectionalNavigationAdapter"), + level = DeprecationLevel.ERROR +) public class EdgeTapNavigation diff --git a/readium/navigator/src/test/java/org/readium/r2/navigator/DecorationTest.kt b/readium/navigator/src/test/java/org/readium/r2/navigator/DecorationTest.kt index 2d3cc9f5df..868ed20a12 100644 --- a/readium/navigator/src/test/java/org/readium/r2/navigator/DecorationTest.kt +++ b/readium/navigator/src/test/java/org/readium/r2/navigator/DecorationTest.kt @@ -18,19 +18,19 @@ class DecorationTest { id = "1", locator = Locator("chapter.html", "text/html"), style = Decoration.Style.Highlight(tint = Color.RED), - extras = mapOf("param" to "value"), + extras = mapOf("param" to "value") ) val d1b = Decoration( id = "1", locator = Locator("chapter.html", "text/html"), style = Decoration.Style.Highlight(tint = Color.RED), - extras = mapOf("param" to "value"), + extras = mapOf("param" to "value") ) val d2 = Decoration( id = "2", locator = Locator("chapter2.html", "text/html"), style = Decoration.Style.Highlight(tint = Color.RED), - extras = mapOf("param" to "value"), + extras = mapOf("param" to "value") ) assertTrue { d1a == d1a } diff --git a/readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt b/readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt index 494e379b6e..461337c250 100644 --- a/readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt +++ b/readium/navigator/src/test/java/org/readium/r2/navigator/audio/SmartSeekerTest.kt @@ -11,7 +11,14 @@ import org.readium.r2.navigator.media3.audio.SmartSeeker class SmartSeekerTest { private val playlist: List = listOf( - 10, 20, 15, 800, 10, 230, 20, 10 + 10, + 20, + 15, + 800, + 10, + 230, + 20, + 10 ).map { it.seconds } private val forwardOffset = 50.seconds diff --git a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt index 1ef19eb77c..94d83c2071 100644 --- a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt +++ b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/EpubSettingsResolverTest.kt @@ -53,47 +53,91 @@ class EpubSettingsResolverTest { resolveLayout() ) assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.Default, readingProgression = LTR), + Layout( + language = Language("en"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), resolveLayout(languages = listOf("en")) ) assertEquals( - Layout(language = Language("ar"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), + Layout( + language = Language("ar"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), resolveLayout(languages = listOf("ar")) ) assertEquals( - Layout(language = Language("fa"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), + Layout( + language = Language("fa"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), resolveLayout(languages = listOf("fa")) ) assertEquals( - Layout(language = Language("he"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), + Layout( + language = Language("he"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), resolveLayout(languages = listOf("he")) ) assertEquals( - Layout(language = Language("ja"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("ja"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(languages = listOf("ja")) ) assertEquals( - Layout(language = Language("ko"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("ko"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(languages = listOf("ko")) ) assertEquals( - Layout(language = Language("zh"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(languages = listOf("zh")) ) assertEquals( - Layout(language = Language("zh-HK"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh-HK"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(languages = listOf("zh-HK")) ) assertEquals( - Layout(language = Language("zh-Hans"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh-Hans"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(languages = listOf("zh-Hans")) ) assertEquals( - Layout(language = Language("zh-Hant"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("zh-Hant"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(languages = listOf("zh-Hant")) ) assertEquals( - Layout(language = Language("zh-TW"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("zh-TW"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(languages = listOf("zh-TW")) ) } @@ -105,47 +149,91 @@ class EpubSettingsResolverTest { resolveLayout(readingProgression = PublicationLTR) ) assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.Default, readingProgression = LTR), + Layout( + language = Language("en"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("en")) ) assertEquals( - Layout(language = Language("ar"), stylesheets = Stylesheets.Default, readingProgression = LTR), + Layout( + language = Language("ar"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("ar")) ) assertEquals( - Layout(language = Language("fa"), stylesheets = Stylesheets.Default, readingProgression = LTR), + Layout( + language = Language("fa"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("fa")) ) assertEquals( - Layout(language = Language("he"), stylesheets = Stylesheets.Default, readingProgression = LTR), + Layout( + language = Language("he"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("he")) ) assertEquals( - Layout(language = Language("ja"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("ja"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("ja")) ) assertEquals( - Layout(language = Language("ko"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("ko"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("ko")) ) assertEquals( - Layout(language = Language("zh"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("zh")) ) assertEquals( - Layout(language = Language("zh-HK"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh-HK"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("zh-HK")) ) assertEquals( - Layout(language = Language("zh-Hans"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh-Hans"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("zh-Hans")) ) assertEquals( - Layout(language = Language("zh-Hant"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh-Hant"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("zh-Hant")) ) assertEquals( - Layout(language = Language("zh-TW"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), + Layout( + language = Language("zh-TW"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), resolveLayout(readingProgression = PublicationLTR, languages = listOf("zh-TW")) ) } @@ -157,47 +245,91 @@ class EpubSettingsResolverTest { resolveLayout(readingProgression = PublicationRTL) ) assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), + Layout( + language = Language("en"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("en")) ) assertEquals( - Layout(language = Language("ar"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), + Layout( + language = Language("ar"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("ar")) ) assertEquals( - Layout(language = Language("fa"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), + Layout( + language = Language("fa"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("fa")) ) assertEquals( - Layout(language = Language("he"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), + Layout( + language = Language("he"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("he")) ) assertEquals( - Layout(language = Language("ja"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("ja"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("ja")) ) assertEquals( - Layout(language = Language("ko"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("ko"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("ko")) ) assertEquals( - Layout(language = Language("zh"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("zh"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("zh")) ) assertEquals( - Layout(language = Language("zh-HK"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("zh-HK"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("zh-HK")) ) assertEquals( - Layout(language = Language("zh-Hans"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("zh-Hans"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("zh-Hans")) ) assertEquals( - Layout(language = Language("zh-Hant"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("zh-Hant"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("zh-Hant")) ) assertEquals( - Layout(language = Language("zh-TW"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), + Layout( + language = Language("zh-TW"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), resolveLayout(readingProgression = PublicationRTL, languages = listOf("zh-TW")) ) } @@ -210,15 +342,29 @@ class EpubSettingsResolverTest { ) assertEquals( Layout(language = null, stylesheets = Stylesheets.CjkVertical, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, preferences = EpubPreferences(verticalText = true)) + resolveLayout( + readingProgression = PublicationLTR, + preferences = EpubPreferences(verticalText = true) + ) ) assertEquals( Layout(language = null, stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), - resolveLayout(readingProgression = PublicationRTL, preferences = EpubPreferences(verticalText = true)) - ) - assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.CjkVertical, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("en"), preferences = EpubPreferences(verticalText = true)) + resolveLayout( + readingProgression = PublicationRTL, + preferences = EpubPreferences(verticalText = true) + ) + ) + assertEquals( + Layout( + language = Language("en"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = LTR + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("en"), + preferences = EpubPreferences(verticalText = true) + ) ) } @@ -230,31 +376,77 @@ class EpubSettingsResolverTest { ) assertEquals( Layout(language = null, stylesheets = Stylesheets.Default, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, preferences = EpubPreferences(verticalText = false)) + resolveLayout( + readingProgression = PublicationLTR, + preferences = EpubPreferences(verticalText = false) + ) ) assertEquals( Layout(language = null, stylesheets = Stylesheets.Rtl, readingProgression = RTL), - resolveLayout(readingProgression = PublicationRTL, preferences = EpubPreferences(verticalText = false)) - ) - assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.Default, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("en"), preferences = EpubPreferences(verticalText = false)) - ) - assertEquals( - Layout(language = Language("ar"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), - resolveLayout(readingProgression = PublicationRTL, languages = listOf("ar"), preferences = EpubPreferences(verticalText = false)) - ) - assertEquals( - Layout(language = Language("ja"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("ja"), preferences = EpubPreferences(verticalText = false)) - ) - assertEquals( - Layout(language = Language("ja"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("ja"), preferences = EpubPreferences(verticalText = false)) - ) - assertEquals( - Layout(language = Language("ja"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = RTL), - resolveLayout(readingProgression = PublicationRTL, languages = listOf("ja"), preferences = EpubPreferences(verticalText = false)) + resolveLayout( + readingProgression = PublicationRTL, + preferences = EpubPreferences(verticalText = false) + ) + ) + assertEquals( + Layout( + language = Language("en"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("en"), + preferences = EpubPreferences(verticalText = false) + ) + ) + assertEquals( + Layout( + language = Language("ar"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), + resolveLayout( + readingProgression = PublicationRTL, + languages = listOf("ar"), + preferences = EpubPreferences(verticalText = false) + ) + ) + assertEquals( + Layout( + language = Language("ja"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("ja"), + preferences = EpubPreferences(verticalText = false) + ) + ) + assertEquals( + Layout( + language = Language("ja"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("ja"), + preferences = EpubPreferences(verticalText = false) + ) + ) + assertEquals( + Layout( + language = Language("ja"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = RTL + ), + resolveLayout( + readingProgression = PublicationRTL, + languages = listOf("ja"), + preferences = EpubPreferences(verticalText = false) + ) ) } @@ -262,11 +454,22 @@ class EpubSettingsResolverTest { fun `RTL readingProgression preference takes precedence over LTR readingProgression hint`() { assertEquals( Layout(language = null, stylesheets = Stylesheets.Rtl, readingProgression = RTL), - resolveLayout(readingProgression = PublicationLTR, preferences = EpubPreferences(readingProgression = RTL)) - ) - assertEquals( - Layout(language = Language("zh-tw"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("zh-tw"), preferences = EpubPreferences(readingProgression = RTL)) + resolveLayout( + readingProgression = PublicationLTR, + preferences = EpubPreferences(readingProgression = RTL) + ) + ) + assertEquals( + Layout( + language = Language("zh-tw"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("zh-tw"), + preferences = EpubPreferences(readingProgression = RTL) + ) ) } @@ -274,11 +477,22 @@ class EpubSettingsResolverTest { fun `LTR readingProgression setting takes precedence over RTL readingProgression hint`() { assertEquals( Layout(language = null, stylesheets = Stylesheets.Default, readingProgression = LTR), - resolveLayout(readingProgression = PublicationRTL, preferences = EpubPreferences(readingProgression = LTR)) - ) - assertEquals( - Layout(language = Language("zh-tw"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), - resolveLayout(readingProgression = PublicationRTL, languages = listOf("zh-tw"), preferences = EpubPreferences(readingProgression = LTR)) + resolveLayout( + readingProgression = PublicationRTL, + preferences = EpubPreferences(readingProgression = LTR) + ) + ) + assertEquals( + Layout( + language = Language("zh-tw"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), + resolveLayout( + readingProgression = PublicationRTL, + languages = listOf("zh-tw"), + preferences = EpubPreferences(readingProgression = LTR) + ) ) } @@ -286,11 +500,22 @@ class EpubSettingsResolverTest { fun `LTR readingProgression hint takes precedence over default RTL readingProgression`() { assertEquals( Layout(language = null, stylesheets = Stylesheets.Default, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, defaults = EpubDefaults(readingProgression = RTL)) - ) - assertEquals( - Layout(language = Language("ja"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("ja"), defaults = EpubDefaults(readingProgression = RTL)) + resolveLayout( + readingProgression = PublicationLTR, + defaults = EpubDefaults(readingProgression = RTL) + ) + ) + assertEquals( + Layout( + language = Language("ja"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("ja"), + defaults = EpubDefaults(readingProgression = RTL) + ) ) } @@ -298,11 +523,22 @@ class EpubSettingsResolverTest { fun `RTL readingProgression hint takes precedence over default LTR readingProgression`() { assertEquals( Layout(language = null, stylesheets = Stylesheets.Rtl, readingProgression = RTL), - resolveLayout(readingProgression = PublicationRTL, defaults = EpubDefaults(readingProgression = LTR)) - ) - assertEquals( - Layout(language = Language("zh-tw"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), - resolveLayout(readingProgression = PublicationRTL, languages = listOf("zh-tw"), defaults = EpubDefaults(readingProgression = LTR)) + resolveLayout( + readingProgression = PublicationRTL, + defaults = EpubDefaults(readingProgression = LTR) + ) + ) + assertEquals( + Layout( + language = Language("zh-tw"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), + resolveLayout( + readingProgression = PublicationRTL, + languages = listOf("zh-tw"), + defaults = EpubDefaults(readingProgression = LTR) + ) ) } @@ -325,69 +561,139 @@ class EpubSettingsResolverTest { @Test fun `metadata language takes precedence over default readingProgression`() { assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.Default, readingProgression = LTR), - resolveLayout(languages = listOf("en"), defaults = EpubDefaults(readingProgression = RTL)) + Layout( + language = Language("en"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), + resolveLayout( + languages = listOf("en"), + defaults = EpubDefaults(readingProgression = RTL) + ) ) assertEquals( - Layout(language = Language("zh"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), - resolveLayout(languages = listOf("zh"), defaults = EpubDefaults(readingProgression = RTL)) + Layout( + language = Language("zh"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), + resolveLayout( + languages = listOf("zh"), + defaults = EpubDefaults(readingProgression = RTL) + ) ) } @Test fun `RTL readingProgression preference takes precedence over metadata language`() { assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), - resolveLayout(languages = listOf("en"), preferences = EpubPreferences(readingProgression = RTL)) - ) - assertEquals( - Layout(language = Language("zh"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), - resolveLayout(languages = listOf("zh"), preferences = EpubPreferences(readingProgression = RTL)) + Layout( + language = Language("en"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), + resolveLayout( + languages = listOf("en"), + preferences = EpubPreferences(readingProgression = RTL) + ) + ) + assertEquals( + Layout( + language = Language("zh"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), + resolveLayout( + languages = listOf("zh"), + preferences = EpubPreferences(readingProgression = RTL) + ) ) } @Test fun `LTR readingProgression preference takes precedence over metadata language`() { assertEquals( - Layout(language = Language("he"), stylesheets = Stylesheets.Default, readingProgression = LTR), - resolveLayout(languages = listOf("he"), preferences = EpubPreferences(readingProgression = LTR)) - ) - assertEquals( - Layout(language = Language("zh-tw"), stylesheets = Stylesheets.CjkHorizontal, readingProgression = LTR), - resolveLayout(languages = listOf("zh-tw"), preferences = EpubPreferences(readingProgression = LTR)) + Layout( + language = Language("he"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), + resolveLayout( + languages = listOf("he"), + preferences = EpubPreferences(readingProgression = LTR) + ) + ) + assertEquals( + Layout( + language = Language("zh-tw"), + stylesheets = Stylesheets.CjkHorizontal, + readingProgression = LTR + ), + resolveLayout( + languages = listOf("zh-tw"), + preferences = EpubPreferences(readingProgression = LTR) + ) ) } @Test fun `RTL readingProgression preference takes precedence over language preference`() { assertEquals( - Layout(language = Language("en"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), - resolveLayout(preferences = EpubPreferences(readingProgression = RTL, language = Language("en"))) + Layout( + language = Language("en"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), + resolveLayout( + preferences = EpubPreferences(readingProgression = RTL, language = Language("en")) + ) ) } @Test fun `LTR readingProgression preference takes precedence over language preference`() { assertEquals( - Layout(language = Language("he"), stylesheets = Stylesheets.Default, readingProgression = LTR), - resolveLayout(preferences = EpubPreferences(readingProgression = LTR, language = Language("he"))) + Layout( + language = Language("he"), + stylesheets = Stylesheets.Default, + readingProgression = LTR + ), + resolveLayout( + preferences = EpubPreferences(readingProgression = LTR, language = Language("he")) + ) ) } @Test fun `he language preference takes precedence over language metadata`() { assertEquals( - Layout(language = Language("he"), stylesheets = Stylesheets.Rtl, readingProgression = RTL), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("en"), preferences = EpubPreferences(language = Language("he"))) + Layout( + language = Language("he"), + stylesheets = Stylesheets.Rtl, + readingProgression = RTL + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("en"), + preferences = EpubPreferences(language = Language("he")) + ) ) } @Test fun `zh-tw language preference takes precedence over language metadata`() { assertEquals( - Layout(language = Language("zh-tw"), stylesheets = Stylesheets.CjkVertical, readingProgression = RTL), - resolveLayout(readingProgression = PublicationLTR, languages = listOf("en"), preferences = EpubPreferences(language = Language("zh-tw"))) + Layout( + language = Language("zh-tw"), + stylesheets = Stylesheets.CjkVertical, + readingProgression = RTL + ), + resolveLayout( + readingProgression = PublicationLTR, + languages = listOf("en"), + preferences = EpubPreferences(language = Language("zh-tw")) + ) ) } } diff --git a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/PropertiesTest.kt b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/PropertiesTest.kt index 0da3b2f539..df35418f64 100644 --- a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/PropertiesTest.kt +++ b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/PropertiesTest.kt @@ -52,7 +52,7 @@ class PropertiesTest { "--RS__serif-ja-v" to null, "--RS__sans-serif-ja-v" to null, "--RS__compFontFamily" to null, - "--RS__codeFontFamily" to null, + "--RS__codeFontFamily" to null ), RsProperties().toCssProperties() ) @@ -109,7 +109,7 @@ class PropertiesTest { "--RS__serif-ja-v" to """"Serif", "JaV"""", "--RS__sans-serif-ja-v" to """"Sans serif", "JaV"""", "--RS__compFontFamily" to """"Arial"""", - "--RS__codeFontFamily" to """"Monaco", "Console Sans"""", + "--RS__codeFontFamily" to """"Monaco", "Console Sans"""" ), RsProperties( colWidth = Length.Cm(1.2), @@ -175,7 +175,7 @@ class PropertiesTest { "--USER__letterSpacing" to null, "--USER__bodyHyphens" to null, "--USER__ligatures" to null, - "--USER__a11yNormalize" to null, + "--USER__a11yNormalize" to null ), UserProperties().toCssProperties() ) @@ -206,7 +206,7 @@ class PropertiesTest { "--USER__letterSpacing" to "8.9rem", "--USER__bodyHyphens" to "auto", "--USER__ligatures" to "common-ligatures", - "--USER__a11yNormalize" to "readium-a11y-on", + "--USER__a11yNormalize" to "readium-a11y-on" ), UserProperties( view = View.SCROLL, @@ -230,7 +230,7 @@ class PropertiesTest { letterSpacing = Length.Rem(8.9), bodyHyphens = Hyphens.AUTO, ligatures = Ligatures.COMMON, - a11yNormalize = true, + a11yNormalize = true ).toCssProperties() ) } @@ -267,7 +267,7 @@ class PropertiesTest { """.trimIndent(), UserProperties( view = View.SCROLL, - colCount = ColCount.AUTO, + colCount = ColCount.AUTO ).toCss() ) } @@ -322,7 +322,7 @@ class PropertiesTest { letterSpacing = Length.Rem(8.9), bodyHyphens = Hyphens.AUTO, ligatures = Ligatures.COMMON, - a11yNormalize = true, + a11yNormalize = true ).toCss() ) } diff --git a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/ReadiumCssTest.kt b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/ReadiumCssTest.kt index 093572d53a..debb5b0e52 100644 --- a/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/ReadiumCssTest.kt +++ b/readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/ReadiumCssTest.kt @@ -608,7 +608,7 @@ class ReadiumCssTest { googleFonts = listOf( FontFamily.OPEN_DYSLEXIC, FontFamily.SANS_SERIF, - FontFamily.SERIF, + FontFamily.SERIF ), assetsBaseHref = "/assets/" ) diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt index a300195080..4c15ad1da9 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt @@ -24,6 +24,8 @@ import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpRequest import org.readium.r2.shared.util.http.fetchWithDecoder +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever public enum class OPDSParserError { MissingTitle @@ -46,7 +48,10 @@ public object Namespaces { public class OPDS1Parser { public companion object { - public suspend fun parseUrlString(url: String, client: HttpClient = DefaultHttpClient()): Try { + public suspend fun parseUrlString( + url: String, + client: HttpClient = DefaultHttpClient(MediaTypeRetriever()) + ): Try { return client.fetchWithDecoder(HttpRequest(url)) { this.parse(it.body, URL(url)) } @@ -54,7 +59,7 @@ public class OPDS1Parser { public suspend fun parseRequest( request: HttpRequest, - client: HttpClient = DefaultHttpClient() + client: HttpClient = DefaultHttpClient(MediaTypeRetriever()) ): Try { return client.fetchWithDecoder(request) { this.parse(it.body, URL(request.url)) @@ -63,10 +68,11 @@ public class OPDS1Parser { public fun parse(xmlData: ByteArray, url: URL): ParseData { val root = XmlParser().parse(xmlData.inputStream()) - return if (root.name == "feed") + return if (root.name == "feed") { ParseData(parseFeed(root, url), null, 1) - else + } else { ParseData(null, parseEntry(root, url), 1) + } } private fun parseFeed(root: ElementNode, url: URL): Feed { @@ -127,7 +133,9 @@ public class OPDS1Parser { val newLink = Link( href = Href(href, baseHref = feed.href.toString()).percentEncodedString, - type = link.getAttr("type"), + mediaType = mediaTypeRetriever.retrieve( + mediaType = link.getAttr("type") + ), title = entry.getFirst("title", Namespaces.Atom)?.text, rels = listOfNotNull(link.getAttr("rel")).toSet(), properties = Properties(otherProperties = otherProperties) @@ -146,7 +154,7 @@ public class OPDS1Parser { val hrefAttr = link.getAttr("href") ?: continue val href = Href(hrefAttr, baseHref = feed.href.toString()).percentEncodedString val title = link.getAttr("title") - val type = link.getAttr("type") + val type = mediaTypeRetriever.retrieve(link.getAttr("type")) val rels = listOfNotNull(link.getAttr("rel")).toSet() val facetGroupName = link.getAttrNs("facetGroup", Namespaces.Opds) @@ -156,10 +164,16 @@ public class OPDS1Parser { if (facetElementCount != null) { otherProperties["numberOfItems"] = facetElementCount } - val newLink = Link(href = href, type = type, title = title, rels = rels, properties = Properties(otherProperties = otherProperties)) + val newLink = Link( + href = href, + mediaType = type, + title = title, + rels = rels, + properties = Properties(otherProperties = otherProperties) + ) addFacet(feed, newLink, facetGroupName) } else { - feed.links.add(Link(href = href, type = type, title = title, rels = rels)) + feed.links.add(Link(href = href, mediaType = type, title = title, rels = rels)) } } return feed @@ -179,15 +193,17 @@ public class OPDS1Parser { } @Suppress("unused") - public suspend fun retrieveOpenSearchTemplate(feed: Feed): Try { - + public suspend fun retrieveOpenSearchTemplate( + feed: Feed, + client: HttpClient = DefaultHttpClient(MediaTypeRetriever()) + ): Try { var openSearchURL: URL? = null - var selfMimeType: String? = null + var selfMimeType: MediaType? = null for (link in feed.links) { if (link.rels.contains("self")) { - if (link.type != null) { - selfMimeType = link.type + if (link.mediaType != null) { + selfMimeType = link.mediaType } } else if (link.rels.contains("search")) { openSearchURL = URL(link.href) @@ -198,8 +214,7 @@ public class OPDS1Parser { return@let it } - return DefaultHttpClient().fetchWithDecoder(HttpRequest(unwrappedURL.toString())) { - + return client.fetchWithDecoder(HttpRequest(unwrappedURL.toString())) { val document = XmlParser().parse(it.body.inputStream()) val urls = document.get("Url", Namespaces.Search) @@ -209,7 +224,7 @@ public class OPDS1Parser { selfMimeType?.let { s -> - val selfMimeParams = parseMimeType(mimeTypeString = s) + val selfMimeParams = parseMimeType(mimeTypeString = s.toString()) for (url in urls) { val urlMimeType = url.getAttr("type") ?: continue val otherMimeParams = parseMimeType(mimeTypeString = urlMimeType) @@ -263,7 +278,7 @@ public class OPDS1Parser { Link( href = Href(href, baseHref = baseUrl.toString()).percentEncodedString, - type = element.getAttr("type"), + mediaType = mediaTypeRetriever.retrieve(element.getAttr("type")), title = element.getAttr("title"), rels = listOfNotNull(rel).toSet(), properties = Properties(otherProperties = properties) @@ -271,7 +286,9 @@ public class OPDS1Parser { } val images = links.filter { - it.rels.contains("http://opds-spec.org/image") || it.rels.contains("http://opds-spec.org/image-thumbnail") + it.rels.contains("http://opds-spec.org/image") || it.rels.contains( + "http://opds-spec.org/image-thumbnail" + ) } links = links - images @@ -294,7 +311,11 @@ public class OPDS1Parser { publishers = entry.get("publisher", Namespaces.Dcterms) .mapNotNull { - it.text?.let { name -> Contributor(localizedName = LocalizedString(name)) } + it.text?.let { name -> + Contributor( + localizedName = LocalizedString(name) + ) + } }, subjects = entry.get("category", Namespaces.Atom) @@ -404,5 +425,7 @@ public class OPDS1Parser { children = fromXML(child) ) } + + public var mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever() } } diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt index 3656ba49c0..b7c137af48 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt @@ -15,7 +15,11 @@ import org.json.JSONArray import org.json.JSONObject import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.removeLastComponent -import org.readium.r2.shared.opds.* +import org.readium.r2.shared.opds.Facet +import org.readium.r2.shared.opds.Feed +import org.readium.r2.shared.opds.Group +import org.readium.r2.shared.opds.OpdsMetadata +import org.readium.r2.shared.opds.ParseData import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication @@ -24,13 +28,14 @@ import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpRequest import org.readium.r2.shared.util.http.fetchWithDecoder +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever public enum class OPDS2ParserError { MetadataNotFound, InvalidLink, MissingTitle, InvalidFacet, - InvalidGroup, + InvalidGroup } public class OPDS2Parser { @@ -39,7 +44,10 @@ public class OPDS2Parser { private lateinit var feed: Feed - public suspend fun parseUrlString(url: String, client: HttpClient = DefaultHttpClient()): Try { + public suspend fun parseUrlString( + url: String, + client: HttpClient = DefaultHttpClient(MediaTypeRetriever()) + ): Try { return client.fetchWithDecoder(HttpRequest(url)) { this.parse(it.body, URL(url)) } @@ -47,7 +55,7 @@ public class OPDS2Parser { public suspend fun parseRequest( request: HttpRequest, - client: HttpClient = DefaultHttpClient() + client: HttpClient = DefaultHttpClient(MediaTypeRetriever()) ): Try { return client.fetchWithDecoder(request) { this.parse(it.body, URL(request.url)) @@ -58,7 +66,14 @@ public class OPDS2Parser { return if (isFeed(jsonData)) { ParseData(parseFeed(jsonData, url), null, 2) } else { - ParseData(null, Manifest.fromJSON(JSONObject(String(jsonData)))?.let { Publication(it) }, 2) + ParseData( + null, + Manifest.fromJSON( + JSONObject(String(jsonData)), + mediaTypeRetriever = mediaTypeRetriever + )?.let { Publication(it) }, + 2 + ) } } @@ -199,7 +214,7 @@ public class OPDS2Parser { private fun parsePublications(feed: Feed, publications: JSONArray) { for (i in 0 until publications.length()) { val pubDict = publications.getJSONObject(i) - Manifest.fromJSON(pubDict)?.let { manifest -> + Manifest.fromJSON(pubDict, mediaTypeRetriever = mediaTypeRetriever)?.let { manifest -> feed.publications.add(Publication(manifest)) } } @@ -249,7 +264,7 @@ public class OPDS2Parser { ?: throw Exception(OPDS2ParserError.InvalidGroup.name) for (j in 0 until publications.length()) { val pubDict = publications.getJSONObject(j) - Manifest.fromJSON(pubDict)?.let { manifest -> + Manifest.fromJSON(pubDict, mediaTypeRetriever = mediaTypeRetriever)?.let { manifest -> group.publications.add(Publication(manifest)) } } @@ -260,7 +275,14 @@ public class OPDS2Parser { private fun parseLink(feed: Feed, json: JSONObject): Link? { val baseUrl = feed.href.removeLastComponent() - return Link.fromJSON(json, normalizeHref = { Href(it, baseUrl.toString()).string }) + return Link.fromJSON(json, mediaTypeRetriever, normalizeHref = { + Href( + it, + baseUrl.toString() + ).string + }) } + + public var mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever() } } diff --git a/readium/opds/src/test/java/org/readium/r2/opds/OPDS1ParserTest.kt b/readium/opds/src/test/java/org/readium/r2/opds/OPDS1ParserTest.kt index c8f91d6a1c..701ede334d 100644 --- a/readium/opds/src/test/java/org/readium/r2/opds/OPDS1ParserTest.kt +++ b/readium/opds/src/test/java/org/readium/r2/opds/OPDS1ParserTest.kt @@ -13,6 +13,7 @@ import org.readium.r2.shared.opds.OpdsMetadata import org.readium.r2.shared.opds.ParseData import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.Properties +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -35,32 +36,42 @@ class OPDS1ParserTest { links = mutableListOf( Link( href = "https://example.com/opds-catalogs/root.xml", - type = "application/atom+xml;profile=opds-catalog;kind=navigation", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=navigation" + )!!, rels = setOf("self"), properties = Properties() ), Link( href = "https://example.com/opds-catalogs/root.xml", - type = "application/atom+xml;profile=opds-catalog;kind=navigation", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=navigation" + )!!, rels = setOf("start") ) ), navigation = mutableListOf( Link( href = "https://example.com/opds-catalogs/popular.xml", - type = "application/atom+xml;profile=opds-catalog;kind=acquisition", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=acquisition" + )!!, title = "Popular Publications", rels = setOf("http://opds-spec.org/sort/popular") ), Link( href = "https://example.com/opds-catalogs/new.xml", - type = "application/atom+xml;profile=opds-catalog;kind=acquisition", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=acquisition" + )!!, title = "New Publications", rels = setOf("http://opds-spec.org/sort/new") ), Link( href = "https://example.com/opds-catalogs/unpopular.xml", - type = "application/atom+xml;profile=opds-catalog;kind=acquisition", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=acquisition" + )!!, title = "Unpopular Publications", rels = setOf("subsection") ) @@ -93,22 +104,30 @@ class OPDS1ParserTest { mutableListOf( Link( href = "https://example.com/opds-catalogs/vampire.farming.xml", - type = "application/atom+xml;profile=opds-catalog;kind=acquisition", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=acquisition" + )!!, rels = setOf("related") ), Link( href = "https://example.com/opds-catalogs/unpopular.xml", - type = "application/atom+xml;profile=opds-catalog;kind=acquisition", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=acquisition" + )!!, rels = setOf("self") ), Link( href = "https://example.com/opds-catalogs/root.xml", - type = "application/atom+xml;profile=opds-catalog;kind=navigation", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=navigation" + )!!, rels = setOf("start") ), Link( href = "https://example.com/opds-catalogs/root.xml", - type = "application/atom+xml;profile=opds-catalog;kind=navigation", + mediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=navigation" + )!!, rels = setOf("up") ) ), @@ -164,23 +183,25 @@ class OPDS1ParserTest { links = listOf( Link( href = "https://example.com/covers/4561.thmb.gif", - type = "image/gif", + mediaType = MediaType("image/gif")!!, rels = setOf("http://opds-spec.org/image/thumbnail") ), Link( href = "https://example.com/opds-catalogs/entries/4571.complete.xml", - type = "application/atom+xml;type=entry;profile=opds-catalog", + mediaType = MediaType( + "application/atom+xml;type=entry;profile=opds-catalog" + )!!, title = "Complete Catalog Entry for Bob, Son of Bob", rels = setOf("alternate") ), Link( href = "https://example.com/content/free/4561.epub", - type = "application/epub+zip", + mediaType = MediaType("application/epub+zip")!!, rels = setOf("http://opds-spec.org/acquisition") ), Link( href = "https://example.com/content/free/4561.mobi", - type = "application/x-mobipocket-ebook", + mediaType = MediaType("application/x-mobipocket-ebook")!!, rels = setOf("http://opds-spec.org/acquisition") ) ), @@ -190,13 +211,13 @@ class OPDS1ParserTest { links = listOf( Link( href = "https://example.com/covers/4561.lrg.png", - type = "image/png", + mediaType = MediaType("image/png")!!, rels = setOf("http://opds-spec.org/image") ) ) ) ) - ), + ) ).toJSON(), JSONObject(feed.publications[0].jsonManifest) ) @@ -230,9 +251,11 @@ class OPDS1ParserTest { links = listOf( Link( href = "https://example.com/content/buy/11241.epub", - type = "application/epub+zip", + mediaType = MediaType("application/epub+zip")!!, rels = setOf("http://opds-spec.org/acquisition/buy"), - properties = Properties(mapOf("price" to mapOf("currency" to "USD", "value" to 18.99))) + properties = Properties( + mapOf("price" to mapOf("currency" to "USD", "value" to 18.99)) + ) ) ), subcollections = mapOf( @@ -241,13 +264,13 @@ class OPDS1ParserTest { links = listOf( Link( href = "https://example.com/covers/11241.lrg.jpg", - type = "image/jpeg", + mediaType = MediaType("image/jpeg")!!, rels = setOf("http://opds-spec.org/image") ) ) ) ) - ), + ) ).toJSON(), JSONObject(feed.publications[1].jsonManifest) ) @@ -284,22 +307,24 @@ class OPDS1ParserTest { links = listOf( Link( href = "https://example.com/covers/4561.thmb.gif", - type = "image/gif", + mediaType = MediaType("image/gif")!!, rels = setOf("http://opds-spec.org/image/thumbnail") ), Link( href = "https://example.com/opds-catalogs/entries/4571.complete.xml", - type = "application/atom+xml;type=entry;profile=opds-catalog", + mediaType = MediaType( + "application/atom+xml;type=entry;profile=opds-catalog" + )!!, rels = setOf("self") ), Link( href = "https://example.com/content/free/4561.epub", - type = "application/epub+zip", + mediaType = MediaType("application/epub+zip")!!, rels = setOf("http://opds-spec.org/acquisition") ), Link( href = "https://example.com/content/free/4561.mobi", - type = "application/x-mobipocket-ebook", + mediaType = MediaType("application/x-mobipocket-ebook")!!, rels = setOf("http://opds-spec.org/acquisition") ) ), @@ -309,13 +334,13 @@ class OPDS1ParserTest { links = listOf( Link( href = "https://example.com/covers/4561.lrg.png", - type = "image/png", + mediaType = MediaType("image/png")!!, rels = setOf("http://opds-spec.org/image") ) ) ) ) - ), + ) ).toJSON(), JSONObject(publication!!.jsonManifest) ) diff --git a/readium/shared/src/androidTest/java/org/readium/r2/shared/util/HrefTest.kt b/readium/shared/src/androidTest/java/org/readium/r2/shared/util/HrefTest.kt index 34d201fbd5..3f98d7bb98 100644 --- a/readium/shared/src/androidTest/java/org/readium/r2/shared/util/HrefTest.kt +++ b/readium/shared/src/androidTest/java/org/readium/r2/shared/util/HrefTest.kt @@ -23,50 +23,166 @@ class HrefTest { assertEquals("/foo/bar.txt", Href("foo/bar.txt", "/file.txt").string) assertEquals("/foo/bar.txt", Href("foo/bar.txt", "/folder").string) assertEquals("/folder/foo/bar.txt", Href("foo/bar.txt", "/folder/").string) - assertEquals("http://example.com/folder/foo/bar.txt", Href("foo/bar.txt", "http://example.com/folder/file.txt").string) - assertEquals("http://example.com/foo/bar.txt", Href("foo/bar.txt", "http://example.com/folder").string) - assertEquals("http://example.com/folder/foo/bar.txt", Href("foo/bar.txt", "http://example.com/folder/").string) + assertEquals( + "http://example.com/folder/foo/bar.txt", + Href("foo/bar.txt", "http://example.com/folder/file.txt").string + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("foo/bar.txt", "http://example.com/folder").string + ) + assertEquals( + "http://example.com/folder/foo/bar.txt", + Href("foo/bar.txt", "http://example.com/folder/").string + ) + assertEquals( + "file:///root/folder/foo/bar.txt", + Href("foo/bar.txt", "file:///root/folder").string + ) + assertEquals( + "file:///root/folder/foo/bar.txt", + Href("foo/bar.txt", "file:///root/folder/").string + ) assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "").string) assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/").string) assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/file.txt").string) assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/folder").string) assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/folder/").string) - assertEquals("http://example.com/foo/bar.txt", Href("/foo/bar.txt", "http://example.com/folder/file.txt").string) - assertEquals("http://example.com/foo/bar.txt", Href("/foo/bar.txt", "http://example.com/folder").string) - assertEquals("http://example.com/foo/bar.txt", Href("/foo/bar.txt", "http://example.com/folder/").string) + assertEquals( + "http://example.com/foo/bar.txt", + Href("/foo/bar.txt", "http://example.com/folder/file.txt").string + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("/foo/bar.txt", "http://example.com/folder").string + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("/foo/bar.txt", "http://example.com/folder/").string + ) + assertEquals( + "file:///foo/bar.txt", + Href("/foo/bar.txt", "file:///root/folder").string + ) + assertEquals( + "file:///foo/bar.txt", + Href("/foo/bar.txt", "file:///root/folder/").string + ) assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "").string) assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/").string) assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/file.txt").string) assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/folder").string) assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/folder/").string) - assertEquals("http://example.com/foo/bar.txt", Href("../foo/bar.txt", "http://example.com/folder/file.txt").string) - assertEquals("http://example.com/foo/bar.txt", Href("../foo/bar.txt", "http://example.com/folder").string) - assertEquals("http://example.com/foo/bar.txt", Href("../foo/bar.txt", "http://example.com/folder/").string) + assertEquals( + "http://example.com/foo/bar.txt", + Href("../foo/bar.txt", "http://example.com/folder/file.txt").string + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("../foo/bar.txt", "http://example.com/folder").string + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("../foo/bar.txt", "http://example.com/folder/").string + ) + assertEquals( + "file:///root/folder/foo/bar.txt", + Href("../foo/bar.txt", "file:///root/folder/file.txt").string + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("../foo/bar.txt", "file:///root/folder").string + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("../foo/bar.txt", "file:///root/folder/").string + ) assertEquals("/bar.txt", Href("foo/../bar.txt", "").string) assertEquals("/bar.txt", Href("foo/../bar.txt", "/").string) assertEquals("/bar.txt", Href("foo/../bar.txt", "/file.txt").string) assertEquals("/bar.txt", Href("foo/../bar.txt", "/folder").string) assertEquals("/folder/bar.txt", Href("foo/../bar.txt", "/folder/").string) - assertEquals("http://example.com/folder/bar.txt", Href("foo/../bar.txt", "http://example.com/folder/file.txt").string) - assertEquals("http://example.com/bar.txt", Href("foo/../bar.txt", "http://example.com/folder").string) - assertEquals("http://example.com/folder/bar.txt", Href("foo/../bar.txt", "http://example.com/folder/").string) + assertEquals( + "http://example.com/folder/bar.txt", + Href("foo/../bar.txt", "http://example.com/folder/file.txt").string + ) + assertEquals( + "http://example.com/bar.txt", + Href("foo/../bar.txt", "http://example.com/folder").string + ) + assertEquals( + "http://example.com/folder/bar.txt", + Href("foo/../bar.txt", "http://example.com/folder/").string + ) + assertEquals( + "file:///root/folder/file.txt/bar.txt", + Href("foo/../bar.txt", "file:///root/folder/file.txt").string + ) + assertEquals( + "file:///root/folder/bar.txt", + Href("foo/../bar.txt", "file:///root/folder").string + ) + assertEquals( + "file:///root/folder/bar.txt", + Href("foo/../bar.txt", "file:///root/folder/").string + ) - assertEquals("http://absolute.com/foo/bar.txt", Href("http://absolute.com/foo/bar.txt", "/").string) - assertEquals("http://absolute.com/foo/bar.txt", Href("http://absolute.com/foo/bar.txt", "https://example.com/").string) + assertEquals( + "http://absolute.com/foo/bar.txt", + Href("http://absolute.com/foo/bar.txt", "/").string + ) + assertEquals( + "http://absolute.com/foo/bar.txt", + Href("http://absolute.com/foo/bar.txt", "https://example.com/").string + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("file:///root/foo/bar.txt", "/").string + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("file:///root/foo/bar.txt", "file://foo/").string + ) // Anchor and query parameters are preserved assertEquals("/foo/bar.txt#anchor", Href("foo/bar.txt#anchor", "/").string) - assertEquals("/foo/bar.txt?query=param#anchor", Href("foo/bar.txt?query=param#anchor", "/").string) - assertEquals("/foo/bar.txt?query=param#anchor", Href("/foo/bar.txt?query=param#anchor", "/").string) - assertEquals("http://absolute.com/foo/bar.txt?query=param#anchor", Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").string) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("foo/bar.txt?query=param#anchor", "/").string + ) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("/foo/bar.txt?query=param#anchor", "/").string + ) + assertEquals( + "http://absolute.com/foo/bar.txt?query=param#anchor", + Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").string + ) + assertEquals( + "file:///root/foo/bar.txt?query=param#anchor", + Href("file:///root/foo/bar.txt?query=param#anchor", "/").string + ) assertEquals("/foo/bar.txt#anchor", Href("foo/bar.txt#anchor", "/").string) - assertEquals("/foo/bar.txt?query=param#anchor", Href("foo/bar.txt?query=param#anchor", "/").string) - assertEquals("/foo/bar.txt?query=param#anchor", Href("/foo/bar.txt?query=param#anchor", "/").string) - assertEquals("http://absolute.com/foo/bar.txt?query=param#anchor", Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").string) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("foo/bar.txt?query=param#anchor", "/").string + ) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("/foo/bar.txt?query=param#anchor", "/").string + ) + assertEquals( + "http://absolute.com/foo/bar.txt?query=param#anchor", + Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").string + ) + assertEquals( + "file:///root/foo/bar.txt?query=param#anchor", + Href("file:///root/foo/bar.txt?query=param#anchor", "/").string + ) // HREF that is just an anchor assertEquals("/#anchor", Href("#anchor", "").string) @@ -74,30 +190,124 @@ class HrefTest { assertEquals("/file.txt#anchor", Href("#anchor", "/file.txt").string) assertEquals("/folder#anchor", Href("#anchor", "/folder").string) assertEquals("/folder/#anchor", Href("#anchor", "/folder/").string) - assertEquals("http://example.com/folder/file.txt#anchor", Href("#anchor", "http://example.com/folder/file.txt").string) - assertEquals("http://example.com/folder#anchor", Href("#anchor", "http://example.com/folder").string) - assertEquals("http://example.com/folder/#anchor", Href("#anchor", "http://example.com/folder/").string) + assertEquals( + "http://example.com/folder/file.txt#anchor", + Href("#anchor", "http://example.com/folder/file.txt").string + ) + assertEquals( + "http://example.com/folder#anchor", + Href("#anchor", "http://example.com/folder").string + ) + assertEquals( + "http://example.com/folder/#anchor", + Href("#anchor", "http://example.com/folder/").string + ) + assertEquals( + "file:///root/folder/file.txt#anchor", + Href("#anchor", "file:///root/folder/file.txt").string + ) + assertEquals( + "file:///root/folder#anchor", + Href("#anchor", "file:///root/folder").string + ) + assertEquals( + "file:///root/folder/#anchor", + Href("#anchor", "file:///root/folder/").string + ) // HREF containing spaces. assertEquals("/foo bar.txt", Href("foo bar.txt", "").string) assertEquals("/foo bar.txt", Href("foo bar.txt", "/").string) assertEquals("/foo bar.txt", Href("foo bar.txt", "/file.txt").string) assertEquals("/foo bar.txt", Href("foo bar.txt", "/base folder").string) - assertEquals("/base folder/foo bar.txt", Href("foo bar.txt", "/base folder/").string) - assertEquals("/base folder/foo bar.txt", Href("foo bar.txt", "/base folder/file.txt").string) - assertEquals("/base folder/foo bar.txt", Href("foo bar.txt", "base folder/file.txt").string) + assertEquals( + "/base folder/foo bar.txt", + Href("foo bar.txt", "/base folder/").string + ) + assertEquals( + "/base folder/foo bar.txt", + Href("foo bar.txt", "/base folder/file.txt").string + ) + assertEquals( + "/base folder/foo bar.txt", + Href("foo bar.txt", "base folder/file.txt").string + ) // HREF containing special characters - assertEquals("/base%folder/foo bar/baz%qux.txt", Href("foo bar/baz%qux.txt", "/base%folder/").string) - assertEquals("/base folder/foo bar/baz%qux.txt", Href("foo%20bar/baz%25qux.txt", "/base%20folder/").string) - assertEquals("http://example.com/foo bar/baz qux.txt", Href("foo bar/baz qux.txt", "http://example.com/base%20folder").string) - assertEquals("http://example.com/base folder/foo bar/baz qux.txt", Href("foo bar/baz qux.txt", "http://example.com/base%20folder/").string) - assertEquals("http://example.com/base folder/foo bar/baz%qux.txt", Href("foo bar/baz%qux.txt", "http://example.com/base%20folder/").string) - assertEquals("/foo bar.txt?query=param#anchor", Href("/foo bar.txt?query=param#anchor", "/").string) - assertEquals("http://example.com/foo bar.txt?query=param#anchor", Href("/foo bar.txt?query=param#anchor", "http://example.com/").string) - assertEquals("http://example.com/foo bar.txt?query=param#anchor", Href("/foo%20bar.txt?query=param#anchor", "http://example.com/").string) - assertEquals("http://absolute.com/foo bar.txt?query=param#Hello world £500", Href("http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", "/").string) - assertEquals("http://absolute.com/foo bar.txt?query=param#Hello world £500", Href("http://absolute.com/foo bar.txt?query=param#Hello world £500", "/").string) + assertEquals( + "/base%folder/foo bar/baz%qux.txt", + Href("foo bar/baz%qux.txt", "/base%folder/").string + ) + assertEquals( + "/base folder/foo bar/baz%qux.txt", + Href("foo%20bar/baz%25qux.txt", "/base%20folder/").string + ) + assertEquals( + "http://example.com/foo bar/baz qux.txt", + Href("foo bar/baz qux.txt", "http://example.com/base%20folder").string + ) + assertEquals( + "http://example.com/base folder/foo bar/baz qux.txt", + Href("foo bar/baz qux.txt", "http://example.com/base%20folder/").string + ) + assertEquals( + "http://example.com/base folder/foo bar/baz%qux.txt", + Href("foo bar/baz%qux.txt", "http://example.com/base%20folder/").string + ) + assertEquals( + "file:///root/base folder/foo bar/baz qux.txt", + Href("foo bar/baz qux.txt", "file:///root/base%20folder").string + ) + assertEquals( + "file:///root/base folder/foo bar/baz qux.txt", + Href("foo bar/baz qux.txt", "file:///root/base%20folder/").string + ) + assertEquals( + "file:///root/base folder/foo bar/baz%qux.txt", + Href("foo bar/baz%qux.txt", "file:///root/base%20folder/").string + ) + assertEquals( + "/foo bar.txt?query=param#anchor", + Href("/foo bar.txt?query=param#anchor", "/").string + ) + assertEquals( + "http://example.com/foo bar.txt?query=param#anchor", + Href("/foo bar.txt?query=param#anchor", "http://example.com/").string + ) + assertEquals( + "http://example.com/foo bar.txt?query=param#anchor", + Href("/foo%20bar.txt?query=param#anchor", "http://example.com/").string + ) + assertEquals( + "http://absolute.com/foo bar.txt?query=param#Hello world £500", + Href( + "http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + "/" + ).string + ) + assertEquals( + "http://absolute.com/foo bar.txt?query=param#Hello world £500", + Href("http://absolute.com/foo bar.txt?query=param#Hello world £500", "/").string + ) + assertEquals( + "file:///foo bar.txt?query=param#anchor", + Href("/foo bar.txt?query=param#anchor", "file:///root/").string + ) + assertEquals( + "file:///foo bar.txt?query=param#anchor", + Href("/foo%20bar.txt?query=param#anchor", "file:///root/").string + ) + assertEquals( + "file:///root/foo bar.txt?query=param#Hello world £500", + Href( + "file:///root/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + "/" + ).string + ) + assertEquals( + "file:///root/foo bar.txt?query=param#Hello world £500", + Href("file:///root/foo bar.txt?query=param#Hello world £500", "/").string + ) } @Test @@ -107,90 +317,409 @@ class HrefTest { assertEquals("/foo/bar.txt", Href("foo/bar.txt", "").percentEncodedString) assertEquals("/foo/bar.txt", Href("foo/bar.txt", "/").percentEncodedString) - assertEquals("/foo/bar.txt", Href("foo/bar.txt", "/file.txt").percentEncodedString) - assertEquals("/foo/bar.txt", Href("foo/bar.txt", "/folder").percentEncodedString) - assertEquals("/folder/foo/bar.txt", Href("foo/bar.txt", "/folder/").percentEncodedString) - assertEquals("http://example.com/folder/foo/bar.txt", Href("foo/bar.txt", "http://example.com/folder/file.txt").percentEncodedString) - assertEquals("http://example.com/foo/bar.txt", Href("foo/bar.txt", "http://example.com/folder").percentEncodedString) - assertEquals("http://example.com/folder/foo/bar.txt", Href("foo/bar.txt", "http://example.com/folder/").percentEncodedString) + assertEquals( + "/foo/bar.txt", + Href("foo/bar.txt", "/file.txt").percentEncodedString + ) + assertEquals( + "/foo/bar.txt", + Href("foo/bar.txt", "/folder").percentEncodedString + ) + assertEquals( + "/folder/foo/bar.txt", + Href("foo/bar.txt", "/folder/").percentEncodedString + ) + assertEquals( + "http://example.com/folder/foo/bar.txt", + Href( + "foo/bar.txt", + "http://example.com/folder/file.txt" + ).percentEncodedString + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("foo/bar.txt", "http://example.com/folder").percentEncodedString + ) + assertEquals( + "http://example.com/folder/foo/bar.txt", + Href("foo/bar.txt", "http://example.com/folder/").percentEncodedString + ) + assertEquals( + "file:///root/folder/foo/bar.txt", + Href("foo/bar.txt", "file:///root/folder").percentEncodedString + ) + assertEquals( + "file:///root/folder/foo/bar.txt", + Href("foo/bar.txt", "file:///root/folder/").percentEncodedString + ) assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "").percentEncodedString) assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/").percentEncodedString) - assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/file.txt").percentEncodedString) - assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/folder").percentEncodedString) - assertEquals("/foo/bar.txt", Href("/foo/bar.txt", "/folder/").percentEncodedString) - assertEquals("http://example.com/foo/bar.txt", Href("/foo/bar.txt", "http://example.com/folder/file.txt").percentEncodedString) - assertEquals("http://example.com/foo/bar.txt", Href("/foo/bar.txt", "http://example.com/folder").percentEncodedString) - assertEquals("http://example.com/foo/bar.txt", Href("/foo/bar.txt", "http://example.com/folder/").percentEncodedString) + assertEquals( + "/foo/bar.txt", + Href("/foo/bar.txt", "/file.txt").percentEncodedString + ) + assertEquals( + "/foo/bar.txt", + Href("/foo/bar.txt", "/folder").percentEncodedString + ) + assertEquals( + "/foo/bar.txt", + Href("/foo/bar.txt", "/folder/").percentEncodedString + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href( + "/foo/bar.txt", + "http://example.com/folder/file.txt" + ).percentEncodedString + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("/foo/bar.txt", "http://example.com/folder").percentEncodedString + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("/foo/bar.txt", "http://example.com/folder/").percentEncodedString + ) + assertEquals( + "file:///foo/bar.txt", + Href("/foo/bar.txt", "file:///root/folder/file.txt").percentEncodedString + ) + assertEquals( + "file:///foo/bar.txt", + Href("/foo/bar.txt", "file:///root/folder").percentEncodedString + ) + assertEquals( + "file:///foo/bar.txt", + Href("/foo/bar.txt", "file:///root/folder/").percentEncodedString + ) assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "").percentEncodedString) - assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/").percentEncodedString) - assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/file.txt").percentEncodedString) - assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/folder").percentEncodedString) - assertEquals("/foo/bar.txt", Href("../foo/bar.txt", "/folder/").percentEncodedString) - assertEquals("http://example.com/foo/bar.txt", Href("../foo/bar.txt", "http://example.com/folder/file.txt").percentEncodedString) - assertEquals("http://example.com/foo/bar.txt", Href("../foo/bar.txt", "http://example.com/folder").percentEncodedString) - assertEquals("http://example.com/foo/bar.txt", Href("../foo/bar.txt", "http://example.com/folder/").percentEncodedString) + assertEquals( + "/foo/bar.txt", + Href("../foo/bar.txt", "/").percentEncodedString + ) + assertEquals( + "/foo/bar.txt", + Href("../foo/bar.txt", "/file.txt").percentEncodedString + ) + assertEquals( + "/foo/bar.txt", + Href("../foo/bar.txt", "/folder").percentEncodedString + ) + assertEquals( + "/foo/bar.txt", + Href("../foo/bar.txt", "/folder/").percentEncodedString + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href( + "../foo/bar.txt", + "http://example.com/folder/file.txt" + ).percentEncodedString + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("../foo/bar.txt", "http://example.com/folder").percentEncodedString + ) + assertEquals( + "http://example.com/foo/bar.txt", + Href("../foo/bar.txt", "http://example.com/folder/").percentEncodedString + ) + assertEquals( + "file:///root/folder/foo/bar.txt", + Href( + "../foo/bar.txt", + "file:///root/folder/file.txt" + ).percentEncodedString + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("../foo/bar.txt", "file:///root/folder").percentEncodedString + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("../foo/bar.txt", "file:///root/folder/").percentEncodedString + ) assertEquals("/bar.txt", Href("foo/../bar.txt", "").percentEncodedString) assertEquals("/bar.txt", Href("foo/../bar.txt", "/").percentEncodedString) - assertEquals("/bar.txt", Href("foo/../bar.txt", "/file.txt").percentEncodedString) - assertEquals("/bar.txt", Href("foo/../bar.txt", "/folder").percentEncodedString) - assertEquals("/folder/bar.txt", Href("foo/../bar.txt", "/folder/").percentEncodedString) - assertEquals("http://example.com/folder/bar.txt", Href("foo/../bar.txt", "http://example.com/folder/file.txt").percentEncodedString) - assertEquals("http://example.com/bar.txt", Href("foo/../bar.txt", "http://example.com/folder").percentEncodedString) - assertEquals("http://example.com/folder/bar.txt", Href("foo/../bar.txt", "http://example.com/folder/").percentEncodedString) + assertEquals( + "/bar.txt", + Href("foo/../bar.txt", "/file.txt").percentEncodedString + ) + assertEquals( + "/bar.txt", + Href("foo/../bar.txt", "/folder").percentEncodedString + ) + assertEquals( + "/folder/bar.txt", + Href("foo/../bar.txt", "/folder/").percentEncodedString + ) + assertEquals( + "http://example.com/folder/bar.txt", + Href( + "foo/../bar.txt", + "http://example.com/folder/file.txt" + ).percentEncodedString + ) + assertEquals( + "http://example.com/bar.txt", + Href("foo/../bar.txt", "http://example.com/folder").percentEncodedString + ) + assertEquals( + "http://example.com/folder/bar.txt", + Href("foo/../bar.txt", "http://example.com/folder/").percentEncodedString + ) + assertEquals( + "file:///root/folder/file.txt/bar.txt", + Href( + "foo/../bar.txt", + "file:///root/folder/file.txt" + ).percentEncodedString + ) + assertEquals( + "file:///root/folder/bar.txt", + Href("foo/../bar.txt", "file:///root/folder").percentEncodedString + ) + assertEquals( + "file:///root/folder/bar.txt", + Href("foo/../bar.txt", "file:///root/folder/").percentEncodedString + ) - assertEquals("http://absolute.com/foo/bar.txt", Href("http://absolute.com/foo/bar.txt", "/").percentEncodedString) - assertEquals("http://absolute.com/foo/bar.txt", Href("http://absolute.com/foo/bar.txt", "https://example.com/").percentEncodedString) + assertEquals( + "http://absolute.com/foo/bar.txt", + Href("http://absolute.com/foo/bar.txt", "/").percentEncodedString + ) + assertEquals( + "http://absolute.com/foo/bar.txt", + Href("http://absolute.com/foo/bar.txt", "https://example.com/").percentEncodedString + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("file:///root/foo/bar.txt", "/").percentEncodedString + ) + assertEquals( + "file:///root/foo/bar.txt", + Href("file:///root/foo/bar.txt", "file:///root/").percentEncodedString + ) // Anchor and query parameters are preserved - assertEquals("/foo/bar.txt#anchor", Href("foo/bar.txt#anchor", "/").percentEncodedString) - assertEquals("/foo/bar.txt?query=param#anchor", Href("foo/bar.txt?query=param#anchor", "/").percentEncodedString) - assertEquals("/foo/bar.txt?query=param#anchor", Href("/foo/bar.txt?query=param#anchor", "/").percentEncodedString) - assertEquals("http://absolute.com/foo/bar.txt?query=param#anchor", Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").percentEncodedString) + assertEquals( + "/foo/bar.txt#anchor", + Href("foo/bar.txt#anchor", "/").percentEncodedString + ) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("foo/bar.txt?query=param#anchor", "/").percentEncodedString + ) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("/foo/bar.txt?query=param#anchor", "/").percentEncodedString + ) + assertEquals( + "http://absolute.com/foo/bar.txt?query=param#anchor", + Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").percentEncodedString + ) + assertEquals( + "file:///root/foo/bar.txt?query=param#anchor", + Href( + "file:///root/foo/bar.txt?query=param#anchor", + "/" + ).percentEncodedString + ) - assertEquals("/foo/bar.txt#anchor", Href("foo/bar.txt#anchor", "/").percentEncodedString) - assertEquals("/foo/bar.txt?query=param#anchor", Href("foo/bar.txt?query=param#anchor", "/").percentEncodedString) - assertEquals("/foo/bar.txt?query=param#anchor", Href("/foo/bar.txt?query=param#anchor", "/").percentEncodedString) - assertEquals("http://absolute.com/foo/bar.txt?query=param#anchor", Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").percentEncodedString) + assertEquals( + "/foo/bar.txt#anchor", + Href("foo/bar.txt#anchor", "/").percentEncodedString + ) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("foo/bar.txt?query=param#anchor", "/").percentEncodedString + ) + assertEquals( + "/foo/bar.txt?query=param#anchor", + Href("/foo/bar.txt?query=param#anchor", "/").percentEncodedString + ) + assertEquals( + "http://absolute.com/foo/bar.txt?query=param#anchor", + Href("http://absolute.com/foo/bar.txt?query=param#anchor", "/").percentEncodedString + ) + assertEquals( + "file:///root/foo/bar.txt?query=param#anchor", + Href( + "file:///root/foo/bar.txt?query=param#anchor", + "/" + ).percentEncodedString + ) // HREF that is just an anchor assertEquals("/#anchor", Href("#anchor", "").percentEncodedString) assertEquals("/#anchor", Href("#anchor", "/").percentEncodedString) - assertEquals("/file.txt#anchor", Href("#anchor", "/file.txt").percentEncodedString) - assertEquals("/folder#anchor", Href("#anchor", "/folder").percentEncodedString) - assertEquals("/folder/#anchor", Href("#anchor", "/folder/").percentEncodedString) - assertEquals("http://example.com/folder/file.txt#anchor", Href("#anchor", "http://example.com/folder/file.txt").percentEncodedString) - assertEquals("http://example.com/folder#anchor", Href("#anchor", "http://example.com/folder").percentEncodedString) - assertEquals("http://example.com/folder/#anchor", Href("#anchor", "http://example.com/folder/").percentEncodedString) + assertEquals( + "/file.txt#anchor", + Href("#anchor", "/file.txt").percentEncodedString + ) + assertEquals( + "/folder#anchor", + Href("#anchor", "/folder").percentEncodedString + ) + assertEquals( + "/folder/#anchor", + Href("#anchor", "/folder/").percentEncodedString + ) + assertEquals( + "http://example.com/folder/file.txt#anchor", + Href( + "#anchor", + "http://example.com/folder/file.txt" + ).percentEncodedString + ) + assertEquals( + "http://example.com/folder#anchor", + Href("#anchor", "http://example.com/folder").percentEncodedString + ) + assertEquals( + "http://example.com/folder/#anchor", + Href("#anchor", "http://example.com/folder/").percentEncodedString + ) + assertEquals( + "file:///root/folder/file.txt#anchor", + Href("#anchor", "file:///root/folder/file.txt").percentEncodedString + ) + assertEquals( + "file:///root/folder#anchor", + Href("#anchor", "file:///root/folder").percentEncodedString + ) + assertEquals( + "file:///root/folder/#anchor", + Href("#anchor", "file:///root/folder/").percentEncodedString + ) // HREF containing spaces. assertEquals("/foo%20bar.txt", Href("foo bar.txt", "").percentEncodedString) assertEquals("/foo%20bar.txt", Href("foo bar.txt", "/").percentEncodedString) - assertEquals("/foo%20bar.txt", Href("foo bar.txt", "/file.txt").percentEncodedString) - assertEquals("/foo%20bar.txt", Href("foo bar.txt", "/base folder").percentEncodedString) - assertEquals("/base%20folder/foo%20bar.txt", Href("foo bar.txt", "/base folder/").percentEncodedString) - assertEquals("/base%20folder/foo%20bar.txt", Href("foo bar.txt", "/base folder/file.txt").percentEncodedString) - assertEquals("/base%20folder/foo%20bar.txt", Href("foo bar.txt", "base folder/file.txt").percentEncodedString) + assertEquals( + "/foo%20bar.txt", + Href("foo bar.txt", "/file.txt").percentEncodedString + ) + assertEquals( + "/foo%20bar.txt", + Href("foo bar.txt", "/base folder").percentEncodedString + ) + assertEquals( + "/base%20folder/foo%20bar.txt", + Href("foo bar.txt", "/base folder/").percentEncodedString + ) + assertEquals( + "/base%20folder/foo%20bar.txt", + Href("foo bar.txt", "/base folder/file.txt").percentEncodedString + ) + assertEquals( + "/base%20folder/foo%20bar.txt", + Href("foo bar.txt", "base folder/file.txt").percentEncodedString + ) // HREF containing special characters - assertEquals("/base%25folder/foo%20bar/baz%25qux.txt", Href("foo bar/baz%qux.txt", "/base%folder/").percentEncodedString) - assertEquals("/base%20folder/foo%20bar/baz%25qux.txt", Href("foo%20bar/baz%25qux.txt", "/base%20folder/").percentEncodedString) - assertEquals("http://example.com/foo%20bar/baz%20qux.txt", Href("foo bar/baz qux.txt", "http://example.com/base%20folder").percentEncodedString) - assertEquals("http://example.com/base%20folder/foo%20bar/baz%20qux.txt", Href("foo bar/baz qux.txt", "http://example.com/base%20folder/").percentEncodedString) - assertEquals("http://example.com/base%20folder/foo%20bar/baz%25qux.txt", Href("foo bar/baz%qux.txt", "http://example.com/base%20folder/").percentEncodedString) - assertEquals("/foo%20bar.txt?query=param#anchor", Href("/foo bar.txt?query=param#anchor", "/").percentEncodedString) - assertEquals("http://example.com/foo%20bar.txt?query=param#anchor", Href("/foo bar.txt?query=param#anchor", "http://example.com/").percentEncodedString) - assertEquals("http://example.com/foo%20bar.txt?query=param#anchor", Href("/foo%20bar.txt?query=param#anchor", "http://example.com/").percentEncodedString) - assertEquals("http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", Href("http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", "/").percentEncodedString) - assertEquals("http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", Href("http://absolute.com/foo bar.txt?query=param#Hello world £500", "/").percentEncodedString) + assertEquals( + "/base%25folder/foo%20bar/baz%25qux.txt", + Href("foo bar/baz%qux.txt", "/base%folder/").percentEncodedString + ) + assertEquals( + "/base%20folder/foo%20bar/baz%25qux.txt", + Href("foo%20bar/baz%25qux.txt", "/base%20folder/").percentEncodedString + ) + assertEquals( + "http://example.com/foo%20bar/baz%20qux.txt", + Href("foo bar/baz qux.txt", "http://example.com/base%20folder").percentEncodedString + ) + assertEquals( + "http://example.com/base%20folder/foo%20bar/baz%20qux.txt", + Href("foo bar/baz qux.txt", "http://example.com/base%20folder/").percentEncodedString + ) + assertEquals( + "http://example.com/base%20folder/foo%20bar/baz%25qux.txt", + Href("foo bar/baz%qux.txt", "http://example.com/base%20folder/").percentEncodedString + ) + assertEquals( + "file:///root/base%20folder/foo%20bar/baz%20qux.txt", + Href( + "foo bar/baz qux.txt", + "file:///root/base%20folder" + ).percentEncodedString + ) + assertEquals( + "file:///root/base%20folder/foo%20bar/baz%20qux.txt", + Href( + "foo bar/baz qux.txt", + "file:///root/base%20folder/" + ).percentEncodedString + ) + assertEquals( + "file:///root/base%20folder/foo%20bar/baz%25qux.txt", + Href( + "foo bar/baz%qux.txt", + "file:///root/base%20folder/" + ).percentEncodedString + ) + assertEquals( + "/foo%20bar.txt?query=param#anchor", + Href("/foo bar.txt?query=param#anchor", "/").percentEncodedString + ) + assertEquals( + "http://example.com/foo%20bar.txt?query=param#anchor", + Href("/foo bar.txt?query=param#anchor", "http://example.com/").percentEncodedString + ) + assertEquals( + "http://example.com/foo%20bar.txt?query=param#anchor", + Href("/foo%20bar.txt?query=param#anchor", "http://example.com/").percentEncodedString + ) + assertEquals( + "http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + Href( + "http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + "/" + ).percentEncodedString + ) + assertEquals( + "http://absolute.com/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + Href("http://absolute.com/foo bar.txt?query=param#Hello world £500", "/").percentEncodedString + ) + assertEquals( + "file:///foo%20bar.txt?query=param#anchor", + Href( + "/foo bar.txt?query=param#anchor", + "file:///root/" + ).percentEncodedString + ) + assertEquals( + "file:///foo%20bar.txt?query=param#anchor", + Href( + "/foo%20bar.txt?query=param#anchor", + "file:///root/" + ).percentEncodedString + ) + assertEquals( + "file:///root/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + Href( + "file:///root/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + "/" + ).percentEncodedString + ) + assertEquals( + "file:///root/foo%20bar.txt?query=param#Hello%20world%20%C2%A3500", + Href("file:///root/foo bar.txt?query=param#Hello world £500", "/").percentEncodedString + ) } @Test fun getQueryParameters() { assertEquals(emptyList(), Href("http://domain.com/path").queryParameters) - assertEquals(listOf(QueryParameter(name = "query", value = "param")), Href("http://domain.com/path?query=param#anchor").queryParameters) + assertEquals( + listOf(QueryParameter(name = "query", value = "param")), + Href("http://domain.com/path?query=param#anchor").queryParameters + ) assertEquals( listOf( QueryParameter(name = "query", value = "param"), @@ -228,7 +757,7 @@ class HrefTest { assertEquals(params.allNamed("query"), listOf("param", "other")) assertEquals(params.allNamed("fruit"), listOf("banana")) - assertEquals(params.allNamed("empty"), emptyList()) - assertEquals(params.allNamed("not-found"), emptyList()) + assertEquals(params.allNamed("empty"), emptyList()) + assertEquals(params.allNamed("not-found"), emptyList()) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/Deprecated.kt b/readium/shared/src/main/java/org/readium/r2/shared/Deprecated.kt index 268a1d9c20..3d2afcded9 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/Deprecated.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/Deprecated.kt @@ -23,87 +23,178 @@ import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.Subject import org.readium.r2.shared.publication.encryption.Encryption import org.readium.r2.shared.publication.presentation.Presentation -import org.readium.r2.shared.util.Href -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Locator"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Locator"), + level = DeprecationLevel.ERROR +) public typealias Locator = org.readium.r2.shared.publication.Locator -@Deprecated("Renamed into [Locator.Locations]", ReplaceWith("Locator.Locations", "org.readium.r2.shared.publication.Locator"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed into [Locator.Locations]", + ReplaceWith("Locator.Locations", "org.readium.r2.shared.publication.Locator"), + level = DeprecationLevel.ERROR +) public typealias Locations = org.readium.r2.shared.publication.Locator.Locations -@Deprecated("Renamed into [Locator.Text]", ReplaceWith("Locator.Text", "org.readium.r2.shared.publication.Locator"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed into [Locator.Text]", + ReplaceWith("Locator.Text", "org.readium.r2.shared.publication.Locator"), + level = DeprecationLevel.ERROR +) public typealias LocatorText = org.readium.r2.shared.publication.Locator.Text -@Deprecated("Moved to another package", ReplaceWith("Locator.Text", "org.readium.r2.shared.publication.html.DomRange"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("Locator.Text", "org.readium.r2.shared.publication.html.DomRange"), + level = DeprecationLevel.ERROR +) public typealias DomRange = org.readium.r2.shared.publication.html.DomRange -@Deprecated("Renamed into [DomRange.Point]", ReplaceWith("DomRange.Point", "org.readium.r2.shared.publication.html.DomRange"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed into [DomRange.Point]", + ReplaceWith("DomRange.Point", "org.readium.r2.shared.publication.html.DomRange"), + level = DeprecationLevel.ERROR +) public typealias Range = org.readium.r2.shared.publication.html.DomRange.Point -@Deprecated("Refactored into [LocalizedString]", ReplaceWith("org.readium.r2.shared.publication.LocalizedString"), level = DeprecationLevel.ERROR) +@Deprecated( + "Refactored into [LocalizedString]", + ReplaceWith("org.readium.r2.shared.publication.LocalizedString"), + level = DeprecationLevel.ERROR +) public typealias MultilanguageString = org.readium.r2.shared.publication.LocalizedString -@Deprecated("Renamed into [ReadingProgression]", ReplaceWith("org.readium.r2.shared.publication.ReadingProgression"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed into [ReadingProgression]", + ReplaceWith("org.readium.r2.shared.publication.ReadingProgression"), + level = DeprecationLevel.ERROR +) public typealias PageProgressionDirection = org.readium.r2.shared.publication.ReadingProgression -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Publication"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Publication"), + level = DeprecationLevel.ERROR +) public typealias Publication = org.readium.r2.shared.publication.Publication -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Link"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Link"), + level = DeprecationLevel.ERROR +) public typealias Link = Link -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Properties"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Properties"), + level = DeprecationLevel.ERROR +) public typealias Properties = Properties -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Metadata"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Metadata"), + level = DeprecationLevel.ERROR +) public typealias Metadata = Metadata -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Contributor"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Contributor"), + level = DeprecationLevel.ERROR +) public typealias Contributor = Contributor -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Collection"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Collection"), + level = DeprecationLevel.ERROR +) public typealias Collection = Collection -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.Subject"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.Subject"), + level = DeprecationLevel.ERROR +) public typealias Subject = Subject -@Deprecated("Moved to another package", ReplaceWith("org.readium.r2.shared.publication.encryption.Encryption"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("org.readium.r2.shared.publication.encryption.Encryption"), + level = DeprecationLevel.ERROR +) public typealias Encryption = Encryption -@Deprecated("Refactored into [Presentation]", ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation"), level = DeprecationLevel.ERROR) +@Deprecated( + "Refactored into [Presentation]", + ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation"), + level = DeprecationLevel.ERROR +) public typealias Rendition = Presentation -@Deprecated("Refactored into [EpubLayout]", ReplaceWith("org.readium.r2.shared.publication.epub.EpubLayout"), level = DeprecationLevel.ERROR) +@Deprecated( + "Refactored into [EpubLayout]", + ReplaceWith("org.readium.r2.shared.publication.epub.EpubLayout"), + level = DeprecationLevel.ERROR +) public typealias RenditionLayout = org.readium.r2.shared.publication.epub.EpubLayout -@Deprecated("Refactored into [Presentation.Overflow]", ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation.Overflow"), level = DeprecationLevel.ERROR) +@Deprecated( + "Refactored into [Presentation.Overflow]", + ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation.Overflow"), + level = DeprecationLevel.ERROR +) public typealias RenditionFlow = Presentation.Overflow -@Deprecated("Refactored into [Presentation.Orientation]", ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation.Orientation"), level = DeprecationLevel.ERROR) +@Deprecated( + "Refactored into [Presentation.Orientation]", + ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation.Orientation"), + level = DeprecationLevel.ERROR +) public typealias RenditionOrientation = Presentation.Orientation -@Deprecated("Refactored into [Presentation.Spread]", ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation.Spread"), level = DeprecationLevel.ERROR) +@Deprecated( + "Refactored into [Presentation.Spread]", + ReplaceWith("org.readium.r2.shared.publication.presentation.Presentation.Spread"), + level = DeprecationLevel.ERROR +) public typealias RenditionSpread = Presentation.Spread -@Deprecated("Use [Manifest::fromJSON] instead", ReplaceWith("Manifest.fromJSON(pubDict)", "org.readium.r2.shared.publication.Manifest"), level = DeprecationLevel.ERROR) -public fun parsePublication(pubDict: JSONObject): org.readium.r2.shared.publication.Publication { - return org.readium.r2.shared.publication.Manifest.fromJSON(pubDict)?.let { Publication(it) } - ?: throw Exception("Invalid publication") +@Deprecated( + "Use [Manifest::fromJSON] instead", + ReplaceWith("Manifest.fromJSON(pubDict)", "org.readium.r2.shared.publication.Manifest"), + level = DeprecationLevel.ERROR +) +public fun parsePublication(): org.readium.r2.shared.publication.Publication = + throw NotImplementedError() + +@Suppress("Unused_parameter") +@Deprecated( + "Use [Link::fromJSON] instead", + ReplaceWith("Link.fromJSON(linkDict)", "org.readium.r2.shared.publication.Link"), + level = DeprecationLevel.ERROR +) +public fun parseLink(linkDict: JSONObject, feedUrl: URL? = null): Link { + throw NotImplementedError() } -@Deprecated("Use [Link::fromJSON] instead", ReplaceWith("Link.fromJSON(linkDict)", "org.readium.r2.shared.publication.Link"), level = DeprecationLevel.ERROR) -public fun parseLink(linkDict: JSONObject, feedUrl: URL? = null): Link = - Link.fromJSON(linkDict, normalizeHref = { - if (feedUrl == null) { - it - } else { - Href(it, baseHref = feedUrl.toString()).string - } - }) ?: Link(href = "#") - -@Deprecated("Moved to another package", ReplaceWith("removeLastComponent()", "org.readium.r2.shared.extensions.removeLastComponent"), level = DeprecationLevel.ERROR) +@Deprecated( + "Moved to another package", + ReplaceWith("removeLastComponent()", "org.readium.r2.shared.extensions.removeLastComponent"), + level = DeprecationLevel.ERROR +) public fun URL.removeLastComponent(): URL = removeLastComponent() -@Deprecated("Use `Href().string` instead", replaceWith = ReplaceWith("Href(href, base).string"), level = DeprecationLevel.ERROR) -public fun normalize(base: String, href: String?): String = - Href(href ?: "", baseHref = base).string +@Suppress("Unused_parameter") +@Deprecated( + "Use `Href().string` instead", + replaceWith = ReplaceWith("Href(href, base).string"), + level = DeprecationLevel.ERROR +) +public fun normalize(base: String, href: String?): String { + throw NotImplementedError() +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/MediaOverlays.kt b/readium/shared/src/main/java/org/readium/r2/shared/MediaOverlays.kt index 71b95528a2..184c86cc7b 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/MediaOverlays.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/MediaOverlays.kt @@ -22,10 +22,11 @@ public data class MediaOverlays(private val nodes: List = list private fun findNode(ref: String?, inNodes: List): MediaOverlayNode? { for (node in inNodes) { - if (node.role.contains("section")) + if (node.role.contains("section")) { return findNode(ref, node.children) - else if (ref == null || node.text == ref) + } else if (ref == null || node.text == ref) { return node + } } return null } @@ -40,10 +41,11 @@ public data class MediaOverlays(private val nodes: List = list for (node in inNodes) { if (prevNodeFoundFlag) { // If the node is a section, we get the first non section child. - if (node.role.contains("section")) + if (node.role.contains("section")) { getFirstNonSectionChild(node)?.let { return NextNodeResult(it, false) } - else + } else { return NextNodeResult(node, false) + } } else { // If the node is a "section" ( sequence element) if (node.role.contains("section")) { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/OptIn.kt b/readium/shared/src/main/java/org/readium/r2/shared/OptIn.kt index 7afc6ad859..0107964486 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/OptIn.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/OptIn.kt @@ -14,7 +14,13 @@ package org.readium.r2.shared message = "This is an internal API that should not be used outside of Readium modules. No compatibility guarantees are provided." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY, AnnotationTarget.CONSTRUCTOR) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY, + AnnotationTarget.CONSTRUCTOR +) public annotation class InternalReadiumApi @RequiresOptIn( @@ -22,7 +28,12 @@ public annotation class InternalReadiumApi message = "This API is still experimental. It might change in the future without notice." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class ExperimentalReadiumApi @RequiresOptIn( @@ -30,7 +41,12 @@ public annotation class ExperimentalReadiumApi message = "This is a delicate API and its use requires care. Make sure you fully read and understand documentation of the declaration that is marked as a delicate API." ) @Retention(value = AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class DelicateReadiumApi @RequiresOptIn( @@ -38,7 +54,12 @@ public annotation class DelicateReadiumApi message = "Support for PDF is still experimental. The API may be changed in the future without notice." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class PdfSupport @RequiresOptIn( @@ -46,5 +67,10 @@ public annotation class PdfSupport message = "Support for SearchService is still experimental. The API may be changed in the future without notice." ) @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.PROPERTY +) public annotation class Search diff --git a/readium/shared/src/main/java/org/readium/r2/shared/ReadiumCSS.kt b/readium/shared/src/main/java/org/readium/r2/shared/ReadiumCSS.kt index f3b62944dd..40257e49e7 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/ReadiumCSS.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/ReadiumCSS.kt @@ -2,55 +2,80 @@ package org.readium.r2.shared @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val FONT_SIZE_REF: String = "fontSize" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val FONT_FAMILY_REF: String = "fontFamily" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val FONT_OVERRIDE_REF: String = "fontOverride" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val APPEARANCE_REF: String = "appearance" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val SCROLL_REF: String = "scroll" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val PUBLISHER_DEFAULT_REF: String = "advancedSettings" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val TEXT_ALIGNMENT_REF: String = "textAlign" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val COLUMN_COUNT_REF: String = "colCount" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val WORD_SPACING_REF: String = "wordSpacing" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val LETTER_SPACING_REF: String = "letterSpacing" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val PAGE_MARGINS_REF: String = "pageMargins" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val LINE_HEIGHT_REF: String = "lineHeight" @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val FONT_SIZE_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val FONT_FAMILY_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val FONT_OVERRIDE_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val APPEARANCE_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val SCROLL_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val PUBLISHER_DEFAULT_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val TEXT_ALIGNMENT_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val COLUMN_COUNT_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val WORD_SPACING_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val LETTER_SPACING_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val PAGE_MARGINS_NAME: String = "" + @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) public const val LINE_HEIGHT_NAME: String = "" // List of strings that can identify the name of a CSS custom property // Also used for storing UserSettings in UserDefaults -@Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.WARNING) +@Deprecated( + "Migrate to the new Settings API (see migration guide)", + level = DeprecationLevel.WARNING +) public enum class ReadiumCSSName(public val ref: String) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/RootFile.kt b/readium/shared/src/main/java/org/readium/r2/shared/RootFile.kt index 194c1c29c1..4feb2055d6 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/RootFile.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/RootFile.kt @@ -12,6 +12,7 @@ package org.readium.r2.shared @Deprecated("Not used anymore", level = DeprecationLevel.ERROR) public class RootFile { public var rootPath: String = "" + // Path to OPF public var rootFilePath: String = "" public var mimetype: String = "" diff --git a/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt b/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt index 515bd7fd7b..c7bb22f0f9 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/UserException.kt @@ -97,8 +97,15 @@ public open class UserException protected constructor( } var message = - if (quantity != null) context.resources.getQuantityString(userMessageId, quantity, *(args.toTypedArray())) - else context.getString(userMessageId, *(args.toTypedArray())) + if (quantity != null) { + context.resources.getQuantityString( + userMessageId, + quantity, + *(args.toTypedArray()) + ) + } else { + context.getString(userMessageId, *(args.toTypedArray())) + } // Includes nested causes if they are also [UserException]. val userException = cause?.asInstance() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt b/readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt index e4c2938d08..2650b284b1 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/asset/Asset.kt @@ -6,6 +6,8 @@ package org.readium.r2.shared.asset +import org.readium.r2.shared.resource.Container as SharedContainer +import org.readium.r2.shared.resource.Resource as SharedResource import org.readium.r2.shared.util.mediatype.MediaType /** @@ -14,20 +16,15 @@ import org.readium.r2.shared.util.mediatype.MediaType public sealed class Asset { /** - * Name of the asset, e.g. a filename. + * Type of the asset source. */ - public abstract val name: String + public abstract val assetType: AssetType /** * Media type of the asset. */ public abstract val mediaType: MediaType - /** - * Type of the asset source. - */ - public abstract val assetType: AssetType - /** * Releases in-memory resources related to this asset. */ @@ -36,14 +33,12 @@ public sealed class Asset { /** * A single resource asset. * - * @param name Name of the asset. * @param mediaType Media type of the asset. * @param resource Opened resource to access the asset. */ public class Resource( - override val name: String, override val mediaType: MediaType, - public val resource: org.readium.r2.shared.resource.Resource + public val resource: SharedResource ) : Asset() { override val assetType: AssetType = @@ -57,23 +52,22 @@ public sealed class Asset { /** * A container asset providing access to several resources. * - * @param name Name of the asset. * @param mediaType Media type of the asset. * @param exploded If this container is an exploded or packaged container. * @param container Opened container to access asset resources. */ public class Container( - override val name: String, override val mediaType: MediaType, exploded: Boolean, - public val container: org.readium.r2.shared.resource.Container + public val container: SharedContainer ) : Asset() { override val assetType: AssetType = - if (exploded) + if (exploded) { AssetType.Directory - else + } else { AssetType.Archive + } override suspend fun close() { container.close() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt index 2b9aaff848..3397366111 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt @@ -9,36 +9,60 @@ package org.readium.r2.shared.asset import android.content.ContentResolver import android.content.Context import android.net.Uri +import android.provider.MediaStore import java.io.File import org.readium.r2.shared.error.ThrowableError import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.flatMap -import org.readium.r2.shared.resource.* +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.extensions.queryProjection +import org.readium.r2.shared.resource.ArchiveFactory +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.ContainerFactory +import org.readium.r2.shared.resource.ContainerMediaTypeSnifferContent +import org.readium.r2.shared.resource.DefaultArchiveFactory +import org.readium.r2.shared.resource.DirectoryContainerFactory +import org.readium.r2.shared.resource.FileResourceFactory +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceFactory +import org.readium.r2.shared.resource.ResourceMediaTypeSnifferContent +import org.readium.r2.shared.util.Either import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.mediatype.* +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeHints +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.shared.util.toUrl +/** + * Retrieves an [Asset] instance providing reading access to the resource(s) of an asset stored at a + * given [Url]. + */ public class AssetRetriever( + private val mediaTypeRetriever: MediaTypeRetriever, private val resourceFactory: ResourceFactory, private val containerFactory: ContainerFactory, private val archiveFactory: ArchiveFactory, - contentResolver: ContentResolver, - sniffers: List + private val contentResolver: ContentResolver ) { - public constructor(context: Context) : this( - resourceFactory = FileResourceFactory(), - containerFactory = DirectoryContainerFactory(), - archiveFactory = DefaultArchiveFactory(), - contentResolver = context.contentResolver, - sniffers = MediaType.sniffers - ) + public companion object { + public operator fun invoke(context: Context): AssetRetriever { + val mediaTypeRetriever = MediaTypeRetriever() + return AssetRetriever( + mediaTypeRetriever = mediaTypeRetriever, + resourceFactory = FileResourceFactory(mediaTypeRetriever), + containerFactory = DirectoryContainerFactory(mediaTypeRetriever), + archiveFactory = DefaultArchiveFactory(mediaTypeRetriever), + contentResolver = context.contentResolver + ) + } + } public sealed class Error : org.readium.r2.shared.error.Error { public class SchemeNotSupported( public val scheme: String, - override val cause: org.readium.r2.shared.error.Error?, + override val cause: org.readium.r2.shared.error.Error? ) : Error() { public constructor(scheme: String, exception: Exception) : @@ -129,21 +153,24 @@ public class AssetRetriever( } /** - * Retrieves an asset from a known media and asset type again. + * Retrieves an asset from a known media and asset type. */ public suspend fun retrieve( url: Url, mediaType: MediaType, assetType: AssetType - ): Try = - when (assetType) { + ): Try { + return when (assetType) { AssetType.Archive -> retrieveArchiveAsset(url, mediaType) + AssetType.Directory -> retrieveDirectoryAsset(url, mediaType) + AssetType.Resource -> retrieveResourceAsset(url, mediaType) } + } private suspend fun retrieveArchiveAsset( url: Url, @@ -163,7 +190,7 @@ public class AssetRetriever( } } } - .map { container -> Asset.Container(url.filename, mediaType, false, container) } + .map { container -> Asset.Container(mediaType, exploded = false, container) } } private suspend fun retrieveDirectoryAsset( @@ -172,7 +199,7 @@ public class AssetRetriever( ): Try { return containerFactory.create(url) .map { container -> - Asset.Container(url.filename, mediaType, true, container) + Asset.Container(mediaType, exploded = true, container) } .mapFailure { error -> when (error) { @@ -191,11 +218,11 @@ public class AssetRetriever( mediaType: MediaType ): Try { return retrieveResource(url) - .map { resource -> Asset.Resource(url.filename, mediaType, resource) } + .map { resource -> Asset.Resource(mediaType, resource) } } private suspend fun retrieveResource( - url: Url, + url: Url ): Try { return resourceFactory.create(url) .mapFailure { error -> @@ -227,130 +254,94 @@ public class AssetRetriever( /* Sniff unknown assets */ - private val snifferContextFactory: UrlSnifferContextFactory = - UrlSnifferContextFactory(resourceFactory, containerFactory, archiveFactory) - - private val mediaTypeRetriever: MediaTypeRetriever = - MediaTypeRetriever(resourceFactory, containerFactory, archiveFactory, contentResolver, sniffers) - /** * Retrieves an asset from a local file. */ - public suspend fun retrieve( - file: File, - mediaType: String? = null, - fileExtension: String? = null, - ): Asset? = - retrieve( - file, - mediaTypes = listOfNotNull(mediaType), - fileExtensions = listOfNotNull(fileExtension) - ) + public suspend fun retrieve(file: File): Asset? = + retrieve(file.toUrl()) /** - * Retrieves an asset from a local file. + * Retrieves an asset from a [Uri]. */ - public suspend fun retrieve( - file: File, - mediaTypes: List, - fileExtensions: List, - ): Asset? { - val context = snifferContextFactory - .createContext( - file.toUrl(), - mediaTypes = mediaTypes, - fileExtensions = listOf(file.extension) + fileExtensions - ) ?: return null - - return retrieve(context, file.name) - } - - /** - * Retrieves an asset from an Uri. - */ - public suspend fun retrieve( - uri: Uri, - mediaType: String? = null, - fileExtension: String? = null, - ): Asset? = - retrieve( - uri, - mediaTypes = listOfNotNull(mediaType), - fileExtensions = listOfNotNull(fileExtension) - ) - - /** - * Retrieves an asset from a Uri. - */ - public suspend fun retrieve( - uri: Uri, - mediaTypes: List, - fileExtensions: List, - ): Asset? { + public suspend fun retrieve(uri: Uri): Asset? { val url = uri.toUrl() ?: return null - return retrieve(url, mediaTypes, fileExtensions) + return retrieve(url) } /** - * Retrieves an asset from a Url. + * Retrieves an asset from a [Url]. */ - public suspend fun retrieve( - url: Url, - mediaType: String? = null, - fileExtension: String? = null - ): Asset? { - return retrieve(url, listOfNotNull(mediaType), listOfNotNull(fileExtension)) + public suspend fun retrieve(url: Url): Asset? { + val resource = resourceFactory + .create(url) + .getOrElse { error -> + when (error) { + is ResourceFactory.Error.NotAResource -> + return containerFactory.create(url).getOrNull() + ?.let { retrieve(url, it, exploded = true) } + else -> return null + } + } + + return archiveFactory.create(resource, password = null) + .fold( + { retrieve(url, container = it, exploded = false) }, + { retrieve(url, resource) } + ) } - /** - * Retrieves an asset from a Url. - */ - public suspend fun retrieve( + private suspend fun retrieve( url: Url, - mediaTypes: List, - fileExtensions: List + container: Container, + exploded: Boolean ): Asset? { - val context = snifferContextFactory - .createContext( - url, - mediaTypes = mediaTypes, - fileExtensions = buildList { - addAll(fileExtensions) - url.extension?.let { add(it) } - } - ) + val mediaType = retrieveMediaType(url, Either(container)) ?: return null + return Asset.Container(mediaType, exploded = exploded, container = container) + } - return retrieve(context, url.filename) + private suspend fun retrieve(url: Url, resource: Resource): Asset? { + val mediaType = retrieveMediaType(url, Either(resource)) + ?: return null + return Asset.Resource(mediaType, resource = resource) } - private suspend fun retrieve( - context: ContentAwareSnifferContext, - fallbackName: String - ): Asset? { + private suspend fun retrieveMediaType( + url: Url, + asset: Either + ): MediaType? { + suspend fun retrieve(hints: MediaTypeHints): MediaType? = + mediaTypeRetriever.retrieve( + hints = hints, + content = when (asset) { + is Either.Left -> ResourceMediaTypeSnifferContent(asset.value) + is Either.Right -> ContainerMediaTypeSnifferContent(asset.value) + } + ) - val mediaType = mediaTypeRetriever.doRetrieve( - fullContext = { context }, - mediaTypes = context.mediaTypes.map(MediaType::toString), - fileExtensions = context.fileExtensions - ) ?: return null - - return when (context) { - is ContainerSnifferContext -> - Asset.Container( - name = context.container.name().getOrNull() ?: fallbackName, - mediaType = mediaType, - exploded = context.isExploded, - container = context.container - ) - is ResourceSnifferContext -> - Asset.Resource( - name = context.resource.name().getOrNull() ?: fallbackName, - mediaType = mediaType, - resource = context.resource - ) + retrieve(MediaTypeHints(fileExtensions = listOfNotNull(url.extension))) + ?.let { return it } + + // Falls back on the [contentResolver] in case of content Uri. + // Note: This is done after the heavy sniffing of the provided [sniffers], because + // otherwise it will detect JSON, XML or ZIP formats before we have a chance of sniffing + // their content (for example, for RWPM). + + if (url.scheme == ContentResolver.SCHEME_CONTENT) { + val contentHints = MediaTypeHints( + mediaType = contentResolver.getType(url.uri) + ?.let { MediaType(it)!! } + ?.takeUnless { it.matches(MediaType.BINARY) }, + fileExtension = contentResolver + .queryProjection(url.uri, MediaStore.MediaColumns.DISPLAY_NAME) + ?.let { filename -> File(filename).extension } + ) + + retrieve(contentHints)?.let { return it } } + + return null } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/drm/DRM.kt b/readium/shared/src/main/java/org/readium/r2/shared/drm/DRM.kt index 30784496a7..4f8cd7178f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/drm/DRM.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/drm/DRM.kt @@ -15,14 +15,10 @@ import java.io.Serializable public class DRM { @Deprecated("Not used anymore", level = DeprecationLevel.ERROR) - public enum class Brand(public val rawValue: String) : Serializable { - lcp("lcp"); - } + public enum class Brand(public val rawValue: String) : Serializable @Deprecated("Not used anymore", level = DeprecationLevel.ERROR) - public enum class Scheme(public val rawValue: String) : Serializable { - lcp("http://readium.org/2014/01/lcp"); - } + public enum class Scheme(public val rawValue: String) : Serializable } @Deprecated("Not used anymore", level = DeprecationLevel.ERROR) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt b/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt index dedf070fa7..6855e4496a 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt @@ -42,7 +42,7 @@ public class ThrowableError( * A basic [Error] implementation with a message. */ public class MessageError( - override val message: String, + override val message: String ) : Error { override val cause: Error? = null diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Bitmap.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Bitmap.kt index b1d4b87e39..8a6b9e3915 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Bitmap.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Bitmap.kt @@ -21,8 +21,9 @@ import org.readium.r2.shared.InternalReadiumApi * Resizes a bitmap to fit [maxSize] with bilinear filtering. */ internal fun Bitmap.scaleToFit(maxSize: Size): Bitmap { - if (width <= maxSize.width && height <= maxSize.height) + if (width <= maxSize.width && height <= maxSize.height) { return this + } val ratio = min( maxSize.width / width.toFloat(), diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/ByteArray.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/ByteArray.kt index 19149a5bd1..9606e762e2 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/ByteArray.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/ByteArray.kt @@ -47,3 +47,14 @@ public fun ByteArray.md5(): String? = Timber.e(e) null } + +internal fun ByteArray.read(range: LongRange?): ByteArray { + range ?: return this + + @Suppress("NAME_SHADOWING") + val range = range + .coerceIn(0L until size) + .requireLengthFitInt() + + return sliceArray(range.map(Long::toInt)) +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt index f380f89ca9..bc52a94ead 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/File.kt @@ -14,7 +14,6 @@ import java.io.FileInputStream import java.security.MessageDigest import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber /** @@ -68,6 +67,7 @@ public fun File.isParentOf(other: File): Boolean { * * If unknown, fallback on `MediaType.BINARY`. */ +@Suppress("UnusedReceiverParameter", "RedundantSuspendModifier", "UNUSED_PARAMETER") @Deprecated("Explicitly use MediaTypeRetriever", level = DeprecationLevel.ERROR) public suspend fun File.mediaType(mediaTypeHint: String? = null): MediaType = - MediaTypeRetriever().retrieve(this, mediaType = mediaTypeHint) ?: MediaType.BINARY + throw NotImplementedError() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt index 30d1c9dd13..2d1e1441be 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/InputStream.kt @@ -62,8 +62,9 @@ internal suspend fun InputStream.readRange(range: LongRange): ByteArray { .coerceFirstNonNegative() .requireLengthFitInt() - if (range.isEmpty()) + if (range.isEmpty()) { return ByteArray(0) + } return withContext(Dispatchers.IO) { val skipped = skip(range.first) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt index 5536b235ab..cc050e1a47 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/Intent.kt @@ -14,27 +14,37 @@ import android.content.Intent import android.os.Bundle import java.util.* import org.readium.r2.shared.BuildConfig -import org.readium.r2.shared.publication.LocalizedString import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Metadata import org.readium.r2.shared.publication.Publication import timber.log.Timber private const val extraKey = "publicationId" -private val deprecationException = IllegalArgumentException("The [publication] intent extra is not supported anymore. Use the shared [PublicationRepository] instead.") - -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +private val deprecationException = IllegalArgumentException( + "The [publication] intent extra is not supported anymore. Use the shared [PublicationRepository] instead." +) + +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Intent.putPublication(publication: Publication) { val id = PublicationRepository.add(publication) putExtra(extraKey, id) } -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Intent.putPublicationFrom(activity: Activity) { putExtra(extraKey, activity.intent.getStringExtra(extraKey)) } -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Intent.getPublication(activity: Activity?): Publication { if (hasExtra("publication")) { if (BuildConfig.DEBUG) { @@ -49,14 +59,17 @@ public fun Intent.getPublication(activity: Activity?): Publication { if (publication == null) { activity?.finish() // Fallbacks on a dummy Publication to avoid crashing the app until the Activity finishes. - val metadata = Metadata(identifier = "dummy", localizedTitle = LocalizedString("")) + val metadata = Metadata(identifier = "dummy") return Publication(Manifest(metadata = metadata)) } return publication } -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Intent.getPublicationOrNull(): Publication? { if (hasExtra("publication")) { if (BuildConfig.DEBUG) { @@ -75,7 +88,10 @@ public fun Intent.getPublicationOrNull(activity: Activity): Publication? { throw NotImplementedError() } -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Intent.destroyPublication(activity: Activity?) { if (activity == null || activity.isFinishing) { getStringExtra(extraKey)?.let { @@ -84,18 +100,27 @@ public fun Intent.destroyPublication(activity: Activity?) { } } -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Bundle.putPublication(publication: Publication) { val id = PublicationRepository.add(publication) putString(extraKey, id) } -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Bundle.putPublicationFrom(activity: Activity) { putString(extraKey, activity.intent.getStringExtra(extraKey)) } -@Deprecated("Use a repository to share publications between components", level = DeprecationLevel.ERROR) +@Deprecated( + "Use a repository to share publications between components", + level = DeprecationLevel.ERROR +) public fun Bundle.getPublicationOrNull(): Publication? { return getString(extraKey)?.let { PublicationRepository.get(it) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/JSON.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/JSON.kt index 1c506afc18..9d811c538e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/JSON.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/JSON.kt @@ -302,7 +302,7 @@ public fun JSONObject.mapNotNull(transform: (Pair) -> T?): List * If the tranform returns `null`, it is not included in the output list. */ @InternalReadiumApi -public fun JSONArray.mapNotNull(transform: (Any) -> T?): List { +public inline fun JSONArray.mapNotNull(transform: (Any) -> T?): List { val result = mutableListOf() for (i in 0 until length()) { val transformedValue = transform(get(i)) @@ -331,7 +331,7 @@ internal fun JSONArray.filterIsInstance(klass: Class): List { /** * Parses a [JSONArray] of [JSONObject] into a [List] of models using the given [factory]. */ -internal fun JSONArray?.parseObjects(factory: (Any) -> T?): List { +internal inline fun JSONArray?.parseObjects(factory: (Any) -> T?): List { this ?: return emptyList() val models = mutableListOf() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/extensions/LongRange.kt b/readium/shared/src/main/java/org/readium/r2/shared/extensions/LongRange.kt index 9e1ac1d830..5e43eecd5b 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/extensions/LongRange.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/extensions/LongRange.kt @@ -15,10 +15,17 @@ import org.readium.r2.shared.InternalReadiumApi public fun LongRange.coerceFirstNonNegative(): LongRange = LongRange(first.coerceAtLeast(0), last) @InternalReadiumApi -public fun LongRange.coerceIn(range: LongRange): LongRange = LongRange(first.coerceAtLeast(range.first), last.coerceAtMost(range.last)) +public fun LongRange.coerceIn(range: LongRange): LongRange = LongRange( + first.coerceAtLeast(range.first), + last.coerceAtMost(range.last) +) @InternalReadiumApi -public fun LongRange.requireLengthFitInt(): LongRange = this.apply { require(last - first + 1 <= Int.MAX_VALUE) } +public fun LongRange.requireLengthFitInt(): LongRange = this.apply { + require( + last - first + 1 <= Int.MAX_VALUE + ) +} internal fun LongRange.contains(range: LongRange) = contains(range.first) && contains(range.last) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt deleted file mode 100644 index 56c4f32efd..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/BytesResource.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ -package org.readium.r2.shared.fetcher - -import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.InternalReadiumApi -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.resource.Resource -import org.readium.r2.shared.resource.ResourceTry - -@InternalReadiumApi -public sealed class BaseBytesResource( - private val link: Link, - protected val resource: org.readium.r2.shared.resource.BytesResource -) : Resource by resource, Fetcher.Resource { - - protected constructor(link: Link, bytes: suspend () -> ResourceTry) : - this(link, org.readium.r2.shared.resource.BytesResource(bytes)) - - protected constructor(link: Link, bytes: ByteArray) : - this(link, { Try.success(bytes) }) - - override suspend fun link(): Link = - link - - override fun toString(): String = - "${javaClass.simpleName}(${runBlocking { length().getOrNull() }} bytes)" -} - -/** Creates a Resource serving [ByteArray]. */ -public class BytesResource( - link: Link, - bytes: suspend () -> ByteArray -) : BaseBytesResource(link, { Try.success(bytes()) }) { - - public constructor(link: Link, bytes: ByteArray) : this(link, { bytes }) -} - -/** Creates a Resource serving a [String]. */ -public class StringResource( - link: Link, - string: suspend () -> String -) : BaseBytesResource(link, { Try.success(string()).map { it.toByteArray() } }) { - - public constructor(link: Link, string: String) : this(link, { string }) - - override fun toString(): String = - "${javaClass.simpleName}(${runBlocking { resource.bytes().map { it.toString() } } })" -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt deleted file mode 100644 index 46e9624c0a..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ContainerFetcher.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.fetcher - -import java.io.File -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrDefault -import org.readium.r2.shared.error.tryRecover -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Properties -import org.readium.r2.shared.resource.Container -import org.readium.r2.shared.resource.Resource -import org.readium.r2.shared.resource.ResourceTry -import org.readium.r2.shared.resource.ZipContainer -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever -import org.readium.r2.shared.util.use - -/** Provides access to entries of a [Container]. */ -public class ContainerFetcher( - private val container: Container, - private val mediaTypeRetriever: MediaTypeRetriever -) : Fetcher { - - override suspend fun links(): List = - container.entries() - ?.map { it.toLink(mediaTypeRetriever) } - ?: emptyList() - - override fun get(link: Link): Fetcher.Resource = - EntryResource(link, container) - - override suspend fun close() { - container.close() - } - - private class EntryResource( - val originalLink: Link, - val container: Container - ) : Fetcher.Resource { - - override suspend fun link(): Link = - withEntry { entry -> - val enhancedLink = (entry as? ZipContainer.Entry) - ?.let { originalLink.addProperties(entry.toLinkProperties()) } - ?: originalLink - - Try.success(enhancedLink) - }.getOrDefault(originalLink) - - override suspend fun read(range: LongRange?): ResourceTry = - withEntry { entry -> entry.read(range) } - - override suspend fun length(): ResourceTry = - metadataLength() - .tryRecover { read().map { it.size.toLong() } } - - override suspend fun close() { - } - - private suspend fun metadataLength(): ResourceTry = - withEntry { entry -> entry.length() } - - suspend fun withEntry(block: suspend (Container.Entry) -> ResourceTry): ResourceTry = - originalLink.href - .let { href -> container.entry(href) } - .let { entry -> entry.use { block(entry) } } - .takeIf { result -> result.failureOrNull() !is Resource.Exception.NotFound } - ?: run { - // Try again after removing query and fragment. - originalLink.href - .takeWhile { it !in "#?" } - .let { href -> container.entry(href) } - .let { entry -> entry.use { block(entry) } } - } - - override fun toString(): String = - "${javaClass.simpleName}(${container::class.java.simpleName}, ${originalLink.href})" - } -} - -private suspend fun Container.Entry.toLink(mediaTypeRetriever: MediaTypeRetriever): Link { - return Link( - href = path, - type = mediaTypeRetriever.retrieve(fileExtension = File(path).extension)?.toString(), - properties = Properties((this as? ZipContainer.Entry)?.toLinkProperties().orEmpty()) - ) -} - -private suspend fun ZipContainer.Entry.toLinkProperties(): Map { - return mutableMapOf( - "archive" to mapOf( - "entryLength" to (compressedLength ?: length().getOrNull() ?: 0), - "isEntryCompressed" to (compressedLength != null) - ) - ) -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt deleted file mode 100644 index 3b4b9ec203..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Fetcher.kt +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.fetcher - -import java.io.File -import org.readium.r2.shared.fetcher.Fetcher.Resource -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.resource.ResourceTry -import org.readium.r2.shared.util.SuspendingCloseable - -/** Provides access to a [Resource] from a [Link]. */ -public interface Fetcher : SuspendingCloseable { - - /** - * Acts as a proxy to an actual resource by handling read access. - */ - public interface Resource : org.readium.r2.shared.resource.Resource { - - /** - * Returns the link from which the resource was retrieved. - * - * It might be modified by the [Resource] to include additional metadata, e.g. the - * `Content-Type` HTTP header in [Link.type]. - */ - public suspend fun link(): Link - } - - /** - * Known resources available in the medium, such as file paths on the file system - * or entries in a ZIP archive. This list is not exhaustive, and additional - * unknown resources might be reachable. - * - * If the medium has an inherent resource order, it should be followed. - * Otherwise, HREFs are sorted alphabetically. - */ - public suspend fun links(): List - - /** - * Returns the [Resource] at the given [link]'s HREF. - * - * A [Resource] is always returned, since for some cases we can't know if it exists before - * actually fetching it, such as HTTP. Therefore, errors are handled at the Resource level. - */ - public fun get(link: Link): Resource - - /** Returns the [Resource] at the given [href]. */ - public fun get(href: String): Resource = - get(Link(href = href)) - - // To be able to add extensions on Fetcher.Companion in other components... - public companion object -} - -/** A [Fetcher] providing no resources at all. */ -public class EmptyFetcher : Fetcher { - - override suspend fun links(): List = - emptyList() - - override fun get(link: Link): Resource = - FailureResource(link, org.readium.r2.shared.resource.Resource.Exception.NotFound()) - - override suspend fun close() {} -} - -public class ResourceFetcher( - private val link: Link, - private val resource: org.readium.r2.shared.resource.Resource -) : Fetcher { - - public companion object { - - public suspend operator fun invoke(resource: Resource): ResourceFetcher { - val link = resource.link() - return ResourceFetcher(link, resource) - } - } - - public class Resource( - private val link: Link, - private val resource: org.readium.r2.shared.resource.Resource - ) : Fetcher.Resource { - - override val file: File? = - resource.file - - override suspend fun link(): Link = - link - - override suspend fun length(): ResourceTry = - resource.length() - - override suspend fun read(range: LongRange?): ResourceTry = - resource.read(range) - - override suspend fun close() { - } - } - - override suspend fun links(): List = - listOf(link) - - override fun get(link: Link): Fetcher.Resource { - if (link.href.takeWhile { it !in "#?" } != this.link.href) { - val exception = org.readium.r2.shared.resource.Resource.Exception.NotFound() - return FailureResource(link, exception) - } - - return Resource(link, resource) - } - - override suspend fun close() { - resource.close() - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt deleted file mode 100644 index 904274f0bf..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/FileFetcher.kt +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.fetcher - -import java.io.File -import java.lang.ref.WeakReference -import java.util.* -import org.readium.r2.shared.extensions.* -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.resource.Resource -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever - -/** - * Provides access to resources on the local file system. - * - * [paths] contains the reachable local paths, indexed by the exposed HREF. Sub-paths are reachable - * as well, to be able to access a whole directory. - */ -public class FileFetcher( - private val paths: Map, - private val mediaTypeRetriever: MediaTypeRetriever -) : Fetcher { - - /** Provides access to the given local [file] at [href]. */ - public constructor(href: String, file: File, mediaTypeRetriever: MediaTypeRetriever) : - this(mapOf(href to file), mediaTypeRetriever) - - private val openedResources: MutableList> = LinkedList() - - override suspend fun links(): List = - paths.toSortedMap().flatMap { (href, file) -> - file.walk().toList().mapNotNull { - tryOrNull { - if (it.isDirectory) { - null - } else { - Link( - href = File(href, it.canonicalPath.removePrefix(file.canonicalPath)).canonicalPath, - type = mediaTypeRetriever.retrieve(it)?.toString() - ) - } - } - } - } - - override fun get(link: Link): Fetcher.Resource { - val linkHref = link.href.addPrefix("/") - for ((itemHref, itemFile) in paths) { - @Suppress("NAME_SHADOWING") - val itemHref = itemHref.addPrefix("/") - if (linkHref.startsWith(itemHref)) { - val resourceFile = File(itemFile, linkHref.removePrefix(itemHref)) - // Make sure that the requested resource is [path] or one of its descendant. - if (resourceFile.canonicalPath.startsWith(itemFile.canonicalPath)) { - val resource = FileResource(link, resourceFile) - openedResources.add(WeakReference(resource)) - return resource - } - } - } - return FailureResource(link, Resource.Exception.NotFound()) - } - - override suspend fun close() { - openedResources.mapNotNull(WeakReference::get).forEach { it.close() } - openedResources.clear() - } - - public class FileResource( - public val link: Link, - public val resource: org.readium.r2.shared.resource.FileResource - ) : Resource by resource, Fetcher.Resource { - - public companion object { - - public operator fun invoke(link: Link, file: File): FileResource = - FileResource(link, org.readium.r2.shared.resource.FileResource(file)) - } - - override suspend fun link(): Link = - link - - override fun toString(): String = - "${javaClass.simpleName}(${resource.file.path})" - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt deleted file mode 100644 index d2c91fc141..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/Resource.kt +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.fetcher - -import java.io.File -import kotlinx.coroutines.* -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import org.readium.r2.shared.InternalReadiumApi -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap -import org.readium.r2.shared.extensions.coerceIn -import org.readium.r2.shared.extensions.contains -import org.readium.r2.shared.extensions.requireLengthFitInt -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.resource.Resource -import org.readium.r2.shared.resource.ResourceTry - -/** - * Implements the transformation of a Resource. It can be used, for example, to decrypt, - * deobfuscate, inject CSS or JavaScript, correct content – e.g. adding a missing dir="rtl" in an - * HTML document, pre-process – e.g. before indexing a publication's content, etc. - * - * If the transformation doesn't apply, simply return resource unchanged. - */ -public typealias ResourceTransformer = (Fetcher.Resource) -> Fetcher.Resource - -/** Creates a Resource that will always return the given [error]. */ -public class FailureResource(private val link: Link, private val error: Resource.Exception) : - Fetcher.Resource { - - internal constructor(link: Link, cause: Throwable) : this(link, Resource.Exception.Other(cause)) - - override suspend fun link(): Link = link - - override suspend fun read(range: LongRange?): ResourceTry = Try.failure(error) - - override suspend fun length(): ResourceTry = Try.failure(error) - - override suspend fun close() {} - - override fun toString(): String = - "${javaClass.simpleName}($error)" -} - -/** - * Resource that will act as a proxy to a fallback resource if the [originalResource] errors out. - */ -public class FallbackResource( - private val originalResource: Fetcher.Resource, - private val fallbackResourceFactory: (Resource.Exception) -> Fetcher.Resource -) : Fetcher.Resource { - private val coroutineScope = - CoroutineScope(Dispatchers.Default) - - private val resource: Deferred = - coroutineScope.async { - when (val result = originalResource.length()) { - is Try.Success -> originalResource - is Try.Failure -> fallbackResourceFactory(result.value) - } - } - - override suspend fun link(): Link = - resource.await().link() - - override suspend fun length(): ResourceTry = - resource.await().length() - - override suspend fun read(range: LongRange?): ResourceTry = - resource.await().read(range) - - @OptIn(ExperimentalCoroutinesApi::class) - override suspend fun close() { - coroutineScope.cancel() - if (resource.isCompleted) { - resource.getCompleted().close() - } - } -} - -/** - * Falls back to alternative resources when the receiver fails. - */ -public fun Fetcher.Resource.fallback( - fallbackResourceFactory: (Resource.Exception) -> Fetcher.Resource -): Fetcher.Resource = - FallbackResource(this, fallbackResourceFactory) - -/** - * Falls back to the given alternative [Fetcher.Resource] when the receiver fails. - */ -public fun Fetcher.Resource.fallback(fallbackResource: Fetcher.Resource): Fetcher.Resource = - FallbackResource(this) { fallbackResource } - -/** - * A base class for a [Resource] which acts as a proxy to another one. - * - * Every function is delegating to the proxied resource, and subclasses should override some of them. - */ -public abstract class ProxyResource(protected val resource: Fetcher.Resource) : Fetcher.Resource { - - override val file: File? = resource.file - - override suspend fun link(): Link = resource.link() - - override suspend fun length(): ResourceTry = resource.length() - - override suspend fun read(range: LongRange?): ResourceTry = resource.read(range) - - override suspend fun close() { resource.close() } - - override fun toString(): String = - "${javaClass.simpleName}($resource)" -} - -/** - * Transforms the bytes of [resource] on-the-fly. - * - * If you set [cacheBytes] to false, consider providing your own implementation of [length] to avoid - * unnecessary transformations. - * - * Warning: The transformation runs on the full content of [resource], so it's not appropriate for - * large resources which can't be held in memory. - */ -public abstract class TransformingResource( - resource: Fetcher.Resource, - private val cacheBytes: Boolean = true -) : ProxyResource(resource) { - - public companion object { - /** - * Creates a [TransformingResource] using the given [transform] function. - */ - public operator fun invoke( - resource: Fetcher.Resource, - transform: suspend (ByteArray) -> ByteArray - ): TransformingResource = - object : TransformingResource(resource) { - override suspend fun transform(data: ResourceTry): ResourceTry = - data.mapCatching { transform(it) } - } - } - - private lateinit var _bytes: ResourceTry - - public abstract suspend fun transform(data: ResourceTry): ResourceTry - - private suspend fun bytes(): ResourceTry { - if (::_bytes.isInitialized) - return _bytes - - val bytes = transform(resource.read()) - if (cacheBytes) - _bytes = bytes - - return bytes - } - - override suspend fun read(range: LongRange?): ResourceTry = - bytes().map { - if (range == null) - return bytes() - - @Suppress("NAME_SHADOWING") - val range = range - .coerceIn(0L until it.size) - .requireLengthFitInt() - - it.sliceArray(range.map(Long::toInt)) - } - - override suspend fun length(): ResourceTry = bytes().map { it.size.toLong() } -} - -/** - * Wraps a [Fetcher.Resource] which will be created only when first accessing one of its members. - */ -public class LazyResource(private val factory: suspend () -> Fetcher.Resource) : Fetcher.Resource { - - private lateinit var _resource: Fetcher.Resource - - private suspend fun resource(): Fetcher.Resource { - if (!::_resource.isInitialized) - _resource = factory() - - return _resource - } - - override suspend fun link(): Link = - resource().link() - - override suspend fun length(): ResourceTry = - resource().length() - - override suspend fun read(range: LongRange?): ResourceTry = - resource().read(range) - - override suspend fun close() { - if (::_resource.isInitialized) - _resource.close() - } - - override fun toString(): String = - if (::_resource.isInitialized) { - "${javaClass.simpleName}($_resource)" - } else { - "${javaClass.simpleName}(...)" - } -} - -/** - * Protects the access to a wrapped resource with a mutex to make it thread-safe. - * - * This doesn't implement [ProxyResource] to avoid forgetting the synchronization for a future API. - */ -public class SynchronizedResource( - private val resource: Fetcher.Resource -) : Fetcher.Resource { - - private val mutex = Mutex() - - override val file: File? = - resource.file - - override suspend fun link(): Link = - mutex.withLock { resource.link() } - - override suspend fun length(): ResourceTry = - mutex.withLock { resource.length() } - - override suspend fun read(range: LongRange?): ResourceTry = - mutex.withLock { resource.read(range) } - - override suspend fun close() { - mutex.withLock { resource.close() } - } - - override fun toString(): String = - "${javaClass.simpleName}($resource)" -} - -/** - * Wraps this resource in a [SynchronizedResource] to protect the access from multiple threads. - */ -public fun Fetcher.Resource.synchronized(): SynchronizedResource = - SynchronizedResource(this) - -/** - * Wraps a [Resource] and buffers its content. - * - * Expensive interaction with the underlying resource is minimized, since most (smaller) requests - * can be satisfied by accessing the buffer alone. The drawback is that some extra space is required - * to hold the buffer and that copying takes place when filling that buffer, but this is usually - * outweighed by the performance benefits. - * - * Note that this implementation is pretty limited and the benefits are only apparent when reading - * forward and consecutively – e.g. when downloading the resource by chunks. The buffer is ignored - * when reading backward or far ahead. - * - * @param resource Underlying resource which will be buffered. - * @param resourceLength The total length of the resource, when known. This can improve performance - * by avoiding requesting the length from the underlying resource. - * @param bufferSize Size of the buffer chunks to read. - */ -public class BufferingResource( - resource: Fetcher.Resource, - resourceLength: Long? = null, - private val bufferSize: Long = DEFAULT_BUFFER_SIZE, -) : ProxyResource(resource) { - - internal companion object { - internal const val DEFAULT_BUFFER_SIZE: Long = 8192 - } - - /** - * The buffer containing the current bytes read from the wrapped [Resource], with the range it - * covers. - */ - private var buffer: Pair? = null - - private lateinit var _cachedLength: ResourceTry - private suspend fun cachedLength(): ResourceTry { - if (!::_cachedLength.isInitialized) - _cachedLength = resource.length() - return _cachedLength - } - - init { - if (resourceLength != null) { - _cachedLength = Try.success(resourceLength) - } - } - - override suspend fun read(range: LongRange?): ResourceTry { - val length = cachedLength().getOrNull() - // Reading the whole resource bypasses buffering to keep things simple. - if (range == null || length == null) { - return super.read(range) - } - - val requestedRange = range - .coerceIn(0L until length) - .requireLengthFitInt() - if (requestedRange.isEmpty()) { - return Try.success(ByteArray(0)) - } - - // Round up the range to be read to the next `bufferSize`, because we will buffer the - // excess. - val readLast = (requestedRange.last + 1).ceilMultipleOf(bufferSize).coerceAtMost(length) - var readRange = requestedRange.first until readLast - - // Attempt to serve parts or all of the request using the buffer. - buffer?.let { pair -> - var (buffer, bufferedRange) = pair - - // Everything already buffered? - if (bufferedRange.contains(requestedRange)) { - val data = extractRange(requestedRange, buffer, start = bufferedRange.first) - return Try.success(data) - - // Beginning of requested data is buffered? - } else if (bufferedRange.contains(requestedRange.first)) { - readRange = (bufferedRange.last + 1)..readRange.last - - return super.read(readRange).map { readData -> - buffer += readData - // Shift the current buffer to the tail of the read data. - saveBuffer(buffer, readRange) - - val bytes = extractRange(requestedRange, buffer, start = bufferedRange.first) - bytes - } - } - } - - // Fallback on reading the requested range from the original resource. - return super.read(readRange).map { data -> - saveBuffer(data, readRange) - - val res = if (data.count() > requestedRange.count()) - data.copyOfRange(0, requestedRange.count()) - else - data - - res - } - } - - /** - * Keeps the last chunk of the given data as the buffer for next reads. - * - * @param data Data read from the original resource. - * @param range Range of the read data in the resource. - */ - private fun saveBuffer(data: ByteArray, range: LongRange) { - val lastChunk = data.takeLast(bufferSize.toInt()).toByteArray() - val chunkRange = (range.last + 1 - lastChunk.count())..range.last - buffer = Pair(lastChunk, chunkRange) - } - - /** - * Reads a sub-range of the given [data] after shifting the given absolute (to the resource) - * ranges to be relative to [data]. - */ - private fun extractRange(requestedRange: LongRange, data: ByteArray, start: Long): ByteArray { - val first = requestedRange.first - start - val lastExclusive = first + requestedRange.count() - require(first >= 0) - require(lastExclusive <= data.count()) { "$lastExclusive > ${data.count()}" } - return data.copyOfRange(first.toInt(), lastExclusive.toInt()) - } - - private fun Long.ceilMultipleOf(divisor: Long) = - divisor * (this / divisor + if (this % divisor == 0L) 0 else 1) -} - -/** - * Wraps this resource in a [BufferingResource] to improve reading performances. - * - * @param resourceLength The total length of the resource, when known. This can improve performance - * by avoiding requesting the length from the underlying resource. - * @param size Size of the buffer chunks to read. - */ -public fun Fetcher.Resource.buffered( - resourceLength: Long? = null, - size: Long = BufferingResource.DEFAULT_BUFFER_SIZE -): BufferingResource = - BufferingResource(resource = this, resourceLength = resourceLength, bufferSize = size) - -/** - * Maps the result with the given [transform] - * - * If the [transform] throws an [Exception], it is wrapped in a failure with Resource.Exception.Other. - */ -@InternalReadiumApi -public inline fun ResourceTry.mapCatching(transform: (value: S) -> R): ResourceTry = - try { - map(transform) - } catch (e: Exception) { - Try.failure(Resource.Exception.wrap(e)) - } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. - Try.failure(Resource.Exception.wrap(e)) - } - -@InternalReadiumApi -public inline fun ResourceTry.flatMapCatching(transform: (value: S) -> ResourceTry): ResourceTry = - mapCatching(transform).flatMap { it } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt deleted file mode 100644 index 2c97ef9466..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/RoutingFetcher.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.fetcher - -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.resource.Resource - -/** - * Routes requests to child fetchers, depending on a provided predicate. - * - * This can be used for example to serve a publication containing both local and remote resources, - * and more generally to concatenate different content sources. - * - * The [routes] will be tested in the given order. - */ -public class RoutingFetcher(private val routes: List) : Fetcher { - - /** - * Holds a child fetcher and the predicate used to determine if it can answer a request. - * - * The default value for [accepts] means that the fetcher will accept any link. - */ - public class Route( - public val fetcher: Fetcher, - public val accepts: (Link) -> Boolean = { true } - ) - - public constructor(local: Fetcher, remote: Fetcher) : - this(listOf(Route(local, Link::isLocal), Route(remote))) - - override suspend fun links(): List = routes.flatMap { it.fetcher.links() } - - override fun get(link: Link): Fetcher.Resource = - routes.firstOrNull { it.accepts(link) }?.fetcher?.get(link) ?: FailureResource(link, Resource.Exception.NotFound()) - - override suspend fun close() { - routes.forEach { it.fetcher.close() } - } -} - -private val Link.isLocal: Boolean get() = href.startsWith("/") diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt deleted file mode 100644 index b02cd8a89b..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/TransformingFetcher.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.fetcher - -import org.readium.r2.shared.publication.Link - -/** - * Transforms the resources' content of a child fetcher using a list of [ResourceTransformer] - * functions. - */ -public class TransformingFetcher( - private val fetcher: Fetcher, - private val transformers: List -) : Fetcher { - - public constructor(fetcher: Fetcher, transformer: ResourceTransformer) : - this(fetcher, listOf(transformer)) - - override suspend fun links(): List = fetcher.links() - - override fun get(link: Link): Fetcher.Resource { - val resource = fetcher.get(link) - return transformers.fold(resource) { acc, transformer -> transformer(acc) } - } - - override suspend fun close() { - fetcher.close() - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/opds/Acquisition.kt b/readium/shared/src/main/java/org/readium/r2/shared/opds/Acquisition.kt index 91e8ab6ee9..0ced3d2727 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/opds/Acquisition.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/opds/Acquisition.kt @@ -34,7 +34,7 @@ public data class Acquisition( /** Media type of the resource to acquire. */ val mediaType: MediaType get() = - MediaType.parse(type) ?: MediaType.BINARY + MediaType(type) ?: MediaType.BINARY /** * Serializes an [Acquisition] to its JSON representation. @@ -84,10 +84,18 @@ public data class Acquisition( get() = children } -@Deprecated("Renamed into [Acquisition]", ReplaceWith("Acquisition"), level = DeprecationLevel.ERROR) +@Deprecated( + "Renamed into [Acquisition]", + ReplaceWith("Acquisition"), + level = DeprecationLevel.ERROR +) public typealias IndirectAcquisition = Acquisition -@Deprecated("Use [Acquisition::fromJSON] instead", ReplaceWith("Acquisition.fromJSON"), level = DeprecationLevel.ERROR) +@Deprecated( + "Use [Acquisition::fromJSON] instead", + ReplaceWith("Acquisition.fromJSON"), + level = DeprecationLevel.ERROR +) public fun parseIndirectAcquisition(indirectAcquisitionDict: JSONObject): Acquisition = Acquisition.fromJSON(indirectAcquisitionDict) ?: throw Exception("Invalid indirect acquisition") diff --git a/readium/shared/src/main/java/org/readium/r2/shared/parser/xml/XmlParser.kt b/readium/shared/src/main/java/org/readium/r2/shared/parser/xml/XmlParser.kt index c10a8b15da..3c9af81145 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/parser/xml/XmlParser.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/parser/xml/XmlParser.kt @@ -50,8 +50,11 @@ public class XmlParser( text = "" val attributes = buildAttributeMap(parser) val langAttr = - if (isNamespaceAware) attributes[XMLConstants.XML_NS_URI]?.get("lang") - else attributes[""]?.get("xml:lang") + if (isNamespaceAware) { + attributes[XMLConstants.XML_NS_URI]?.get("lang") + } else { + attributes[""]?.get("xml:lang") + } stack.push(Triple(mutableListOf(), attributes, langAttr ?: stack.peek().third)) } XmlPullParser.END_TAG -> { @@ -144,7 +147,9 @@ public data class ElementNode( public fun getAttr(name: String): String? = getAttrNs(name, namespace) ?: getAttrNs(name, "") /** Return the value of an attribute picked in a specific namespace or null if it does not exist */ - public fun getAttrNs(name: String, namespace: String): String? = attributes[namespace]?.get(name) + public fun getAttrNs(name: String, namespace: String): String? = attributes[namespace]?.get( + name + ) /** Return a list of all ElementNode children */ public fun getAll(): List = children.filterIsInstance() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Accessibility.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Accessibility.kt index d3e229b85c..2c4af0ea5f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Accessibility.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Accessibility.kt @@ -64,11 +64,17 @@ public data class Accessibility( public companion object { - public val EPUB_A11Y_10_WCAG_20_A: Profile = Profile("http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-a") + public val EPUB_A11Y_10_WCAG_20_A: Profile = Profile( + "http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-a" + ) - public val EPUB_A11Y_10_WCAG_20_AA: Profile = Profile("http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aa") + public val EPUB_A11Y_10_WCAG_20_AA: Profile = Profile( + "http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aa" + ) - public val EPUB_A11Y_10_WCAG_20_AAA: Profile = Profile("http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aaa") + public val EPUB_A11Y_10_WCAG_20_AAA: Profile = Profile( + "http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aaa" + ) public fun Set.toJSONArray(): JSONArray = JSONArray(this.map(Profile::uri)) @@ -115,7 +121,11 @@ public data class Accessibility( val report = json.optNullableString("report") if (listOfNotNull(certifiedBy, credential, report).isEmpty()) { - warnings?.log(Certification::class.java, "no valid property in certification object", json) + warnings?.log( + Certification::class.java, + "no valid property in certification object", + json + ) return null } @@ -220,12 +230,14 @@ public data class Accessibility( /** * Indicates that auditory perception is necessary to consume the information. */ - @SerialName("auditory") AUDITORY("auditory"), + @SerialName("auditory") + AUDITORY("auditory"), /** * Indicates that tactile perception is necessary to consume the information. */ - @SerialName("tactile") TACTILE("tactile"), + @SerialName("tactile") + TACTILE("tactile"), /** * Indicates that the ability to read textual content is necessary to consume the information. @@ -233,14 +245,19 @@ public data class Accessibility( * Note that reading textual content does not require visual perception, as textual content * can be rendered as audio using a text-to-speech capable device or assistive technology. */ - @SerialName("textual") TEXTUAL("textual"), + @SerialName("textual") + TEXTUAL("textual"), /** * Indicates that visual perception is necessary to consume the information. */ - @SerialName("visual") VISUAL("visual"); + @SerialName("visual") + VISUAL("visual"); - public companion object : MapCompanion(values(), PrimaryAccessMode::value) { + public companion object : MapCompanion( + values(), + PrimaryAccessMode::value + ) { /** * Creates a list of [PrimaryAccessMode] from its RWPM JSON representation. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentLayout.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentLayout.kt index 2c8396f597..ad53826299 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentLayout.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/ContentLayout.kt @@ -28,10 +28,13 @@ import kotlinx.parcelize.Parcelize public enum class ContentLayout(private val cssId: String) : Parcelable { // Right to left RTL("rtl"), + // Left to right LTR("ltr"), + // Asian language, vertically laid out CJK_VERTICAL("cjk-vertical"), + // Asian language, horizontally laid out CJK_HORIZONTAL("cjk-horizontal"); } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt index 2a4a573b98..3346970353 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Contributor.kt @@ -14,9 +14,14 @@ import kotlinx.parcelize.Parcelize import org.json.JSONArray import org.json.JSONObject import org.readium.r2.shared.JSONable -import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.extensions.optNullableDouble +import org.readium.r2.shared.extensions.optNullableString +import org.readium.r2.shared.extensions.optStringsFromArrayOrSingle +import org.readium.r2.shared.extensions.parseObjects +import org.readium.r2.shared.extensions.putIfNotEmpty import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.logging.log +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Contributor Object for the Readium Web Publication Manifest. @@ -81,6 +86,7 @@ public data class Contributor( */ public fun fromJSON( json: Any?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): Contributor? { @@ -103,7 +109,12 @@ public data class Contributor( localizedSortAs = LocalizedString.fromJSON(jsonObject.remove("sortAs"), warnings), roles = jsonObject.optStringsFromArrayOrSingle("role").toSet(), position = jsonObject.optNullableDouble("position"), - links = Link.fromJSONArray(jsonObject.optJSONArray("links"), normalizeHref) + links = Link.fromJSONArray( + jsonObject.optJSONArray("links"), + mediaTypeRetriever, + normalizeHref, + warnings + ) ) } @@ -116,22 +127,34 @@ public data class Contributor( */ public fun fromJSONArray( json: Any?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): List { return when (json) { is String, is JSONObject -> - listOf(json).mapNotNull { fromJSON(it, normalizeHref, warnings) } + listOf(json).mapNotNull { + fromJSON( + it, + mediaTypeRetriever, + normalizeHref, + warnings + ) + } is JSONArray -> - json.parseObjects { fromJSON(it, normalizeHref, warnings) } + json.parseObjects { fromJSON(it, mediaTypeRetriever, normalizeHref, warnings) } else -> emptyList() } } } - @Deprecated("Use [localizedName] instead.", ReplaceWith("localizedName"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [localizedName] instead.", + ReplaceWith("localizedName"), + level = DeprecationLevel.ERROR + ) val multilanguageName: LocalizedString get() = localizedName } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt index 7a17563351..595e0985d5 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Link.kt @@ -15,12 +15,18 @@ import kotlinx.parcelize.Parcelize import org.json.JSONArray import org.json.JSONObject import org.readium.r2.shared.JSONable -import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.extensions.optNullableString +import org.readium.r2.shared.extensions.optPositiveDouble +import org.readium.r2.shared.extensions.optPositiveInt +import org.readium.r2.shared.extensions.optStringsFromArrayOrSingle +import org.readium.r2.shared.extensions.parseObjects +import org.readium.r2.shared.extensions.putIfNotEmpty import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.URITemplate import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.logging.log import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Function used to recursively transform the href of a [Link] when parsing its JSON @@ -39,7 +45,7 @@ public val LinkHrefNormalizerIdentity: LinkHrefNormalizer = { it } * https://readium.org/webpub-manifest/schema/link.schema.json * * @param href URI or URI template of the linked resource. - * @param type MIME type of the linked resource. + * @param mediaType Media type of the linked resource. * @param templated Indicates that a URI template is used in href. * @param title Title of the linked resource. * @param rels Relation between the linked resource and its containing collection. @@ -56,7 +62,7 @@ public val LinkHrefNormalizerIdentity: LinkHrefNormalizer = { it } @Parcelize public data class Link( val href: String, - val type: String? = null, + val mediaType: MediaType? = null, val templated: Boolean = false, val title: String? = null, val rels: Set = setOf(), @@ -70,19 +76,16 @@ public data class Link( val children: List = listOf() ) : JSONable, Parcelable { - /** Media type of the linked resource. */ - val mediaType: MediaType get() = - type?.let { MediaType.parse(it) } ?: MediaType.BINARY - /** * List of URI template parameter keys, if the [Link] is templated. */ @IgnoredOnParcel val templateParameters: List by lazy { - if (!templated) + if (!templated) { emptyList() - else + } else { URITemplate(href).parameters + } } /** @@ -112,7 +115,7 @@ public data class Link( */ override fun toJSON(): JSONObject = JSONObject().apply { put("href", href) - put("type", type) + put("type", mediaType?.toString()) put("templated", templated) put("title", title) putIfNotEmpty("rel", rels) @@ -142,6 +145,7 @@ public data class Link( */ public fun fromJSON( json: JSONObject?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): Link? { @@ -153,7 +157,8 @@ public data class Link( return Link( href = normalizeHref(href), - type = json.optNullableString("type"), + mediaType = json.optNullableString("type") + ?.let { mediaTypeRetriever.retrieve(it) }, templated = json.optBoolean("templated", false), title = json.optNullableString("title"), rels = json.optStringsFromArrayOrSingle("rel").toSet(), @@ -163,8 +168,16 @@ public data class Link( bitrate = json.optPositiveDouble("bitrate"), duration = json.optPositiveDouble("duration"), languages = json.optStringsFromArrayOrSingle("language"), - alternates = fromJSONArray(json.optJSONArray("alternate"), normalizeHref), - children = fromJSONArray(json.optJSONArray("children"), normalizeHref) + alternates = fromJSONArray( + json.optJSONArray("alternate"), + mediaTypeRetriever, + normalizeHref + ), + children = fromJSONArray( + json.optJSONArray("children"), + mediaTypeRetriever, + normalizeHref + ) ) } @@ -176,16 +189,30 @@ public data class Link( */ public fun fromJSONArray( json: JSONArray?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): List { - return json.parseObjects { fromJSON(it as? JSONObject, normalizeHref, warnings) } + return json.parseObjects { + fromJSON( + it as? JSONObject, + mediaTypeRetriever, + normalizeHref, + warnings + ) + } } } + @Deprecated( + "Use [mediaType.toString()] instead", + ReplaceWith("mediaType.toString()"), + level = DeprecationLevel.ERROR + ) + val type: String? get() = throw NotImplementedError() + @Deprecated("Use [type] instead", ReplaceWith("type"), level = DeprecationLevel.ERROR) - val typeLink: String? - get() = type + val typeLink: String? get() = throw NotImplementedError() @Deprecated("Use [rels] instead.", ReplaceWith("rels"), level = DeprecationLevel.ERROR) val rel: List @@ -218,49 +245,49 @@ public fun List.filterByRel(rel: String): List = filter { it.rels.co * Finds the first link matching the given media type. */ public fun List.firstWithMediaType(mediaType: MediaType): Link? = firstOrNull { - it.mediaType.matches(mediaType) + mediaType.matches(it.mediaType) } /** * Finds all the links matching the given media type. */ public fun List.filterByMediaType(mediaType: MediaType): List = filter { - it.mediaType.matches(mediaType) + mediaType.matches(it.mediaType) } /** * Finds all the links matching any of the given media types. */ public fun List.filterByMediaTypes(mediaTypes: List): List = filter { - mediaTypes.any { mediaType -> mediaType.matches(it.type) } + mediaTypes.any { mediaType -> mediaType.matches(it.mediaType) } } /** * Returns whether all the resources in the collection are bitmaps. */ public val List.allAreBitmap: Boolean get() = isNotEmpty() && all { - it.mediaType.isBitmap + it.mediaType?.isBitmap ?: false } /** * Returns whether all the resources in the collection are audio clips. */ public val List.allAreAudio: Boolean get() = isNotEmpty() && all { - it.mediaType.isAudio + it.mediaType?.isAudio ?: false } /** * Returns whether all the resources in the collection are video clips. */ public val List.allAreVideo: Boolean get() = isNotEmpty() && all { - it.mediaType.isVideo + it.mediaType?.isVideo ?: false } /** * Returns whether all the resources in the collection are HTML documents. */ public val List.allAreHtml: Boolean get() = isNotEmpty() && all { - it.mediaType.isHtml + it.mediaType?.isHtml ?: false } /** @@ -276,3 +303,16 @@ public fun List.allMatchMediaType(mediaType: MediaType): Boolean = isNotEm public fun List.allMatchMediaTypes(mediaTypes: List): Boolean = isNotEmpty() && all { mediaTypes.any { mediaType -> mediaType.matches(it.mediaType) } } + +/** + * Returns a list of `Link` after flattening the `children` and `alternates` links of the receiver. + */ +public fun List.flatten(): List { + fun Link.flatten(): List { + val children = children.flatten() + val alternates = alternates.flatten() + return listOf(this) + children.flatten() + alternates.flatten() + } + + return flatMap { it.flatten() } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt index f44c5df215..bee448bab2 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/LocalizedString.kt @@ -150,7 +150,11 @@ public data class LocalizedString(val translations: Map = for (key in json.keys()) { val string = json.optNullableString(key) if (string == null) { - warnings?.log(LocalizedString::class.java, "invalid localized string object", json) + warnings?.log( + LocalizedString::class.java, + "invalid localized string object", + json + ) } else { translations[key] = Translation(string = string) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt index 3cd937d72c..442886003d 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt @@ -19,6 +19,7 @@ import org.readium.r2.shared.extensions.* import org.readium.r2.shared.toJSON import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.logging.log +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Represents a precise location in a publication in a format that can be stored and shared. @@ -100,7 +101,11 @@ public data class Locator( } } - @Deprecated("Renamed to [fragments]", ReplaceWith("fragments"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [fragments]", + ReplaceWith("fragments"), + level = DeprecationLevel.ERROR + ) val fragment: String? get() = fragments.firstOrNull() } @@ -207,18 +212,11 @@ public data class Locator( /** * Creates a [Locator] from a reading order [Link]. */ -@Deprecated("This may create an incorrect `Locator` if the link `type` is missing. Use `publication.locatorFromLink()` instead.", level = DeprecationLevel.ERROR) -public fun Link.toLocator(): Locator { - val components = href.split("#", limit = 2) - return Locator( - href = components.firstOrNull() ?: href, - type = type ?: "", - title = title, - locations = Locator.Locations( - fragments = listOfNotNull(components.getOrNull(1)) - ) - ) -} +@Deprecated( + "This may create an incorrect `Locator` if the link `type` is missing. Use `publication.locatorFromLink()` instead.", + level = DeprecationLevel.ERROR +) +public fun Link.toLocator(): Locator = throw NotImplementedError() /** * Represents a sequential list of `Locator` objects. @@ -229,7 +227,7 @@ public fun Link.toLocator(): Locator { public data class LocatorCollection( val metadata: Metadata = Metadata(), val links: List = emptyList(), - val locators: List = emptyList(), + val locators: List = emptyList() ) : JSONable, Parcelable { /** @@ -241,7 +239,7 @@ public data class LocatorCollection( public data class Metadata( val localizedTitle: LocalizedString? = null, val numberOfItems: Int? = null, - val otherMetadata: @WriteWith Map = mapOf(), + val otherMetadata: @WriteWith Map = mapOf() ) : JSONable, Parcelable { /** @@ -279,11 +277,19 @@ public data class LocatorCollection( public companion object { - public fun fromJSON(json: JSONObject?, warnings: WarningLogger? = null): LocatorCollection { + public fun fromJSON( + json: JSONObject?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), + warnings: WarningLogger? = null + ): LocatorCollection { return LocatorCollection( metadata = Metadata.fromJSON(json?.optJSONObject("metadata"), warnings), - links = Link.fromJSONArray(json?.optJSONArray("links"), warnings = warnings), - locators = Locator.fromJSONArray(json?.optJSONArray("locators"), warnings), + links = Link.fromJSONArray( + json?.optJSONArray("links"), + mediaTypeRetriever, + warnings = warnings + ), + locators = Locator.fromJSONArray(json?.optJSONArray("locators"), warnings) ) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt index da33cba655..ace4d4ef3c 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt @@ -21,6 +21,7 @@ import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.logging.log import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Holds the metadata of a Readium publication, as described in the Readium Web Publication Manifest. @@ -68,9 +69,9 @@ public data class Manifest( public fun linkWithHref(href: String): Link? { fun List.deepLinkWithHref(href: String): Link? { for (l in this) { - if (l.href == href) + if (l.href == href) { return l - else { + } else { l.alternates.deepLinkWithHref(href)?.let { return it } l.children.deepLinkWithHref(href)?.let { return it } } @@ -111,7 +112,7 @@ public data class Manifest( val components = link.href.split("#", limit = 2) val href = components.firstOrNull() ?: link.href val resourceLink = linkWithHref(href) ?: return null - val type = resourceLink.type ?: return null + val type = resourceLink.mediaType?.toString() ?: return null val fragment = components.getOrNull(1) return Locator( @@ -155,47 +156,89 @@ public data class Manifest( public fun fromJSON( json: JSONObject?, packaged: Boolean = false, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), warnings: WarningLogger? = null ): Manifest? { json ?: return null val baseUrl = - if (packaged) + if (packaged) { "/" - else - Link.fromJSONArray(json.optJSONArray("links"), warnings = warnings) + } else { + Link.fromJSONArray( + json.optJSONArray("links"), + mediaTypeRetriever, + warnings = warnings + ) .firstWithRel("self") ?.href ?.toUrlOrNull() ?.removeLastComponent() ?.toString() ?: "/" + } val normalizeHref = { href: String -> Href(href, baseUrl).string } val context = json.optStringsFromArrayOrSingle("@context", remove = true) - val metadata = Metadata.fromJSON(json.remove("metadata") as? JSONObject, normalizeHref, warnings) + val metadata = Metadata.fromJSON( + json.remove("metadata") as? JSONObject, + mediaTypeRetriever, + normalizeHref, + warnings + ) if (metadata == null) { warnings?.log(Manifest::class.java, "[metadata] is required", json) return null } - val links = Link.fromJSONArray(json.remove("links") as? JSONArray, normalizeHref, warnings) - .map { if (!packaged || "self" !in it.rels) it else it.copy(rels = it.rels - "self" + "alternate") } + val links = Link.fromJSONArray( + json.remove("links") as? JSONArray, + mediaTypeRetriever, + normalizeHref, + warnings + ) + .map { + if (packaged && "self" in it.rels) { + it.copy(rels = it.rels - "self" + "alternate") + } else { + it + } + } // [readingOrder] used to be [spine], so we parse [spine] as a fallback. val readingOrderJSON = (json.remove("readingOrder") ?: json.remove("spine")) as? JSONArray - val readingOrder = Link.fromJSONArray(readingOrderJSON, normalizeHref, warnings) - .filter { it.type != null } + val readingOrder = Link.fromJSONArray( + readingOrderJSON, + mediaTypeRetriever, + normalizeHref, + warnings + ) + .filter { it.mediaType != null } - val resources = Link.fromJSONArray(json.remove("resources") as? JSONArray, normalizeHref, warnings) - .filter { it.type != null } + val resources = Link.fromJSONArray( + json.remove("resources") as? JSONArray, + mediaTypeRetriever, + normalizeHref, + warnings + ) + .filter { it.mediaType != null } - val tableOfContents = Link.fromJSONArray(json.remove("toc") as? JSONArray, normalizeHref, warnings) + val tableOfContents = Link.fromJSONArray( + json.remove("toc") as? JSONArray, + mediaTypeRetriever, + normalizeHref, + warnings + ) // Parses subcollections from the remaining JSON properties. - val subcollections = PublicationCollection.collectionsFromJSON(json, normalizeHref, warnings) + val subcollections = PublicationCollection.collectionsFromJSON( + json, + mediaTypeRetriever, + normalizeHref, + warnings + ) return Manifest( context = context, diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt index 731f2bcbdc..d21a2440d3 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Metadata.kt @@ -7,18 +7,27 @@ package org.readium.r2.shared.publication import android.os.Parcelable -import java.util.* +import java.util.Date +import java.util.Locale import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize import kotlinx.parcelize.WriteWith import org.json.JSONObject import org.readium.r2.shared.JSONable -import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.extensions.JSONParceler +import org.readium.r2.shared.extensions.iso8601ToDate +import org.readium.r2.shared.extensions.optPositiveDouble +import org.readium.r2.shared.extensions.optPositiveInt +import org.readium.r2.shared.extensions.optStringsFromArrayOrSingle +import org.readium.r2.shared.extensions.putIfNotEmpty +import org.readium.r2.shared.extensions.toIso8601String +import org.readium.r2.shared.extensions.toMap import org.readium.r2.shared.publication.presentation.Presentation import org.readium.r2.shared.publication.presentation.presentation import org.readium.r2.shared.util.Language import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.logging.log +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * https://readium.org/webpub-manifest/schema/metadata.schema.json @@ -33,7 +42,7 @@ public data class Metadata( val identifier: String? = null, // URI val type: String? = null, // URI (@type) val conformsTo: Set = emptySet(), - val localizedTitle: LocalizedString, + val localizedTitle: LocalizedString? = null, val localizedSubtitle: LocalizedString? = null, val localizedSortAs: LocalizedString? = null, val modified: Date? = null, @@ -66,7 +75,7 @@ public data class Metadata( identifier: String? = null, // URI type: String? = null, // URI (@type) conformsTo: Set = emptySet(), - localizedTitle: LocalizedString, + localizedTitle: LocalizedString? = null, localizedSubtitle: LocalizedString? = null, localizedSortAs: LocalizedString? = null, modified: Date? = null, @@ -141,7 +150,7 @@ public data class Metadata( /** * Returns the default translation string for the [localizedTitle]. */ - val title: String get() = localizedTitle.string + val title: String? get() = localizedTitle?.string /** * Returns the default translation string for the [localizedSortAs]. @@ -168,7 +177,10 @@ public data class Metadata( * * See this issue for more details: https://github.com/readium/architecture/issues/113 */ - @Deprecated("You should resolve [ReadingProgression.AUTO] by yourself.", level = DeprecationLevel.WARNING) + @Deprecated( + "You should resolve [ReadingProgression.AUTO] by yourself.", + level = DeprecationLevel.WARNING + ) @IgnoredOnParcel val effectiveReadingProgression: ReadingProgression get() { if (readingProgression != null) { @@ -244,6 +256,7 @@ public data class Metadata( */ public fun fromJSON( json: JSONObject?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): Metadata? { @@ -265,21 +278,93 @@ public data class Metadata( val accessibility = Accessibility.fromJSON(json.remove("accessibility")) val languages = json.optStringsFromArrayOrSingle("language", remove = true) val localizedSortAs = LocalizedString.fromJSON(json.remove("sortAs"), warnings) - val subjects = Subject.fromJSONArray(json.remove("subject"), normalizeHref, warnings) - val authors = Contributor.fromJSONArray(json.remove("author"), normalizeHref, warnings) - val translators = Contributor.fromJSONArray(json.remove("translator"), normalizeHref, warnings) - val editors = Contributor.fromJSONArray(json.remove("editor"), normalizeHref, warnings) - val artists = Contributor.fromJSONArray(json.remove("artist"), normalizeHref, warnings) - val illustrators = Contributor.fromJSONArray(json.remove("illustrator"), normalizeHref, warnings) - val letterers = Contributor.fromJSONArray(json.remove("letterer"), normalizeHref, warnings) - val pencilers = Contributor.fromJSONArray(json.remove("penciler"), normalizeHref, warnings) - val colorists = Contributor.fromJSONArray(json.remove("colorist"), normalizeHref, warnings) - val inkers = Contributor.fromJSONArray(json.remove("inker"), normalizeHref, warnings) - val narrators = Contributor.fromJSONArray(json.remove("narrator"), normalizeHref, warnings) - val contributors = Contributor.fromJSONArray(json.remove("contributor"), normalizeHref, warnings) - val publishers = Contributor.fromJSONArray(json.remove("publisher"), normalizeHref, warnings) - val imprints = Contributor.fromJSONArray(json.remove("imprint"), normalizeHref, warnings) - val readingProgression = ReadingProgression(json.remove("readingProgression") as? String) + val subjects = Subject.fromJSONArray( + json.remove("subject"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val authors = Contributor.fromJSONArray( + json.remove("author"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val translators = Contributor.fromJSONArray( + json.remove("translator"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val editors = Contributor.fromJSONArray( + json.remove("editor"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val artists = Contributor.fromJSONArray( + json.remove("artist"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val illustrators = Contributor.fromJSONArray( + json.remove("illustrator"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val letterers = Contributor.fromJSONArray( + json.remove("letterer"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val pencilers = Contributor.fromJSONArray( + json.remove("penciler"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val colorists = Contributor.fromJSONArray( + json.remove("colorist"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val inkers = Contributor.fromJSONArray( + json.remove("inker"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val narrators = Contributor.fromJSONArray( + json.remove("narrator"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val contributors = Contributor.fromJSONArray( + json.remove("contributor"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val publishers = Contributor.fromJSONArray( + json.remove("publisher"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val imprints = Contributor.fromJSONArray( + json.remove("imprint"), + mediaTypeRetriever, + normalizeHref, + warnings + ) + val readingProgression = ReadingProgression( + json.remove("readingProgression") as? String + ) val description = json.remove("description") as? String val duration = json.optPositiveDouble("duration", remove = true) val numberOfPages = json.optPositiveInt("numberOfPages", remove = true) @@ -294,7 +379,12 @@ public data class Metadata( for (key in belongsToJson.keys()) { if (!belongsToJson.isNull(key)) { val value = belongsToJson.get(key) - belongsTo[key] = Collection.fromJSONArray(value, normalizeHref, warnings) + belongsTo[key] = Collection.fromJSONArray( + value, + mediaTypeRetriever, + normalizeHref, + warnings + ) } } @@ -336,29 +426,53 @@ public data class Metadata( @Deprecated("Use [type] instead", ReplaceWith("type"), level = DeprecationLevel.ERROR) val rdfType: String? get() = type - @Deprecated("Use [localizeTitle] instead.", ReplaceWith("localizedTitle"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [localizeTitle] instead.", + ReplaceWith("localizedTitle"), + level = DeprecationLevel.ERROR + ) val multilanguageTitle: LocalizedString? get() = localizedTitle - @Deprecated("Use [localizedTitle.get] instead", ReplaceWith("localizedTitle.translationForLanguage(key)?.string"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [localizedTitle.get] instead", + ReplaceWith("localizedTitle.translationForLanguage(key)?.string"), + level = DeprecationLevel.ERROR + ) public fun titleForLang(key: String): String? = - localizedTitle.getOrFallback(key)?.string + localizedTitle?.getOrFallback(key)?.string - @Deprecated("Use [readingProgression] instead.", ReplaceWith("readingProgression"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [readingProgression] instead.", + ReplaceWith("readingProgression"), + level = DeprecationLevel.ERROR + ) val direction: String get() { throw NotImplementedError() } - @Deprecated("Use [published] instead", ReplaceWith("published?.toIso8601String()"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [published] instead", + ReplaceWith("published?.toIso8601String()"), + level = DeprecationLevel.ERROR + ) val publicationDate: String? get() = published?.toIso8601String() - @Deprecated("Use [presentation] instead", ReplaceWith("presentation", "org.readium.r2.shared.publication.presentation.presentation"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [presentation] instead", + ReplaceWith("presentation", "org.readium.r2.shared.publication.presentation.presentation"), + level = DeprecationLevel.ERROR + ) val rendition: Presentation get() = presentation - @Deprecated("Access from [otherMetadata] instead", ReplaceWith("otherMetadata[\"source\"] as? String"), level = DeprecationLevel.ERROR) + @Deprecated( + "Access from [otherMetadata] instead", + ReplaceWith("otherMetadata[\"source\"] as? String"), + level = DeprecationLevel.ERROR + ) val source: String? get() = otherMetadata["source"] as? String diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Properties.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Properties.kt index 742dd5782d..2343622dd5 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Properties.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Properties.kt @@ -16,6 +16,7 @@ import org.json.JSONObject import org.readium.r2.shared.JSONable import org.readium.r2.shared.extensions.JSONParceler import org.readium.r2.shared.extensions.toMap +import org.readium.r2.shared.resource.Resource /** * Properties associated to the linked resource. @@ -42,12 +43,21 @@ public data class Properties( return copy(otherProperties = otherProperties) } + /** + * Makes a copy of this [Properties] after merging in the given additional other [properties]. + */ + public fun add(properties: Properties): Properties = + add(properties.otherProperties) + /** * Syntactic sugar to access the [otherProperties] values by subscripting [Properties] directly. * `properties["price"] == properties.otherProperties["price"]` */ public operator fun get(key: String): Any? = otherProperties[key] + internal fun toResourceProperties(): Resource.Properties = + Resource.Properties(otherProperties) + public companion object { /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt index f128e251b6..eba3934190 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt @@ -21,8 +21,6 @@ import org.readium.r2.shared.error.MessageError import org.readium.r2.shared.error.ThrowableError import org.readium.r2.shared.extensions.* import org.readium.r2.shared.extensions.removeLastComponent -import org.readium.r2.shared.fetcher.EmptyFetcher -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.epub.listOfAudioClips import org.readium.r2.shared.publication.epub.listOfVideoClips import org.readium.r2.shared.publication.services.CacheService @@ -34,8 +32,13 @@ import org.readium.r2.shared.publication.services.PositionsService import org.readium.r2.shared.publication.services.WebPositionsService import org.readium.r2.shared.publication.services.content.ContentService import org.readium.r2.shared.publication.services.search.SearchService +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.EmptyContainer +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.fallback import org.readium.r2.shared.util.Closeable -import org.readium.r2.shared.util.SuspendingCloseable +import org.readium.r2.shared.util.mediatype.MediaType internal typealias ServiceFactory = (Publication.Service.Context) -> Publication.Service? @@ -54,19 +57,25 @@ public typealias PublicationId = String * related to a Readium publication. * * @param manifest The manifest holding the publication metadata extracted from the publication file. - * @param fetcher The underlying fetcher used to read publication resources. + * @param container The underlying container used to read publication resources. * The default implementation returns Resource.Exception.NotFound for all HREFs. * @param servicesBuilder Holds the list of service factories used to create the instances of * Publication.Service attached to this Publication. */ public class Publication( manifest: Manifest, - private val fetcher: Fetcher = EmptyFetcher(), + private val container: Container = EmptyContainer(), private val servicesBuilder: ServicesBuilder = ServicesBuilder(), - @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) + @Deprecated( + "Migrate to the new Settings API (see migration guide)", + level = DeprecationLevel.ERROR + ) public var userSettingsUIPreset: MutableMap = mutableMapOf(), - @Deprecated("Migrate to the new Settings API (see migration guide)", level = DeprecationLevel.ERROR) - public var cssStyle: String? = null, + @Deprecated( + "Migrate to the new Settings API (see migration guide)", + level = DeprecationLevel.ERROR + ) + public var cssStyle: String? = null ) : PublicationServicesHolder { private val _manifest: Manifest @@ -74,8 +83,10 @@ public class Publication( private val services = ListPublicationServicesHolder() init { - services.services = servicesBuilder.build(Service.Context(manifest, fetcher, services)) - _manifest = manifest.copy(links = manifest.links + services.services.map(Service::links).flatten()) + services.services = servicesBuilder.build(Service.Context(manifest, container, services)) + _manifest = manifest.copy( + links = manifest.links + services.services.map(Service::links).flatten() + ) } // Shortcuts to manifest properties @@ -95,7 +106,10 @@ public class Publication( public val subcollections: Map> get() = _manifest.subcollections - @Deprecated("Use conformsTo() to check the kind of a publication.", level = DeprecationLevel.ERROR) + @Deprecated( + "Use conformsTo() to check the kind of a publication.", + level = DeprecationLevel.ERROR + ) public var type: TYPE = TYPE.EPUB @Deprecated("Version is not available any more.", level = DeprecationLevel.ERROR) @@ -152,18 +166,28 @@ public class Publication( /** * Returns the resource targeted by the given non-templated [link]. */ - public fun get(link: Link): Fetcher.Resource { + public fun get(link: Link): Resource { if (DEBUG) { require(!link.templated) { "You must expand templated links before calling [Publication.get]" } } services.services.forEach { service -> service.get(link)?.let { return it } } - return fetcher.get(link) + + return container.get(link.href) + .fallback { error -> + if (error is Resource.Exception.NotFound) { + // Try again after removing query and fragment. + container.get(link.href.takeWhile { it !in "#?" }) + } else { + null + } + } + .withMediaType(link.mediaType) } /** * Closes any opened resource associated with the [Publication], including services. */ override suspend fun close() { - fetcher.close() + container.close() services.close() } @@ -226,7 +250,10 @@ public class Publication( * in the navigator at the moment without changing the code in reading apps. */ @Suppress("UNUSED_PARAMETER") - @Deprecated("The HTTP server is not needed anymore (see migration guide)", level = DeprecationLevel.ERROR) + @Deprecated( + "The HTTP server is not needed anymore (see migration guide)", + level = DeprecationLevel.ERROR + ) public fun localBaseUrlOf(filename: String, port: Int): String { throw NotImplementedError() } @@ -235,7 +262,10 @@ public class Publication( * Gets the absolute URL of a resource locally served through HTTP. */ @Suppress("UNUSED_PARAMETER") - @Deprecated("The HTTP server is not needed anymore (see migration guide)", level = DeprecationLevel.ERROR) + @Deprecated( + "The HTTP server is not needed anymore (see migration guide)", + level = DeprecationLevel.ERROR + ) public fun localUrlOf(filename: String, port: Int, href: String): String { throw NotImplementedError() } @@ -245,7 +275,8 @@ public class Publication( "Parse a RWPM with [Manifest::fromJSON] and then instantiate a Publication", ReplaceWith( "Manifest.fromJSON(json)", - "org.readium.r2.shared.publication.Publication", "org.readium.r2.shared.publication.Manifest" + "org.readium.r2.shared.publication.Publication", + "org.readium.r2.shared.publication.Manifest" ), level = DeprecationLevel.ERROR ) @@ -268,10 +299,17 @@ public class Publication( public companion object { /** Profile for EPUB publications. */ public val EPUB: Profile = Profile("https://readium.org/webpub-manifest/profiles/epub") + /** Profile for audiobooks. */ - public val AUDIOBOOK: Profile = Profile("https://readium.org/webpub-manifest/profiles/audiobook") + public val AUDIOBOOK: Profile = Profile( + "https://readium.org/webpub-manifest/profiles/audiobook" + ) + /** Profile for visual narratives (comics, manga and bandes dessinées). */ - public val DIVINA: Profile = Profile("https://readium.org/webpub-manifest/profiles/divina") + public val DIVINA: Profile = Profile( + "https://readium.org/webpub-manifest/profiles/divina" + ) + /** Profile for PDF documents. */ public val PDF: Profile = Profile("https://readium.org/webpub-manifest/profiles/pdf") } @@ -287,7 +325,7 @@ public class Publication( */ public class Context( public val manifest: Manifest, - public val fetcher: Fetcher, + public val container: Container, public val services: PublicationServicesHolder ) @@ -319,13 +357,13 @@ public class Publication( * Called by [Publication.get] for each request. * * Warning: If you need to request one of the publication resources to answer the request, - * use the [Fetcher] provided by the [Publication.Service.Context] instead of + * use the [Container] provided by the [Publication.Service.Context] instead of * [Publication.get], otherwise it will trigger an infinite loop. * - * @return The [Fetcher.Resource] containing the response, or null if the service doesn't + * @return The [Resource] containing the response, or null if the service doesn't * recognize this request. */ - public fun get(link: Link): Fetcher.Resource? = null + public fun get(link: Link): Resource? = null /** * Closes any opened file handles, removes temporary files, etc. @@ -351,7 +389,7 @@ public class Publication( cover: ServiceFactory? = null, locator: ServiceFactory? = null, positions: ServiceFactory? = null, - search: ServiceFactory? = null, + search: ServiceFactory? = null ) : this( mapOf( CacheService::class.java.simpleName to cache, @@ -360,7 +398,7 @@ public class Publication( CoverService::class.java.simpleName to cover, LocatorService::class.java.simpleName to locator, PositionsService::class.java.simpleName to positions, - SearchService::class.java.simpleName to search, + SearchService::class.java.simpleName to search ).filterValues { it != null }.toMutableMap() as MutableMap ) @@ -508,13 +546,13 @@ public class Publication( */ public class Builder( public var manifest: Manifest, - public var fetcher: Fetcher, + public var container: Container, public var servicesBuilder: ServicesBuilder = ServicesBuilder() ) { public fun build(): Publication = Publication( manifest = manifest, - fetcher = fetcher, + container = container, servicesBuilder = servicesBuilder ) } @@ -522,7 +560,11 @@ public class Publication( /** * Finds the first [Link] to the publication's cover (rel = cover). */ - @Deprecated("Use [Publication.cover] to get the cover as a [Bitmap]", ReplaceWith("cover"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [Publication.cover] to get the cover as a [Bitmap]", + ReplaceWith("cover"), + level = DeprecationLevel.ERROR + ) public val coverLink: Link? get() = linkWithRel("cover") /** @@ -530,82 +572,109 @@ public class Publication( * The provided closure will be used to build the [PositionListFactory], with this being the * [Publication]. */ - @Deprecated("Use [Publication.copy(serviceFactories)] instead", ReplaceWith("Publication.copy(serviceFactories = listOf(positionsServiceFactory)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [Publication.copy(serviceFactories)] instead", + ReplaceWith("Publication.copy(serviceFactories = listOf(positionsServiceFactory)"), + level = DeprecationLevel.ERROR + ) public fun copyWithPositionsFactory(): Publication { throw NotImplementedError() } - @Deprecated("Renamed to [listOfAudioClips]", ReplaceWith("listOfAudioClips"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [listOfAudioClips]", + ReplaceWith("listOfAudioClips"), + level = DeprecationLevel.ERROR + ) public val listOfAudioFiles: List = listOfAudioClips - @Deprecated("Renamed to [listOfVideoClips]", ReplaceWith("listOfVideoClips"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [listOfVideoClips]", + ReplaceWith("listOfVideoClips"), + level = DeprecationLevel.ERROR + ) public val listOfVideos: List = listOfVideoClips - @Deprecated("Renamed to [linkWithHref]", ReplaceWith("linkWithHref(href)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [linkWithHref]", + ReplaceWith("linkWithHref(href)"), + level = DeprecationLevel.ERROR + ) public fun resource(href: String): Link? = linkWithHref(href) @Deprecated("Refactored as a property", ReplaceWith("baseUrl"), level = DeprecationLevel.ERROR) public fun baseUrl(): URL? = baseUrl - @Deprecated("Renamed [subcollections]", ReplaceWith("subcollections"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed [subcollections]", + ReplaceWith("subcollections"), + level = DeprecationLevel.ERROR + ) public val otherCollections: Map> get() = subcollections - @Deprecated("Use [setSelfLink] instead", ReplaceWith("setSelfLink"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [setSelfLink] instead", + ReplaceWith("setSelfLink"), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun addSelfLink(endPoint: String, baseURL: URL) { throw NotImplementedError() } - @Deprecated("Use [linkWithHref] instead.", ReplaceWith("linkWithHref(href)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [linkWithHref] instead.", + ReplaceWith("linkWithHref(href)"), + level = DeprecationLevel.ERROR + ) public fun resourceWithHref(href: String): Link? = linkWithHref(href) - @Deprecated("Use a [ServiceFactory] for a [PositionsService] instead.", level = DeprecationLevel.ERROR) + @Deprecated( + "Use a [ServiceFactory] for a [PositionsService] instead.", + level = DeprecationLevel.ERROR + ) public interface PositionListFactory { public fun create(): List } - @Deprecated("Use [linkWithHref()] to find a link with the given HREF", replaceWith = ReplaceWith("linkWithHref"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [linkWithHref()] to find a link with the given HREF", + replaceWith = ReplaceWith("linkWithHref"), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun link(predicate: (Link) -> Boolean): Link? = null - @Deprecated("Use [jsonManifest] instead", ReplaceWith("jsonManifest"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [jsonManifest] instead", + ReplaceWith("jsonManifest"), + level = DeprecationLevel.ERROR + ) public fun toJSON(): JSONObject = JSONObject(jsonManifest) - @Deprecated("Use `metadata.effectiveReadingProgression` instead", ReplaceWith("metadata.effectiveReadingProgression"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `metadata.effectiveReadingProgression` instead", + ReplaceWith("metadata.effectiveReadingProgression"), + level = DeprecationLevel.ERROR + ) public val contentLayout: ReadingProgression get() = metadata.effectiveReadingProgression - @Deprecated("Use `metadata.effectiveReadingProgression` instead", ReplaceWith("metadata.effectiveReadingProgression"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `metadata.effectiveReadingProgression` instead", + ReplaceWith("metadata.effectiveReadingProgression"), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun contentLayoutForLanguage(language: String?): ReadingProgression = metadata.effectiveReadingProgression } -/** - * Holds [Publication.Service] instances for a [Publication]. - */ -public interface PublicationServicesHolder : SuspendingCloseable { - /** - * Returns the first publication service that is an instance of [serviceType]. - */ - public fun findService(serviceType: KClass): T? - - /** - * Returns all the publication services that are instances of [serviceType]. - */ - public fun findServices(serviceType: KClass): List -} - -internal class ListPublicationServicesHolder( - var services: List = emptyList() -) : PublicationServicesHolder { - override fun findService(serviceType: KClass): T? = - findServices(serviceType).firstOrNull() - - override fun findServices(serviceType: KClass): List = - services.filterIsInstance(serviceType.java) +private fun Resource.withMediaType(mediaType: MediaType?): Resource { + if (mediaType == null) { + return this + } - override suspend fun close() { - for (service in services) { - tryOrLog { service.close() } - } + return object : Resource by this { + override suspend fun mediaType(): ResourceTry = + ResourceTry.success(mediaType) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt index aa64532608..734e123e15 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationCollection.kt @@ -21,6 +21,7 @@ import org.readium.r2.shared.extensions.putIfNotEmpty import org.readium.r2.shared.extensions.toMap import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.logging.log +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Core Collection Model @@ -55,6 +56,7 @@ public data class PublicationCollection( */ public fun fromJSON( json: Any?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): PublicationCollection? { @@ -67,14 +69,24 @@ public data class PublicationCollection( when (json) { // Parses a sub-collection object. is JSONObject -> { - links = Link.fromJSONArray(json.remove("links") as? JSONArray, normalizeHref, warnings) + links = Link.fromJSONArray( + json.remove("links") as? JSONArray, + mediaTypeRetriever, + normalizeHref, + warnings + ) metadata = (json.remove("metadata") as? JSONObject)?.toMap() - subcollections = collectionsFromJSON(json, normalizeHref, warnings) + subcollections = collectionsFromJSON( + json, + mediaTypeRetriever, + normalizeHref, + warnings + ) } // Parses an array of links. is JSONArray -> { - links = Link.fromJSONArray(json, normalizeHref, warnings) + links = Link.fromJSONArray(json, mediaTypeRetriever, normalizeHref, warnings) } else -> { @@ -84,7 +96,10 @@ public data class PublicationCollection( } if (links.isEmpty()) { - warnings?.log(PublicationCollection::class.java, "core collection's [links] must not be empty") + warnings?.log( + PublicationCollection::class.java, + "core collection's [links] must not be empty" + ) return null } @@ -104,6 +119,7 @@ public data class PublicationCollection( */ public fun collectionsFromJSON( json: JSONObject, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): Map> { @@ -112,14 +128,21 @@ public data class PublicationCollection( val subJSON = json.get(role) // Parses a list of links or a single collection object. - val collection = fromJSON(subJSON, normalizeHref, warnings) + val collection = fromJSON(subJSON, mediaTypeRetriever, normalizeHref, warnings) if (collection != null) { collections.getOrPut(role) { mutableListOf() }.add(collection) // Parses a list of collection objects. } else if (subJSON is JSONArray) { collections.getOrPut(role) { mutableListOf() }.addAll( - subJSON.mapNotNull { fromJSON(it, normalizeHref, warnings) } + subJSON.mapNotNull { + fromJSON( + it, + mediaTypeRetriever, + normalizeHref, + warnings + ) + } ) } } @@ -149,10 +172,18 @@ internal fun Map>.appendToJSONObject(jsonObj } } -@Deprecated("Use [subcollections[role].firstOrNull()] instead", ReplaceWith("subcollections[role].firstOrNull()"), level = DeprecationLevel.ERROR) +@Deprecated( + "Use [subcollections[role].firstOrNull()] instead", + ReplaceWith("subcollections[role].firstOrNull()"), + level = DeprecationLevel.ERROR +) public fun Map>.firstWithRole(role: String): PublicationCollection? = get(role)?.firstOrNull() -@Deprecated("Use [subcollections[role]] instead", ReplaceWith("subcollections[role]"), level = DeprecationLevel.ERROR) +@Deprecated( + "Use [subcollections[role]] instead", + ReplaceWith("subcollections[role]"), + level = DeprecationLevel.ERROR +) public fun Map>.findAllWithRole(role: String): List = get(role) ?: emptyList() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationServicesHolder.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationServicesHolder.kt new file mode 100644 index 0000000000..b412694df5 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/PublicationServicesHolder.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.publication + +import kotlin.reflect.KClass +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.SuspendingCloseable + +/** + * Holds [Publication.Service] instances for a [Publication]. + */ +public interface PublicationServicesHolder : SuspendingCloseable { + /** + * Returns the first publication service that is an instance of [serviceType]. + */ + public fun findService(serviceType: KClass): T? + + /** + * Returns all the publication services that are instances of [serviceType]. + */ + public fun findServices(serviceType: KClass): List +} + +internal class ListPublicationServicesHolder( + var services: List = emptyList() +) : PublicationServicesHolder { + override fun findService(serviceType: KClass): T? = + findServices(serviceType).firstOrNull() + + override fun findServices(serviceType: KClass): List = + services.filterIsInstance(serviceType.java) + + override suspend fun close() { + for (service in services) { + tryOrLog { service.close() } + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt index 932b8d4119..4faf049042 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/ReadingProgression.kt @@ -20,11 +20,17 @@ import org.readium.r2.shared.util.MapCompanion @Parcelize public enum class ReadingProgression(public val value: String) : Parcelable { /** Right to left */ - @SerialName("rtl") RTL("rtl"), + @SerialName("rtl") + RTL("rtl"), + /** Left to right */ - @SerialName("ltr") LTR("ltr"); + @SerialName("ltr") + LTR("ltr"); - public companion object : MapCompanion(values(), ReadingProgression::value) { + public companion object : MapCompanion( + values(), + ReadingProgression::value + ) { override fun get(key: String?): ReadingProgression? = // For backward compatibility, we allow uppercase keys. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Subject.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Subject.kt index 83bcd27392..c3727ed8bd 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Subject.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Subject.kt @@ -19,6 +19,7 @@ import org.readium.r2.shared.extensions.parseObjects import org.readium.r2.shared.extensions.putIfNotEmpty import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.logging.log +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * https://github.com/readium/webpub-manifest/tree/master/contexts/default#subjects @@ -77,6 +78,7 @@ public data class Subject( */ public fun fromJSON( json: Any?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): Subject? { @@ -98,7 +100,12 @@ public data class Subject( localizedSortAs = LocalizedString.fromJSON(jsonObject.remove("sortAs"), warnings), scheme = jsonObject.optNullableString("scheme"), code = jsonObject.optNullableString("code"), - links = Link.fromJSONArray(jsonObject.optJSONArray("links"), normalizeHref, warnings) + links = Link.fromJSONArray( + jsonObject.optJSONArray("links"), + mediaTypeRetriever, + normalizeHref, + warnings + ) ) } @@ -111,15 +118,23 @@ public data class Subject( */ public fun fromJSONArray( json: Any?, + mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), normalizeHref: LinkHrefNormalizer = LinkHrefNormalizerIdentity, warnings: WarningLogger? = null ): List { return when (json) { is String, is JSONObject -> - listOf(json).mapNotNull { fromJSON(it, normalizeHref, warnings) } + listOf(json).mapNotNull { + fromJSON( + it, + mediaTypeRetriever, + normalizeHref, + warnings + ) + } is JSONArray -> - json.parseObjects { fromJSON(it, normalizeHref, warnings) } + json.parseObjects { fromJSON(it, mediaTypeRetriever, normalizeHref, warnings) } else -> emptyList() } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/archive/Properties.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/archive/Properties.kt index 75d5466b5f..66c6f08c3d 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/archive/Properties.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/archive/Properties.kt @@ -6,56 +6,13 @@ package org.readium.r2.shared.publication.archive -import android.os.Parcelable -import kotlinx.parcelize.Parcelize -import org.json.JSONObject -import org.readium.r2.shared.JSONable -import org.readium.r2.shared.extensions.optNullableBoolean -import org.readium.r2.shared.extensions.optNullableLong import org.readium.r2.shared.publication.Properties -import org.readium.r2.shared.util.logging.WarningLogger -import org.readium.r2.shared.util.logging.log -// Archive Link Properties Extension - -/** - * Holds information about how the resource is stored in the publication archive. - * - * @param entryLength The length of the entry stored in the archive. It might be a compressed length - * if the entry is deflated. - * @param isEntryCompressed Indicates whether the entry was compressed before being stored in the - * archive. - */ -@Parcelize public data class ArchiveProperties( val entryLength: Long, val isEntryCompressed: Boolean -) : JSONable, Parcelable { - - override fun toJSON(): JSONObject = JSONObject().apply { - put("entryLength", entryLength) - put("isEntryCompressed", isEntryCompressed) - } - - public companion object { - public fun fromJSON(json: JSONObject?, warnings: WarningLogger? = null): ArchiveProperties? { - json ?: return null +) - val entryLength = json.optNullableLong("entryLength") - val isEntryCompressed = json.optNullableBoolean("isEntryCompressed") - if (entryLength == null || isEntryCompressed == null) { - warnings?.log(ArchiveProperties::class.java, "[entryLength] and [isEntryCompressed] are required", json) - return null - } - - return ArchiveProperties(entryLength = entryLength, isEntryCompressed = isEntryCompressed) - } - } -} - -/** - * Provides information about how the resource is stored in the publication archive. - */ +@Deprecated("Not used anymore", level = DeprecationLevel.ERROR) public val Properties.archive: ArchiveProperties? - get() = (this["archive"] as? Map<*, *>) - ?.let { ArchiveProperties.fromJSON(JSONObject(it)) } + get() = throw NotImplementedError() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/epub/EpubLayout.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/epub/EpubLayout.kt index bd77d50ea3..55ecaa11ae 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/epub/EpubLayout.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/epub/EpubLayout.kt @@ -24,9 +24,18 @@ public enum class EpubLayout(public val value: String) : Parcelable { public companion object : MapCompanion(values(), EpubLayout::value) { - @Deprecated("Renamed to [FIXED]", ReplaceWith("EpubLayout.FIXED"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [FIXED]", + ReplaceWith("EpubLayout.FIXED"), + level = DeprecationLevel.ERROR + ) public val Fixed: EpubLayout get() = FIXED - @Deprecated("Renamed to [REFLOWABLE]", ReplaceWith("EpubLayout.REFLOWABLE"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [REFLOWABLE]", + ReplaceWith("EpubLayout.REFLOWABLE"), + level = DeprecationLevel.ERROR + ) public val Reflowable: EpubLayout get() = REFLOWABLE } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt index 80290f2fee..889b001272 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/html/DomRange.kt @@ -79,7 +79,11 @@ public data class DomRange( val cssSelector = json?.optNullableString("cssSelector") val textNodeIndex = json?.optPositiveInt("textNodeIndex") if (cssSelector == null || textNodeIndex == null) { - warnings?.log(Point::class.java, "[cssSelector] and [textNodeIndex] are required", json) + warnings?.log( + Point::class.java, + "[cssSelector] and [textNodeIndex] are required", + json + ) return null } @@ -95,7 +99,11 @@ public data class DomRange( } } - @Deprecated("Renamed into [charOffset]", ReplaceWith("charOffset"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed into [charOffset]", + ReplaceWith("charOffset"), + level = DeprecationLevel.ERROR + ) val offset: Long? get() = charOffset?.toLong() } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt index fea241ddab..3be98b5b7f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Properties.kt @@ -10,7 +10,11 @@ package org.readium.r2.shared.publication.opds import org.json.JSONObject -import org.readium.r2.shared.opds.* +import org.readium.r2.shared.opds.Acquisition +import org.readium.r2.shared.opds.Availability +import org.readium.r2.shared.opds.Copies +import org.readium.r2.shared.opds.Holds +import org.readium.r2.shared.opds.Price import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Properties @@ -46,7 +50,11 @@ public val Properties.indirectAcquisitions: List } ?: emptyList() -@Deprecated("Use [indirectAcquisitions] instead.", ReplaceWith("indirectAcquisitions"), level = DeprecationLevel.ERROR) +@Deprecated( + "Use [indirectAcquisitions] instead.", + ReplaceWith("indirectAcquisitions"), + level = DeprecationLevel.ERROR +) public val Properties.indirectAcquisition: List get() = indirectAcquisitions diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/presentation/Presentation.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/presentation/Presentation.kt index f7f840a854..dfe687e34a 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/presentation/Presentation.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/presentation/Presentation.kt @@ -102,10 +102,17 @@ public data class Presentation( @Parcelize @Serializable public enum class Fit(public val value: String) : Parcelable { - @SerialName("width") WIDTH("width"), - @SerialName("height") HEIGHT("height"), - @SerialName("contain") CONTAIN("contain"), - @SerialName("cover") COVER("cover"); + @SerialName("width") + WIDTH("width"), + + @SerialName("height") + HEIGHT("height"), + + @SerialName("contain") + CONTAIN("contain"), + + @SerialName("cover") + COVER("cover"); public companion object : MapCompanion(values(), Fit::value) { @@ -122,9 +129,14 @@ public data class Presentation( @Parcelize @Serializable public enum class Orientation(public val value: String) : Parcelable { - @SerialName("auto") AUTO("auto"), - @SerialName("landscape") LANDSCAPE("landscape"), - @SerialName("portrait") PORTRAIT("portrait"); + @SerialName("auto") + AUTO("auto"), + + @SerialName("landscape") + LANDSCAPE("landscape"), + + @SerialName("portrait") + PORTRAIT("portrait"); public companion object : MapCompanion(values(), Orientation::value) { @@ -133,11 +145,25 @@ public data class Presentation( */ public val DEFAULT: Orientation = AUTO - @Deprecated("Renamed to [AUTO]", ReplaceWith("Orientation.AUTO"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [AUTO]", + ReplaceWith("Orientation.AUTO"), + level = DeprecationLevel.ERROR + ) public val Auto: Orientation = AUTO - @Deprecated("Renamed to [LANDSCAPE]", ReplaceWith("Orientation.LANDSCAPE"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [LANDSCAPE]", + ReplaceWith("Orientation.LANDSCAPE"), + level = DeprecationLevel.ERROR + ) public val Landscape: Orientation = LANDSCAPE - @Deprecated("Renamed to [PORTRAIT]", ReplaceWith("Orientation.PORTRAIT"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [PORTRAIT]", + ReplaceWith("Orientation.PORTRAIT"), + level = DeprecationLevel.ERROR + ) public val Portrait: Orientation = PORTRAIT } } @@ -148,9 +174,14 @@ public data class Presentation( @Parcelize @Serializable public enum class Overflow(public val value: String) : Parcelable { - @SerialName("auto") AUTO("auto"), - @SerialName("paginated") PAGINATED("paginated"), - @SerialName("scrolled") SCROLLED("scrolled"); + @SerialName("auto") + AUTO("auto"), + + @SerialName("paginated") + PAGINATED("paginated"), + + @SerialName("scrolled") + SCROLLED("scrolled"); public companion object : MapCompanion(values(), Overflow::value) { @@ -159,11 +190,25 @@ public data class Presentation( */ public val DEFAULT: Overflow = AUTO - @Deprecated("Renamed to [PAGINATED]", ReplaceWith("Overflow.PAGINATED"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [PAGINATED]", + ReplaceWith("Overflow.PAGINATED"), + level = DeprecationLevel.ERROR + ) public val Paginated: Overflow = PAGINATED - @Deprecated("Use [presentation.continuous] instead", ReplaceWith("presentation.continuous"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [presentation.continuous] instead", + ReplaceWith("presentation.continuous"), + level = DeprecationLevel.ERROR + ) public val Continuous: Overflow = SCROLLED - @Deprecated("Renamed to [SCROLLED]", ReplaceWith("Overflow.SCROLLED"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [SCROLLED]", + ReplaceWith("Overflow.SCROLLED"), + level = DeprecationLevel.ERROR + ) public val Document: Overflow = SCROLLED } } @@ -175,9 +220,14 @@ public data class Presentation( @Parcelize @Serializable public enum class Page(public val value: String) : Parcelable { - @SerialName("left") LEFT("left"), - @SerialName("right") RIGHT("right"), - @SerialName("center") CENTER("center"); + @SerialName("left") + LEFT("left"), + + @SerialName("right") + RIGHT("right"), + + @SerialName("center") + CENTER("center"); public companion object : MapCompanion(values(), Page::value) } @@ -189,10 +239,17 @@ public data class Presentation( @Parcelize @Serializable public enum class Spread(public val value: String) : Parcelable { - @SerialName("auto") AUTO("auto"), - @SerialName("both") BOTH("both"), - @SerialName("none") NONE("none"), - @SerialName("landscape") LANDSCAPE("landscape"); + @SerialName("auto") + AUTO("auto"), + + @SerialName("both") + BOTH("both"), + + @SerialName("none") + NONE("none"), + + @SerialName("landscape") + LANDSCAPE("landscape"); public companion object : MapCompanion(values(), Spread::value) { @@ -201,15 +258,39 @@ public data class Presentation( */ public val DEFAULT: Spread = AUTO - @Deprecated("Renamed to [AUTO]", ReplaceWith("Spread.AUTO"), level = DeprecationLevel.ERROR) + @Deprecated( + "Renamed to [AUTO]", + ReplaceWith("Spread.AUTO"), + level = DeprecationLevel.ERROR + ) public val Auto: Spread = AUTO - @Deprecated("Renamed to [LANDSCAPE]", ReplaceWith("Spread.LANDSCAPE"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [LANDSCAPE]", + ReplaceWith("Spread.LANDSCAPE"), + level = DeprecationLevel.ERROR + ) public val Landscape: Spread = LANDSCAPE - @Deprecated("Renamed to [BOTH]", ReplaceWith("Spread.BOTH"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [BOTH]", + ReplaceWith("Spread.BOTH"), + level = DeprecationLevel.ERROR + ) public val Portrait: Spread = BOTH - @Deprecated("Renamed to [BOTH]", ReplaceWith("Spread.BOTH"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [BOTH]", + ReplaceWith("Spread.BOTH"), + level = DeprecationLevel.ERROR + ) public val Both: Spread = BOTH - @Deprecated("Renamed to [NONE]", ReplaceWith("Spread.NONE"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Renamed to [NONE]", + ReplaceWith("Spread.NONE"), + level = DeprecationLevel.ERROR + ) public val None: Spread = NONE } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt index 6872b4656b..a3e974d8c0 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt @@ -9,25 +9,20 @@ package org.readium.r2.shared.publication.protection import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.error.Try -import org.readium.r2.shared.fetcher.ContainerFetcher import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.protection.ContentProtection.Scheme import org.readium.r2.shared.publication.services.contentProtectionServiceFactory -import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsXml import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * [ContentProtection] implementation used as a fallback by the Streamer to detect Adept DRM, * if it is not supported by the app. */ @InternalReadiumApi -public class AdeptFallbackContentProtection( - private val mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever() -) : ContentProtection { +public class AdeptFallbackContentProtection : ContentProtection { override val scheme: Scheme = Scheme.Adept @@ -36,7 +31,7 @@ public class AdeptFallbackContentProtection( return false } - return isAdept(asset.container, asset.mediaType) + return isAdept(asset) } override suspend fun open( @@ -52,9 +47,8 @@ public class AdeptFallbackContentProtection( } val protectedFile = ContentProtection.Asset( - asset.name, asset.mediaType, - ContainerFetcher(asset.container, mediaTypeRetriever), + asset.container, onCreatePublication = { servicesBuilder.contentProtectionServiceFactory = FallbackContentProtectionService.createFactory(scheme, "Adobe ADEPT") @@ -64,12 +58,12 @@ public class AdeptFallbackContentProtection( return Try.success(protectedFile) } - private suspend fun isAdept(container: Container, mediaType: MediaType): Boolean { - if (!mediaType.matches(MediaType.EPUB)) { + private suspend fun isAdept(asset: Asset.Container): Boolean { + if (!asset.mediaType.matches(MediaType.EPUB)) { return false } - val rightsXml = container.entry("/META-INF/rights.xml").readAsXmlOrNull() - val encryptionXml = container.entry("/META-INF/encryption.xml").readAsXmlOrNull() + val rightsXml = asset.container.get("/META-INF/rights.xml").readAsXmlOrNull() + val encryptionXml = asset.container.get("/META-INF/encryption.xml").readAsXmlOrNull() return encryptionXml != null && ( rightsXml?.namespace == "http://ns.adobe.com/adept" || diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt index 19d73530f6..86275c3a03 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt @@ -13,17 +13,17 @@ import androidx.annotation.StringRes import org.readium.r2.shared.R import org.readium.r2.shared.UserException import org.readium.r2.shared.error.Try -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.LocalizedString import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.ContentProtectionService +import org.readium.r2.shared.resource.Container import org.readium.r2.shared.util.mediatype.MediaType /** * Bridge between a Content Protection technology and the Readium toolkit. * * Its responsibilities are to: - * - Create a [Fetcher] one can access the publication through. + * - Create a [Container] one can access the publication through. * - Create a [ContentProtectionService] publication service. */ public interface ContentProtection { @@ -53,17 +53,15 @@ public interface ContentProtection { /** * Holds the result of opening an [Asset] with a [ContentProtection]. * - * @property name Asset name * @property mediaType Media type of the asset - * @property fetcher Fetcher to access the publication through + * @property container Container to access the publication through * @property onCreatePublication Called on every parsed Publication.Builder - * It can be used to modify the `Manifest`, the root [Fetcher] or the list of service factories - * of a [Publication]. + * It can be used to modify the `Manifest`, the root [Container] or the list of service + * factories of a [Publication]. */ public data class Asset( - val name: String, val mediaType: MediaType, - val fetcher: Fetcher, + val container: Container, val onCreatePublication: Publication.Builder.() -> Unit = {} ) @@ -72,7 +70,7 @@ public interface ContentProtection { */ @JvmInline public value class Scheme( - public val uri: String, + public val uri: String ) { @Deprecated("Define yourself the name to print to users.", level = DeprecationLevel.ERROR) @@ -81,6 +79,7 @@ public interface ContentProtection { public companion object { /** Readium LCP DRM scheme. */ public val Lcp: Scheme = Scheme(uri = "http://readium.org/2014/01/lcp") + /** Adobe ADEPT DRM scheme. */ public val Adept: Scheme = Scheme(uri = "http://ns.adobe.com/adept") } @@ -103,8 +102,11 @@ public interface ContentProtection { * app. */ public class SchemeNotSupported(public val scheme: Scheme? = null, name: String?) : Exception( - if (name == null) R.string.readium_shared_publication_content_protection_exception_not_supported_unknown - else R.string.readium_shared_publication_content_protection_exception_not_supported, + if (name == null) { + R.string.readium_shared_publication_content_protection_exception_not_supported_unknown + } else { + R.string.readium_shared_publication_content_protection_exception_not_supported + }, name ) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt index a1c0d2f087..5dad613388 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtectionSchemeRetriever.kt @@ -19,7 +19,7 @@ public class ContentProtectionSchemeRetriever( private val contentProtections: List = contentProtections + listOf( LcpFallbackContentProtection(mediaTypeRetriever), - AdeptFallbackContentProtection(mediaTypeRetriever) + AdeptFallbackContentProtection() ) public suspend fun retrieve(asset: Asset): ContentProtection.Scheme? = diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt index 96dd67a829..f96ec028ec 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt @@ -10,7 +10,6 @@ import org.json.JSONObject import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.error.Try -import org.readium.r2.shared.fetcher.ContainerFetcher import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication @@ -30,7 +29,7 @@ import org.readium.r2.shared.util.mediatype.MediaTypeRetriever */ @InternalReadiumApi public class LcpFallbackContentProtection( - private val mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever() + private val mediaTypeRetriever: MediaTypeRetriever ) : ContentProtection { override val scheme: Scheme = @@ -55,9 +54,8 @@ public class LcpFallbackContentProtection( } val protectedFile = ContentProtection.Asset( - asset.name, asset.mediaType, - ContainerFetcher(asset.container, mediaTypeRetriever), + asset.container, onCreatePublication = { servicesBuilder.contentProtectionServiceFactory = FallbackContentProtectionService.createFactory(scheme, "Readium LCP") @@ -72,14 +70,17 @@ public class LcpFallbackContentProtection( mediaType.matches(MediaType.READIUM_WEBPUB) || mediaType.matches(MediaType.LCP_PROTECTED_PDF) || mediaType.matches(MediaType.LCP_PROTECTED_AUDIOBOOK) -> { - if (container.entry("/license.lcpl").readAsJsonOrNull() != null) { + if (container.get("/license.lcpl").readAsJsonOrNull() != null) { return true } - val manifestAsJson = container.entry("/manifest.json").readAsJsonOrNull() + val manifestAsJson = container.get("/manifest.json").readAsJsonOrNull() ?: return false - val manifest = Manifest.fromJSON(manifestAsJson) + val manifest = Manifest.fromJSON( + manifestAsJson, + mediaTypeRetriever = mediaTypeRetriever + ) ?: return false return manifest @@ -87,11 +88,11 @@ public class LcpFallbackContentProtection( .any { it.properties.encryption?.scheme == "http://readium.org/2014/01/lcp" } } mediaType.matches(MediaType.EPUB) -> { - if (container.entry("/META-INF/license.lcpl").readAsJsonOrNull() != null) { + if (container.get("/META-INF/license.lcpl").readAsJsonOrNull() != null) { return true } - val encryptionXml = container.entry("/META-INF/encryption.xml").readAsXmlOrNull() + val encryptionXml = container.get("/META-INF/encryption.xml").readAsXmlOrNull() ?: return false return encryptionXml diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt index e8ce551179..819f343d08 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt @@ -9,21 +9,23 @@ package org.readium.r2.shared.publication.services -import java.util.* +import java.util.Locale import org.json.JSONObject import org.readium.r2.shared.UserException +import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.putIfNotEmpty import org.readium.r2.shared.extensions.queryParameters -import org.readium.r2.shared.fetcher.FailureResource -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.StringResource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.LocalizedString import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.PublicationServicesHolder import org.readium.r2.shared.publication.ServiceFactory import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.resource.FailureResource import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.StringResource +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType /** * Provides information about a publication's content protection and manages user rights. @@ -65,7 +67,7 @@ public interface ContentProtectionService : Publication.Service { override val links: List get() = RouteHandler.links - override fun get(link: Link): Fetcher.Resource? { + override fun get(link: Link): Resource? { val route = RouteHandler.route(link) ?: return null return route.handleRequest(link, this) } @@ -249,43 +251,53 @@ private sealed class RouteHandler { abstract fun acceptRequest(link: Link): Boolean - abstract fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource + abstract fun handleRequest(link: Link, service: ContentProtectionService): Resource object ContentProtectionHandler : RouteHandler() { + private val mediaType = MediaType("application/vnd.readium.content-protection+json")!! + override val link = Link( href = "/~readium/content-protection", - type = "application/vnd.readium.content-protection+json" + mediaType = mediaType ) override fun acceptRequest(link: Link): Boolean = link.href == this.link.href - override fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource = - StringResource(link) { - JSONObject().apply { - put("isRestricted", service.isRestricted) - putOpt("error", service.error?.localizedMessage) - putIfNotEmpty("name", service.name) - put("rights", service.rights.toJSON()) - }.toString() + override fun handleRequest(link: Link, service: ContentProtectionService): Resource = + StringResource( + url = Url(link.href), + mediaType = mediaType + ) { + Try.success( + JSONObject().apply { + put("isRestricted", service.isRestricted) + putOpt("error", service.error?.localizedMessage) + putIfNotEmpty("name", service.name) + put("rights", service.rights.toJSON()) + }.toString() + ) } } object RightsCopyHandler : RouteHandler() { + private val mediaType = MediaType("application/vnd.readium.rights.copy+json")!! + override val link: Link = Link( href = "/~readium/rights/copy{?text,peek}", - type = "application/vnd.readium.rights.copy+json", + mediaType = mediaType, templated = true ) - override fun acceptRequest(link: Link): Boolean = link.href.startsWith("/~readium/rights/copy") + override fun acceptRequest(link: Link): Boolean = link.href.startsWith( + "/~readium/rights/copy" + ) - override fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource { + override fun handleRequest(link: Link, service: ContentProtectionService): Resource { val parameters = link.href.queryParameters() val text = parameters["text"] ?: return FailureResource( - link, Resource.Exception.BadRequest( parameters, IllegalArgumentException("'text' parameter is required") @@ -293,7 +305,6 @@ private sealed class RouteHandler { ) val peek = (parameters["peek"] ?: "false").toBooleanOrNull() ?: return FailureResource( - link, Resource.Exception.BadRequest( parameters, IllegalArgumentException("if present, 'peek' must be true or false") @@ -302,28 +313,32 @@ private sealed class RouteHandler { val copyAllowed = with(service.rights) { if (peek) canCopy(text) else copy(text) } - return if (!copyAllowed) - FailureResource(link, Resource.Exception.Forbidden()) - else - StringResource(link, "true") + return if (!copyAllowed) { + FailureResource(Resource.Exception.Forbidden()) + } else { + StringResource("true", MediaType.JSON) + } } } object RightsPrintHandler : RouteHandler() { + private val mediaType = MediaType("application/vnd.readium.rights.print+json")!! + override val link = Link( href = "/~readium/rights/print{?pageCount,peek}", - type = "application/vnd.readium.rights.print+json", + mediaType = mediaType, templated = true ) - override fun acceptRequest(link: Link): Boolean = link.href.startsWith("/~readium/rights/print") + override fun acceptRequest(link: Link): Boolean = link.href.startsWith( + "/~readium/rights/print" + ) - override fun handleRequest(link: Link, service: ContentProtectionService): Fetcher.Resource { + override fun handleRequest(link: Link, service: ContentProtectionService): Resource { val parameters = link.href.queryParameters() val pageCountString = parameters["pageCount"] ?: return FailureResource( - link, Resource.Exception.BadRequest( parameters, IllegalArgumentException("'pageCount' parameter is required") @@ -332,7 +347,6 @@ private sealed class RouteHandler { val pageCount = pageCountString.toIntOrNull()?.takeIf { it >= 0 } ?: return FailureResource( - link, Resource.Exception.BadRequest( parameters, IllegalArgumentException("'pageCount' must be a positive integer") @@ -340,19 +354,27 @@ private sealed class RouteHandler { ) val peek = (parameters["peek"] ?: "false").toBooleanOrNull() ?: return FailureResource( - link, Resource.Exception.BadRequest( parameters, IllegalArgumentException("if present, 'peek' must be true or false") ) ) - val printAllowed = with(service.rights) { if (peek) canPrint(pageCount) else print(pageCount) } + val printAllowed = with(service.rights) { + if (peek) { + canPrint(pageCount) + } else { + print( + pageCount + ) + } + } - return if (!printAllowed) - FailureResource(link, Resource.Exception.Forbidden()) - else - StringResource(link, "true") + return if (!printAllowed) { + FailureResource(Resource.Exception.Forbidden()) + } else { + StringResource("true", mediaType = MediaType.JSON) + } } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt index 89038aa276..10f4e5876e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/CoverService.kt @@ -14,13 +14,15 @@ import android.graphics.BitmapFactory import android.util.Size import org.readium.r2.shared.extensions.scaleToFit import org.readium.r2.shared.extensions.toPng -import org.readium.r2.shared.fetcher.BytesResource -import org.readium.r2.shared.fetcher.FailureResource -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.LazyResource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.ServiceFactory +import org.readium.r2.shared.resource.BytesResource +import org.readium.r2.shared.resource.FailureResource +import org.readium.r2.shared.resource.LazyResource +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType /** * Provides an easy access to a bitmap version of the publication cover. @@ -90,7 +92,7 @@ public abstract class GeneratedCoverService : CoverService { private val coverLink = Link( href = "/~readium/cover", - type = "image/png", + mediaType = MediaType.PNG, rels = setOf("cover") ) @@ -98,21 +100,20 @@ public abstract class GeneratedCoverService : CoverService { abstract override suspend fun cover(): Bitmap - override fun get(link: Link): Fetcher.Resource? { - if (link.href != coverLink.href) + override fun get(link: Link): Resource? { + if (link.href != coverLink.href) { return null + } - return LazyResource { + return LazyResource(source = Url(link.href)) { val cover = cover() val png = cover.toPng() if (png == null) { val error = Exception("Unable to convert cover to PNG.") - FailureResource(coverLink, error) + FailureResource(error) } else { - @Suppress("NAME_SHADOWING") - val link = coverLink.copy(width = cover.width, height = cover.height) - BytesResource(link, png) + BytesResource(png, url = Url(coverLink.href), mediaType = MediaType.PNG) } } } @@ -124,7 +125,13 @@ public abstract class GeneratedCoverService : CoverService { public class InMemoryCoverService internal constructor(private val cover: Bitmap) : GeneratedCoverService() { public companion object { - public fun createFactory(cover: Bitmap?): ServiceFactory = { cover?.let { InMemoryCoverService(it) } } + public fun createFactory(cover: Bitmap?): ServiceFactory = { + cover?.let { + InMemoryCoverService( + it + ) + } + } } override suspend fun cover(): Bitmap = cover diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/LocatorService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/LocatorService.kt index b79fcfb62d..f2ad560853 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/LocatorService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/LocatorService.kt @@ -64,7 +64,11 @@ public open class DefaultLocatorService( ?: return null return position.copyWithLocations( - progression = resourceProgressionFor(totalProgression, positions, readingOrderIndex = readingOrderIndex) + progression = resourceProgressionFor( + totalProgression, + positions, + readingOrderIndex = readingOrderIndex + ) ?: position.locations.progression, totalProgression = totalProgression ) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt index d21ffdc5ad..807125b714 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt @@ -11,17 +11,29 @@ package org.readium.r2.shared.publication.services import kotlinx.coroutines.runBlocking import org.json.JSONObject +import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.mapNotNull import org.readium.r2.shared.extensions.toJsonOrNull -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.StringResource -import org.readium.r2.shared.publication.* +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Manifest +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.PublicationServicesHolder +import org.readium.r2.shared.publication.ServiceFactory +import org.readium.r2.shared.publication.firstWithMediaType +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.StringResource import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.toJSON +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType + +private val positionsMediaType = + MediaType("application/vnd.readium.position-list+json")!! private val positionsLink = Link( href = "/~readium/positions", - type = "application/vnd.readium.position-list+json" + mediaType = positionsMediaType ) /** @@ -41,16 +53,22 @@ public interface PositionsService : Publication.Service { override val links: List get() = listOf(positionsLink) - override fun get(link: Link): Fetcher.Resource? { - if (link.href != positionsLink.href) + override fun get(link: Link): Resource? { + if (link.href != positionsLink.href) { return null + } - return StringResource(positionsLink) { + return StringResource( + url = Url(positionsLink.href), + mediaType = positionsMediaType + ) { val positions = positions() - JSONObject().apply { - put("total", positions.size) - put("positions", positions.toJSON()) - }.toString() + Try.success( + JSONObject().apply { + put("total", positions.size) + put("positions", positions.toJSON()) + }.toString() + ) } } } @@ -74,7 +92,11 @@ public suspend fun PublicationServicesHolder.positions(): List { /** * List of all the positions in each resource, indexed by their href. */ -@Deprecated("Use [positionsByReadingOrder] instead", ReplaceWith("positionsByReadingOrder"), level = DeprecationLevel.ERROR) +@Deprecated( + "Use [positionsByReadingOrder] instead", + ReplaceWith("positionsByReadingOrder"), + level = DeprecationLevel.ERROR +) public val Publication.positionsByResource: Map> get() = runBlocking { positions().groupBy { it.href } } @@ -102,7 +124,7 @@ public class PerResourcePositionsService( listOf( Locator( href = link.href, - type = link.type ?: fallbackMediaType, + type = link.mediaType?.toString() ?: fallbackMediaType, title = link.title, locations = Locator.Locations( position = index + 1, @@ -132,12 +154,13 @@ internal class WebPositionsService( override val links: List = listOfNotNull( - manifest.links.firstWithMediaType(positionsLink.mediaType) + manifest.links.firstWithMediaType(positionsMediaType) ) override suspend fun positions(): List { - if (!::_positions.isInitialized) + if (!::_positions.isInitialized) { _positions = computePositions() + } return _positions } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/Content.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/Content.kt index 6c32329506..62c966ba0e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/Content.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/Content.kt @@ -50,14 +50,14 @@ public interface Content { public data class AudioElement( override val locator: Locator, override val embeddedLink: Link, - override val attributes: List> = emptyList(), + override val attributes: List> = emptyList() ) : EmbeddedElement, TextualElement /** A video clip. */ public data class VideoElement( override val locator: Locator, override val embeddedLink: Link, - override val attributes: List> = emptyList(), + override val attributes: List> = emptyList() ) : EmbeddedElement, TextualElement /** @@ -69,7 +69,7 @@ public interface Content { override val locator: Locator, override val embeddedLink: Link, val caption: String?, - override val attributes: List> = emptyList(), + override val attributes: List> = emptyList() ) : EmbeddedElement, TextualElement { override val text: String? get() = @@ -89,7 +89,7 @@ public interface Content { override val locator: Locator, val role: Role, val segments: List, - override val attributes: List> = emptyList(), + override val attributes: List> = emptyList() ) : TextualElement { override val text: String @@ -138,7 +138,7 @@ public interface Content { public data class Segment( val locator: Locator, val text: String, - override val attributes: List>, + override val attributes: List> ) : AttributesHolder } @@ -157,7 +157,9 @@ public interface Content { */ public data class AttributeKey(val id: String) { public companion object { - public val ACCESSIBILITY_LABEL: AttributeKey = AttributeKey("accessibilityLabel") + public val ACCESSIBILITY_LABEL: AttributeKey = AttributeKey( + "accessibilityLabel" + ) public val LANGUAGE: AttributeKey = AttributeKey("language") } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt index 2391fcbcab..885b8d1e79 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentService.kt @@ -7,11 +7,11 @@ package org.readium.r2.shared.publication.services.content import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.ServiceFactory import org.readium.r2.shared.publication.services.content.iterators.PublicationContentIterator import org.readium.r2.shared.publication.services.content.iterators.ResourceContentIteratorFactory +import org.readium.r2.shared.resource.Container /** * Provides a way to extract the raw [Content] of a [Publication]. @@ -52,7 +52,7 @@ public var Publication.ServicesBuilder.contentServiceFactory: ServiceFactory? @ExperimentalReadiumApi public class DefaultContentService( private val manifest: Manifest, - private val fetcher: Fetcher, + private val container: Container, private val services: PublicationServicesHolder, private val resourceContentIteratorFactories: List ) : ContentService { @@ -61,24 +61,29 @@ public class DefaultContentService( public fun createFactory( resourceContentIteratorFactories: List ): (Publication.Service.Context) -> DefaultContentService = { context -> - DefaultContentService(context.manifest, context.fetcher, context.services, resourceContentIteratorFactories) + DefaultContentService( + context.manifest, + context.container, + context.services, + resourceContentIteratorFactories + ) } } override fun content(start: Locator?): Content { - return ContentImpl(manifest, fetcher, services, start) + return ContentImpl(manifest, container, services, start) } private inner class ContentImpl( val manifest: Manifest, - val fetcher: Fetcher, + val container: Container, val services: PublicationServicesHolder, - val start: Locator?, + val start: Locator? ) : Content { override fun iterator(): Content.Iterator = PublicationContentIterator( manifest = manifest, - fetcher = fetcher, + container = container, services = services, startLocator = start, resourceContentIteratorFactories = resourceContentIteratorFactories diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentTokenizer.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentTokenizer.kt index 76761d21c5..c90b1eb58e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentTokenizer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/ContentTokenizer.kt @@ -43,7 +43,12 @@ public class TextContentTokenizer( overrideContentLanguage: Boolean = false ) : this( language = language, - textTokenizerFactory = { contentLanguage -> DefaultTextContentTokenizer(unit, contentLanguage) }, + textTokenizerFactory = { contentLanguage -> + DefaultTextContentTokenizer( + unit, + contentLanguage + ) + }, overrideContentLanguage = overrideContentLanguage ) @@ -70,8 +75,14 @@ public class TextContentTokenizer( segment.language.takeUnless { overrideContentLanguage } ?: language private fun extractTextContextIn(string: String, range: IntRange): Locator.Text { - val after = string.substring(range.last, (range.last + contextSnippetLength).coerceAtMost(string.length)) - val before = string.substring((range.first - contextSnippetLength).coerceAtLeast(0), range.first) + val after = string.substring( + range.last, + (range.last + contextSnippetLength).coerceAtMost(string.length) + ) + val before = string.substring( + (range.first - contextSnippetLength).coerceAtLeast(0), + range.first + ) return Locator.Text( after = after.takeIf { it.isNotEmpty() }, before = before.takeIf { it.isNotEmpty() }, diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index 0b35680ab2..47113bc084 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -17,12 +17,20 @@ import org.jsoup.select.NodeVisitor import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.* +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Manifest +import org.readium.r2.shared.publication.PublicationServicesHolder import org.readium.r2.shared.publication.html.cssSelector import org.readium.r2.shared.publication.services.content.Content -import org.readium.r2.shared.publication.services.content.Content.* +import org.readium.r2.shared.publication.services.content.Content.Attribute +import org.readium.r2.shared.publication.services.content.Content.AttributeKey +import org.readium.r2.shared.publication.services.content.Content.AudioElement +import org.readium.r2.shared.publication.services.content.Content.ImageElement +import org.readium.r2.shared.publication.services.content.Content.TextElement +import org.readium.r2.shared.publication.services.content.Content.VideoElement import org.readium.r2.shared.publication.services.positionsByReadingOrder +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.Language @@ -43,7 +51,7 @@ import org.readium.r2.shared.util.use */ @ExperimentalReadiumApi public class HtmlResourceContentIterator internal constructor( - private val resource: Fetcher.Resource, + private val resource: Resource, private val totalProgressionRange: ClosedRange?, private val locator: Locator, private val beforeMaxLength: Int = 50 @@ -54,10 +62,10 @@ public class HtmlResourceContentIterator internal constructor( manifest: Manifest, servicesHolder: PublicationServicesHolder, readingOrderIndex: Int, - resource: Fetcher.Resource, + resource: Resource, locator: Locator ): Content.Iterator? { - if (!resource.link().mediaType.matchesAny(MediaType.HTML, MediaType.XHTML)) { + if (resource.mediaType().getOrNull()?.matchesAny(MediaType.HTML, MediaType.XHTML) != true) { return null } @@ -106,7 +114,9 @@ public class HtmlResourceContentIterator internal constructor( currentElement ?.takeIf { it.delta == -1 }?.element ?.also { currentElement = null } - ?: throw IllegalStateException("Called previous() without a successful call to hasPrevious() first") + ?: throw IllegalStateException( + "Called previous() without a successful call to hasPrevious() first" + ) override suspend fun hasNext(): Boolean { if (currentElement?.delta == +1) return true @@ -126,7 +136,9 @@ public class HtmlResourceContentIterator internal constructor( currentElement ?.takeIf { it.delta == +1 }?.element ?.also { currentElement = null } - ?: throw IllegalStateException("Called next() without a successful call to hasNext() first") + ?: throw IllegalStateException( + "Called next() without a successful call to hasNext() first" + ) private var currentIndex: Int? = null @@ -198,7 +210,7 @@ public class HtmlResourceContentIterator internal constructor( */ public data class ParsedElements( val elements: List, - val startIndex: Int, + val startIndex: Int ) private class ContentParser( @@ -209,8 +221,11 @@ public class HtmlResourceContentIterator internal constructor( fun result() = ParsedElements( elements = elements, - startIndex = if (baseLocator.locations.progression == 1.0) elements.size - else startIndex + startIndex = if (baseLocator.locations.progression == 1.0) { + elements.size + } else { + startIndex + } ) private val elements = mutableListOf() @@ -218,16 +233,22 @@ public class HtmlResourceContentIterator internal constructor( /** Segments accumulated for the current element. */ private val segmentsAcc = mutableListOf() + /** Text since the beginning of the current segment, after coalescing whitespaces. */ private var textAcc = StringBuilder() + /** Text content since the beginning of the resource, including whitespaces. */ private var wholeRawTextAcc: String? = null + /** Text content since the beginning of the current element, including whitespaces. */ private var elementRawTextAcc: String = "" + /** Text content since the beginning of the current segment, including whitespaces. */ private var rawTextAcc: String = "" + /** Language of the current segment. */ private var currentLanguage: String? = null + /** CSS selector of the current element. */ private var currentCssSelector: String? = null @@ -288,7 +309,10 @@ public class HtmlResourceContentIterator internal constructor( val sources = node.select("source") .mapNotNull { source -> source.srcRelativeToHref(baseLocator.href)?.let { href -> - Link(href = href, type = source.attr("type").takeUnless { it.isBlank() }) + Link( + href = href, + mediaType = MediaType(source.attr("type")) + ) } } @@ -297,8 +321,20 @@ public class HtmlResourceContentIterator internal constructor( if (link != null) { when (tag) { - "audio" -> elements.add(AudioElement(locator = elementLocator, embeddedLink = link, attributes = emptyList())) - "video" -> elements.add(VideoElement(locator = elementLocator, embeddedLink = link, attributes = emptyList())) + "audio" -> elements.add( + AudioElement( + locator = elementLocator, + embeddedLink = link, + attributes = emptyList() + ) + ) + "video" -> elements.add( + VideoElement( + locator = elementLocator, + embeddedLink = link, + attributes = emptyList() + ) + ) else -> {} } } @@ -410,7 +446,7 @@ public class HtmlResourceContentIterator internal constructor( currentLanguage?.let { add(Attribute(AttributeKey.LANGUAGE, Language(it))) } - }, + } ) ) } @@ -430,7 +466,10 @@ private fun Locator.Text.Companion.trimmingText(text: String, before: String?): val trailingWhitespace = text.takeLastWhile { it.isWhitespace() } return Locator.Text( before = ((before ?: "") + leadingWhitespace).takeUnless { it.isBlank() }, - highlight = text.substring(leadingWhitespace.length, text.length - trailingWhitespace.length), + highlight = text.substring( + leadingWhitespace.length, + text.length - trailingWhitespace.length + ), after = trailingWhitespace.takeUnless { it.isBlank() } ) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt index 463c7cc620..496f4ac438 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/PublicationContentIterator.kt @@ -7,13 +7,19 @@ package org.readium.r2.shared.publication.services.content.iterators import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.* +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Manifest +import org.readium.r2.shared.publication.PublicationServicesHolder +import org.readium.r2.shared.publication.indexOfFirstWithHref import org.readium.r2.shared.publication.services.content.Content +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.Either /** - * Creates a [Content.Iterator] instance for the [Fetcher.Resource], starting from the given [Locator]. + * Creates a [Content.Iterator] instance for the [Resource], starting from the + * given [Locator]. * * Returns null if the resource media type is not supported. */ @@ -29,7 +35,7 @@ public fun interface ResourceContentIteratorFactory { manifest: Manifest, servicesHolder: PublicationServicesHolder, readingOrderIndex: Int, - resource: Fetcher.Resource, + resource: Resource, locator: Locator ): Content.Iterator? } @@ -47,7 +53,7 @@ public fun interface ResourceContentIteratorFactory { @ExperimentalReadiumApi public class PublicationContentIterator( private val manifest: Manifest, - private val fetcher: Fetcher, + private val container: Container, private val services: PublicationServicesHolder, private val startLocator: Locator?, private val resourceContentIteratorFactories: List @@ -80,7 +86,9 @@ public class PublicationContentIterator( override fun previous(): Content.Element = currentElement ?.takeIf { it.direction == Direction.Backward }?.element - ?: throw IllegalStateException("Called previous() without a successful call to hasPrevious() first") + ?: throw IllegalStateException( + "Called previous() without a successful call to hasPrevious() first" + ) override suspend fun hasNext(): Boolean { currentElement = nextIn(Direction.Forward) @@ -90,7 +98,9 @@ public class PublicationContentIterator( override fun next(): Content.Element = currentElement ?.takeIf { it.direction == Direction.Forward }?.element - ?: throw IllegalStateException("Called next() without a successful call to hasNext() first") + ?: throw IllegalStateException( + "Called next() without a successful call to hasNext() first" + ) private suspend fun nextIn(direction: Direction): ElementInDirection? { val iterator = currentIterator() ?: return null @@ -154,7 +164,7 @@ public class PublicationContentIterator( private suspend fun loadIteratorAt(index: Int, location: LocatorOrProgression): IndexedIterator? { val link = manifest.readingOrder[index] val locator = location.toLocator(link) ?: return null - val resource = fetcher.get(link) + val resource = container.get(link.href) return resourceContentIteratorFactories .firstNotNullOfOrNull { factory -> diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt index 7b2332381a..a707f9b669 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt @@ -27,7 +27,10 @@ public typealias SearchTry = Try * Represents an error which might occur during a search activity. */ @ExperimentalReadiumApi -public sealed class SearchException(content: Content, cause: Throwable? = null) : UserException(content, cause) { +public sealed class SearchException(content: Content, cause: Throwable? = null) : UserException( + content, + cause +) { protected constructor(@StringRes userMessageId: Int, vararg args: Any, cause: Throwable? = null) : this(Content(userMessageId, *args), cause) protected constructor(cause: UserException) : @@ -36,7 +39,9 @@ public sealed class SearchException(content: Content, cause: Throwable? = null) /** * The publication is not searchable. */ - public object PublicationNotSearchable : SearchException(R.string.readium_shared_search_exception_publication_not_searchable) + public object PublicationNotSearchable : SearchException( + R.string.readium_shared_search_exception_publication_not_searchable + ) /** * The provided search query cannot be handled by the service. @@ -61,7 +66,10 @@ public sealed class SearchException(content: Content, cause: Throwable? = null) public object Cancelled : SearchException(R.string.readium_shared_search_exception_cancelled) /** For any other custom service error. */ - public class Other(cause: Throwable) : SearchException(R.string.readium_shared_search_exception_other, cause = cause) + public class Other(cause: Throwable) : SearchException( + R.string.readium_shared_search_exception_other, + cause = cause + ) public companion object { public fun wrap(e: Throwable): SearchException = diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt index c10c1359bf..2b24a39389 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt @@ -19,12 +19,12 @@ import kotlinx.coroutines.withContext import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.fetcher.DefaultResourceContentExtractorFactory -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.ResourceContentExtractor import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.services.positionsByReadingOrder import org.readium.r2.shared.publication.services.search.SearchService.Options +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.content.DefaultResourceContentExtractorFactory +import org.readium.r2.shared.resource.content.ResourceContentExtractor import timber.log.Timber /** @@ -40,24 +40,24 @@ import timber.log.Timber @ExperimentalReadiumApi public class StringSearchService( private val manifest: Manifest, - private val fetcher: Fetcher, + private val container: Container, private val services: PublicationServicesHolder, private val language: String?, private val snippetLength: Int, private val searchAlgorithm: Algorithm, - private val extractorFactory: ResourceContentExtractor.Factory, + private val extractorFactory: ResourceContentExtractor.Factory ) : SearchService { public companion object { public fun createDefaultFactory( snippetLength: Int = 200, searchAlgorithm: Algorithm? = null, - extractorFactory: ResourceContentExtractor.Factory = DefaultResourceContentExtractorFactory(), + extractorFactory: ResourceContentExtractor.Factory = DefaultResourceContentExtractorFactory() ): (Publication.Service.Context) -> StringSearchService = { context -> StringSearchService( manifest = context.manifest, - fetcher = context.fetcher, + container = context.container, services = context.services, language = context.manifest.metadata.languages.firstOrNull(), snippetLength = snippetLength, @@ -78,10 +78,10 @@ public class StringSearchService( Try.success( Iterator( manifest = manifest, - fetcher = fetcher, + container = container, query = query, options = options ?: Options(), - locale = options?.language?.let { Locale.forLanguageTag(it) } ?: locale, + locale = options?.language?.let { Locale.forLanguageTag(it) } ?: locale ) ) } catch (e: Exception) { @@ -90,7 +90,7 @@ public class StringSearchService( private inner class Iterator( val manifest: Manifest, - val fetcher: Fetcher, + val container: Container, val query: String, val options: Options, val locale: Locale @@ -113,7 +113,7 @@ public class StringSearchService( index += 1 val link = manifest.readingOrder[index] - val resource = fetcher.get(link) + val resource = container.get(link.href) val text = extractorFactory.createExtractor(resource)?.extractText(resource)?.getOrThrow() if (text == null) { @@ -137,8 +137,9 @@ public class StringSearchService( } private suspend fun findLocators(resourceIndex: Int, link: Link, text: String): List { - if (text == "") + if (text == "") { return emptyList() + } val resourceTitle = manifest.tableOfContents.titleMatching(link.href) var resourceLocator = manifest.locatorFromLink(link) ?: return emptyList() @@ -146,7 +147,12 @@ public class StringSearchService( val locators = mutableListOf() withContext(Dispatchers.IO) { - for (range in searchAlgorithm.findRanges(query = query, options = options, text = text, locale = locale)) { + for (range in searchAlgorithm.findRanges( + query = query, + options = options, + text = text, + locale = locale + )) { locators.add(createLocator(resourceIndex, resourceLocator, text, range)) } } @@ -173,9 +179,9 @@ public class StringSearchService( return resourceLocator.copy( locations = resourceLocator.locations.copy( progression = progression, - totalProgression = totalProgression, + totalProgression = totalProgression ), - text = createSnippet(text, range), + text = createSnippet(text, range) ) } @@ -210,7 +216,7 @@ public class StringSearchService( return Locator.Text( highlight = text.substring(range), before = before, - after = after, + after = after ) } @@ -248,7 +254,7 @@ public class StringSearchService( override val options: Options = Options( caseSensitive = false, diacriticSensitive = false, - wholeWord = false, + wholeWord = false ) override suspend fun findRanges( @@ -299,8 +305,11 @@ public class StringSearchService( } val breakIterator: BreakIterator? = - if (wholeWord) BreakIterator.getWordInstance() - else null + if (wholeWord) { + BreakIterator.getWordInstance() + } else { + null + } return StringSearch(query, StringCharacterIterator(text), collator, breakIterator) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt new file mode 100644 index 0000000000..f09cc7083a --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt @@ -0,0 +1,157 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.extensions.coerceIn +import org.readium.r2.shared.extensions.contains +import org.readium.r2.shared.extensions.requireLengthFitInt + +/** + * Wraps a [Resource] and buffers its content. + * + * Expensive interaction with the underlying resource is minimized, since most (smaller) requests + * can be satisfied by accessing the buffer alone. The drawback is that some extra space is required + * to hold the buffer and that copying takes place when filling that buffer, but this is usually + * outweighed by the performance benefits. + * + * Note that this implementation is pretty limited and the benefits are only apparent when reading + * forward and consecutively – e.g. when downloading the resource by chunks. The buffer is ignored + * when reading backward or far ahead. + * + * @param resource Underlying resource which will be buffered. + * @param resourceLength The total length of the resource, when known. This can improve performance + * by avoiding requesting the length from the underlying resource. + * @param bufferSize Size of the buffer chunks to read. + */ +public class BufferingResource( + private val resource: Resource, + resourceLength: Long? = null, + private val bufferSize: Long = DEFAULT_BUFFER_SIZE +) : Resource by resource { + + internal companion object { + internal const val DEFAULT_BUFFER_SIZE: Long = 8192 + } + + /** + * The buffer containing the current bytes read from the wrapped [Resource], with the range it + * covers. + */ + private var buffer: Pair? = null + + private lateinit var _cachedLength: ResourceTry + private suspend fun cachedLength(): ResourceTry { + if (!::_cachedLength.isInitialized) { + _cachedLength = resource.length() + } + return _cachedLength + } + + init { + if (resourceLength != null) { + _cachedLength = Try.success(resourceLength) + } + } + + override suspend fun read(range: LongRange?): ResourceTry { + val length = cachedLength().getOrNull() + // Reading the whole resource bypasses buffering to keep things simple. + if (range == null || length == null) { + return resource.read(range) + } + + val requestedRange = range + .coerceIn(0L until length) + .requireLengthFitInt() + if (requestedRange.isEmpty()) { + return Try.success(ByteArray(0)) + } + + // Round up the range to be read to the next `bufferSize`, because we will buffer the + // excess. + val readLast = (requestedRange.last + 1).ceilMultipleOf(bufferSize).coerceAtMost(length) + var readRange = requestedRange.first until readLast + + // Attempt to serve parts or all of the request using the buffer. + buffer?.let { pair -> + var (buffer, bufferedRange) = pair + + // Everything already buffered? + if (bufferedRange.contains(requestedRange)) { + val data = extractRange(requestedRange, buffer, start = bufferedRange.first) + return Try.success(data) + + // Beginning of requested data is buffered? + } else if (bufferedRange.contains(requestedRange.first)) { + readRange = (bufferedRange.last + 1)..readRange.last + + return resource.read(readRange).map { readData -> + buffer += readData + // Shift the current buffer to the tail of the read data. + saveBuffer(buffer, readRange) + + val bytes = extractRange(requestedRange, buffer, start = bufferedRange.first) + bytes + } + } + } + + // Fallback on reading the requested range from the original resource. + return resource.read(readRange).map { data -> + saveBuffer(data, readRange) + + val res = if (data.count() > requestedRange.count()) { + data.copyOfRange(0, requestedRange.count()) + } else { + data + } + + res + } + } + + /** + * Keeps the last chunk of the given data as the buffer for next reads. + * + * @param data Data read from the original resource. + * @param range Range of the read data in the resource. + */ + private fun saveBuffer(data: ByteArray, range: LongRange) { + val lastChunk = data.takeLast(bufferSize.toInt()).toByteArray() + val chunkRange = (range.last + 1 - lastChunk.count())..range.last + buffer = Pair(lastChunk, chunkRange) + } + + /** + * Reads a sub-range of the given [data] after shifting the given absolute (to the resource) + * ranges to be relative to [data]. + */ + private fun extractRange(requestedRange: LongRange, data: ByteArray, start: Long): ByteArray { + val first = requestedRange.first - start + val lastExclusive = first + requestedRange.count() + require(first >= 0) + require(lastExclusive <= data.count()) { "$lastExclusive > ${data.count()}" } + return data.copyOfRange(first.toInt(), lastExclusive.toInt()) + } + + private fun Long.ceilMultipleOf(divisor: Long) = + divisor * (this / divisor + if (this % divisor == 0L) 0 else 1) +} + +/** + * Wraps this resource in a [BufferingResource] to improve reading performances. + * + * @param resourceLength The total length of the resource, when known. This can improve performance + * by avoiding requesting the length from the underlying resource. + * @param size Size of the buffer chunks to read. + */ +public fun Resource.buffered( + resourceLength: Long? = null, + size: Long = BufferingResource.DEFAULT_BUFFER_SIZE +): BufferingResource = + BufferingResource(resource = this, resourceLength = resourceLength, bufferSize = size) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt index ae912c46fa..d142922c2b 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt @@ -8,44 +8,58 @@ package org.readium.r2.shared.resource import kotlinx.coroutines.runBlocking import org.readium.r2.shared.error.Try -import org.readium.r2.shared.extensions.coerceIn -import org.readium.r2.shared.extensions.requireLengthFitInt +import org.readium.r2.shared.extensions.read +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType public sealed class BaseBytesResource( - public val bytes: suspend () -> Try + override val source: Url?, + private val mediaType: MediaType, + private val properties: Resource.Properties, + protected val bytes: suspend () -> Try ) : Resource { + override suspend fun properties(): ResourceTry = + Try.success(properties) + + override suspend fun mediaType(): ResourceTry = + Try.success(mediaType) + + override suspend fun length(): ResourceTry = + read().map { it.size.toLong() } + private lateinit var _bytes: Try override suspend fun read(range: LongRange?): ResourceTry { - if (!::_bytes.isInitialized) + if (!::_bytes.isInitialized) { _bytes = bytes() + } - if (range == null) + if (range == null) { return _bytes + } return _bytes.map { it.read(range) } } - private fun ByteArray.read(range: LongRange): ByteArray { - @Suppress("NAME_SHADOWING") - val range = range - .coerceIn(0L until size) - .requireLengthFitInt() - - return sliceArray(range.map(Long::toInt)) - } - - override suspend fun length(): ResourceTry = - read().map { it.size.toLong() } - override suspend fun close() {} } /** Creates a Resource serving a [ByteArray]. */ -public class BytesResource(bytes: suspend () -> Try) : BaseBytesResource(bytes) { - - public constructor(bytes: ByteArray) : this({ Try.success(bytes) }) +public class BytesResource( + url: Url? = null, + mediaType: MediaType, + properties: Resource.Properties = Resource.Properties(), + bytes: suspend () -> ResourceTry +) : BaseBytesResource(source = url, mediaType = mediaType, properties = properties, bytes = bytes) { + + public constructor( + bytes: ByteArray, + mediaType: MediaType, + url: Url? = null, + properties: Resource.Properties = Resource.Properties() + ) : + this(url = url, mediaType = mediaType, properties = properties, { Try.success(bytes) }) override fun toString(): String = "${javaClass.simpleName}(${runBlocking { length() }} bytes)" @@ -53,10 +67,24 @@ public class BytesResource(bytes: suspend () -> Try ResourceTry -) : BaseBytesResource({ string().map { it.toByteArray() } }) { - - public constructor(string: String) : this({ Try.success(string) }) +) : BaseBytesResource( + source = url, + mediaType = mediaType, + properties = properties, + { string().map { it.toByteArray() } } +) { + + public constructor( + string: String, + mediaType: MediaType, + url: Url? = null, + properties: Resource.Properties = Resource.Properties() + ) : + this(url = url, mediaType = mediaType, properties = properties, { Try.success(string) }) override fun toString(): String = "${javaClass.simpleName}(${runBlocking { readAsString() }})" diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt index c6efd588d5..255f9d6f35 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Container.kt @@ -6,46 +6,79 @@ package org.readium.r2.shared.resource -import java.io.File import org.readium.r2.shared.util.SuspendingCloseable +import org.readium.r2.shared.util.Url /** - * A resource container as an archive or a directory. + * A container provides access to a list of [Resource] entries. */ public interface Container : SuspendingCloseable { /** - * Holds a container entry's. + * Represents a container entry's. */ public interface Entry : Resource { /** * Absolute path to the entry in the archive. + * * It MUST start with /. */ public val path: String } /** - * Direct file to this container, when available. + * Direct source to this container, when available. */ - public val file: File? get() = null - - /** - * Gets the container name if any. - */ - public suspend fun name(): ResourceTry + public val source: Url? get() = null /** * List of all the container entries of null if such a list is not available. */ - public suspend fun entries(): Iterable? + public suspend fun entries(): Set? /** * Returns the [Entry] at the given [path]. * - * A [Entry] is always returned, since for some cases we can't know if it exists before - * actually fetching it, such as HTTP. Therefore, errors are handled at the Entry level. + * A [Entry] is always returned, since for some cases we can't know if it exists before actually + * fetching it, such as HTTP. Therefore, errors are handled at the Entry level. */ - public suspend fun entry(path: String): Entry + public fun get(path: String): Entry +} + +/** A [Container] providing no resources at all. */ +public class EmptyContainer : Container { + + override suspend fun entries(): Set = emptySet() + + override fun get(path: String): Container.Entry = + FailureResource(Resource.Exception.NotFound()).toEntry(path) + + override suspend fun close() {} } + +/** A [Container] for a single [Resource]. */ +public class ResourceContainer(path: String, resource: Resource) : Container { + + private val entry = resource.toEntry(path) + + override suspend fun entries(): Set = setOf(entry) + + override fun get(path: String): Container.Entry { + if (path.takeWhile { it !in "#?" } != entry.path) { + return FailureResource(Resource.Exception.NotFound()).toEntry(path) + } + + return entry + } + + override suspend fun close() { + entry.close() + } +} + +/** Convenience helper to wrap a [Resource] and a [path] into a [Container.Entry]. */ +internal fun Resource.toEntry(path: String): Container.Entry = + object : Container.Entry, Resource by this { + override val path: String = path + } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt index 1f4bca7c8b..2bdf6bf6e0 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt @@ -8,7 +8,6 @@ package org.readium.r2.shared.resource import android.content.ContentResolver import android.net.Uri -import android.provider.OpenableColumns import java.io.FileNotFoundException import java.io.IOException import java.io.InputStream @@ -17,10 +16,10 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.* -import org.readium.r2.shared.extensions.read -import org.readium.r2.shared.extensions.readFully import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.toUri +import org.readium.r2.shared.util.toUrl /** * Creates [ContentResource]s. @@ -45,33 +44,18 @@ public class ContentResourceFactory( */ public class ContentResource( private val uri: Uri, - private val contentResolver: ContentResolver, + private val contentResolver: ContentResolver ) : Resource { private lateinit var _length: ResourceTry - override suspend fun name(): ResourceTry { - val cursor = contentResolver - .query(uri, null, null, null, null) - ?: return ResourceTry.failure(Resource.Exception.NotFound()) - - @Suppress("Name_shadowing") - cursor.use { cursor -> - if (!cursor.moveToFirst()) { - return ResourceTry.failure(Resource.Exception.NotFound()) - } - val columnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) - .takeUnless { it == -1 } - ?: return Try.success(uri.lastPathSegment) + override val source: Url? = uri.toUrl() - tryOrNull { cursor.getString(columnIndex) } - ?.let { return Try.success(it) } - ?: return Try.success(uri.lastPathSegment) - } - } + override suspend fun properties(): ResourceTry = + ResourceTry.success(Resource.Properties()) - override suspend fun mediaType(): ResourceTry = - Try.success(contentResolver.getType(uri)) + override suspend fun mediaType(): ResourceTry = + Try.success(contentResolver.getType(uri)?.let { MediaType(it) } ?: MediaType.BINARY) override suspend fun close() { } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt index 657f1c092a..e0c2f29d41 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt @@ -13,17 +13,21 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.error.MessageError import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.util.toFile -public class DefaultArchiveFactory : ArchiveFactory { +public class DefaultArchiveFactory( + private val mediaTypeRetriever: MediaTypeRetriever +) : ArchiveFactory { override suspend fun create(resource: Resource, password: String?): Try { if (password != null) { return Try.failure(ArchiveFactory.Error.PasswordsNotSupported()) } - return resource.file + return resource.source?.toFile() ?.let { open(it) } - ?: Try.failure( + ?: Try.Failure( ArchiveFactory.Error.FormatNotSupported( MessageError("Resource not supported because file cannot be directly access.") ) @@ -34,7 +38,7 @@ public class DefaultArchiveFactory : ArchiveFactory { internal suspend fun open(file: File): Try = withContext(Dispatchers.IO) { try { - val archive = JavaZipContainer(ZipFile(file), file) + val archive = JavaZipContainer(ZipFile(file), file, mediaTypeRetriever) Try.success(archive) } catch (e: ZipException) { Try.failure(ArchiveFactory.Error.FormatNotSupported(e)) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt index d39285da35..d1d091c7ae 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt @@ -15,25 +15,19 @@ import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.extensions.isParentOf import org.readium.r2.shared.extensions.tryOr import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * A file system directory as a [Container]. */ internal class DirectoryContainer( private val root: File, - private val entries: List + private val entries: List, + private val mediaTypeRetriever: MediaTypeRetriever ) : Container { - private inner class FailureEntry( - override val path: String - ) : Container.Entry, - Resource by FailureResource( - Resource.Exception.NotFound(Exception("No entry at path $path.")) - ) - - private inner class SuccessEntry( - override val file: File - ) : Container.Entry, Resource by FileResource(file) { + private inner class FileEntry(file: File) : + Container.Entry, Resource by FileResource(file, mediaTypeRetriever) { override val path: String = file.relativeTo(root).path.addPrefix("/") @@ -41,25 +35,25 @@ internal class DirectoryContainer( override suspend fun close() {} } - override suspend fun name(): ResourceTry = - ResourceTry.success(root.name) - - override suspend fun entries(): List = - entries.map { SuccessEntry(it) }.toList() + override suspend fun entries(): Set = + entries.map { FileEntry(it) }.toSet() - override suspend fun entry(path: String): Container.Entry { + override fun get(path: String): Container.Entry { val file = File(root, path.removePrefix("/")) - return if (!root.isParentOf(file)) - FailureEntry(path) - else - SuccessEntry(file) + return if (!root.isParentOf(file)) { + FailureResource(Resource.Exception.NotFound()).toEntry(path) + } else { + FileEntry(file) + } } override suspend fun close() {} } -public class DirectoryContainerFactory : ContainerFactory { +public class DirectoryContainerFactory( + private val mediaTypeRetriever: MediaTypeRetriever +) : ContainerFactory { override suspend fun create(url: Url): Try { if (url.scheme != ContentResolver.SCHEME_FILE) { @@ -88,7 +82,7 @@ public class DirectoryContainerFactory : ContainerFactory { return Try.failure(ContainerFactory.Error.Forbidden(e)) } - val container = DirectoryContainer(file, entries) + val container = DirectoryContainer(file, entries, mediaTypeRetriever) return Try.success(container) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt index bb387e964e..f759bfdb18 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt @@ -26,7 +26,10 @@ public fun interface ResourceFactory { override val cause: org.readium.r2.shared.error.Error? = null ) : Error() { - public constructor(scheme: String, exception: Exception) : this(scheme, ThrowableError(exception)) + public constructor(scheme: String, exception: Exception) : this( + scheme, + ThrowableError(exception) + ) override val message: String = "Url scheme $scheme is not supported." @@ -37,7 +40,10 @@ public fun interface ResourceFactory { override val cause: org.readium.r2.shared.error.Error? = null ) : Error() { - public constructor(url: Url, exception: Exception) : this(url, ThrowableError(exception)) + public constructor(url: Url, exception: Exception) : this( + url, + ThrowableError(exception) + ) override val message: String = "No resource found at url $url." @@ -72,7 +78,10 @@ public fun interface ContainerFactory { override val cause: org.readium.r2.shared.error.Error? = null ) : Error() { - public constructor(scheme: String, exception: Exception) : this(scheme, ThrowableError(exception)) + public constructor(scheme: String, exception: Exception) : this( + scheme, + ThrowableError(exception) + ) override val message: String = "Url scheme $scheme is not supported." @@ -83,7 +92,10 @@ public fun interface ContainerFactory { override val cause: org.readium.r2.shared.error.Error? = null ) : Error() { - public constructor(url: Url, exception: Exception) : this(url, ThrowableError(exception)) + public constructor(url: Url, exception: Exception) : this( + url, + ThrowableError(exception) + ) override val message: String = "No container found at url $url." @@ -137,7 +149,10 @@ public fun interface ArchiveFactory { public val resourceException: Resource.Exception ) : Error() { - public constructor(exception: Resource.Exception) : this(ThrowableError(exception), exception) + public constructor(exception: Resource.Exception) : this( + ThrowableError(exception), + exception + ) override val message: String = "An error occurred while attempting to read the resource." @@ -159,10 +174,11 @@ public class CompositeArchiveFactory( override suspend fun create(resource: Resource, password: String?): Try { return primaryFactory.create(resource, password) .tryRecover { error -> - if (error is ArchiveFactory.Error.FormatNotSupported) + if (error is ArchiveFactory.Error.FormatNotSupported) { fallbackFactory.create(resource, password) - else + } else { Try.failure(error) + } } } } @@ -179,10 +195,11 @@ public class CompositeResourceFactory( override suspend fun create(url: Url): Try { return primaryFactory.create(url) .tryRecover { error -> - if (error is ResourceFactory.Error.SchemeNotSupported) + if (error is ResourceFactory.Error.SchemeNotSupported) { fallbackFactory.create(url) - else + } else { Try.failure(error) + } } } } @@ -199,10 +216,11 @@ public class CompositeContainerFactory( override suspend fun create(url: Url): Try { return primaryFactory.create(url) .tryRecover { error -> - if (error is ContainerFactory.Error.SchemeNotSupported) + if (error is ContainerFactory.Error.SchemeNotSupported) { fallbackFactory.create(url) - else + } else { Try.failure(error) + } } } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/FallbackResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/FallbackResource.kt new file mode 100644 index 0000000000..b233ff9ec6 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/FallbackResource.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * Resource that will act as a proxy to a fallback resource if the [originalResource] errors out. + */ +public class FallbackResource( + private val originalResource: Resource, + private val fallbackResourceFactory: (Resource.Exception) -> Resource? +) : Resource { + + override val source: Url? = null + + override suspend fun mediaType(): ResourceTry = + withResource { mediaType() } + + override suspend fun properties(): ResourceTry = + withResource { properties() } + + override suspend fun length(): ResourceTry = + withResource { length() } + + override suspend fun read(range: LongRange?): ResourceTry = + withResource { read(range) } + + override suspend fun close() { + if (::_resource.isInitialized) { + _resource.close() + } + } + + private lateinit var _resource: Resource + + private suspend fun withResource(action: suspend Resource.() -> ResourceTry): ResourceTry { + if (::_resource.isInitialized) { + return _resource.action() + } + + var resource = originalResource + + var result = resource.action() + result.onFailure { error -> + fallbackResourceFactory(error)?.let { fallbackResource -> + resource = fallbackResource + result = resource.action() + } + } + + _resource = resource + return result + } +} + +/** + * Falls back to alternative resources when the receiver fails. + */ +public fun Resource.fallback( + fallbackResourceFactory: (Resource.Exception) -> Resource? +): Resource = + FallbackResource(this, fallbackResourceFactory) + +/** + * Falls back to the given alternative [Resource] when the receiver fails. + */ +public fun Resource.fallback(fallbackResource: Resource): Resource = + FallbackResource(this) { fallbackResource } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt index 88b4935c36..76e8e5f270 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt @@ -6,6 +6,7 @@ package org.readium.r2.shared.resource +import java.io.File import java.io.FileNotFoundException import java.io.IOException import java.nio.channels.Channels @@ -14,17 +15,22 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.* -import org.readium.r2.shared.extensions.read -import org.readium.r2.shared.extensions.readFully +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType internal class FileChannelResource( + override val source: Url?, + private val file: File?, private val channel: FileChannel ) : Resource { private lateinit var _length: ResourceTry - override suspend fun name(): ResourceTry = - ResourceTry.success(null) + override suspend fun mediaType(): ResourceTry = + ResourceTry.success(MediaType.BINARY) + + override suspend fun properties(): ResourceTry = + ResourceTry.success(Resource.Properties()) override suspend fun close() { withContext(Dispatchers.IO) { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt index f0cb278714..f9b500b4b7 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt @@ -6,7 +6,6 @@ package org.readium.r2.shared.resource -import android.content.ContentResolver import java.io.File import java.io.FileNotFoundException import java.io.RandomAccessFile @@ -16,14 +15,29 @@ import kotlinx.coroutines.withContext import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.* -import org.readium.r2.shared.extensions.read import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.isFile import org.readium.r2.shared.util.isLazyInitialized +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeHints +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * A [Resource] to access a [file]. */ -public class FileResource(override val file: File) : Resource { +public class FileResource private constructor( + private val file: File, + private val mediaType: MediaType?, + private val mediaTypeRetriever: MediaTypeRetriever? +) : Resource { + + public constructor(file: File, mediaType: MediaType) : this(file, mediaType, null) + + public constructor(file: File, mediaTypeRetriever: MediaTypeRetriever) : this( + file, + null, + mediaTypeRetriever + ) private val randomAccessFile by lazy { ResourceTry.catching { @@ -31,8 +45,19 @@ public class FileResource(override val file: File) : Resource { } } - override suspend fun name(): ResourceTry = - ResourceTry.success(file.name) + override val source: Url? = Url("file://${file.path}") + + override suspend fun properties(): ResourceTry = + ResourceTry.success(Resource.Properties()) + + override suspend fun mediaType(): ResourceTry = Try.success( + mediaType + ?: mediaTypeRetriever?.retrieve( + hints = MediaTypeHints(fileExtension = file.extension), + content = ResourceMediaTypeSnifferContent(this) + ) + ?: MediaType.BINARY + ) override suspend fun close() { withContext(Dispatchers.IO) { @@ -83,10 +108,11 @@ public class FileResource(override val file: File) : Resource { private val metadataLength: Long? = tryOrNull { - if (file.isFile) + if (file.isFile) { file.length() - else + } else { null + } } private inline fun Try.Companion.catching(closure: () -> T): ResourceTry = @@ -106,10 +132,12 @@ public class FileResource(override val file: File) : Resource { "${javaClass.simpleName}(${file.path})" } -public class FileResourceFactory : ResourceFactory { +public class FileResourceFactory( + private val mediaTypeRetriever: MediaTypeRetriever +) : ResourceFactory { override suspend fun create(url: Url): Try { - if (url.scheme != ContentResolver.SCHEME_FILE) { + if (!url.isFile()) { return Try.failure(ResourceFactory.Error.SchemeNotSupported(url.scheme)) } @@ -123,6 +151,6 @@ public class FileResourceFactory : ResourceFactory { return Try.failure(ResourceFactory.Error.Forbidden(e)) } - return Try.success(FileResource(file)) + return Try.success(FileResource(file, mediaTypeRetriever)) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/LazyResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/LazyResource.kt new file mode 100644 index 0000000000..68f0626f2a --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/LazyResource.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * Wraps a [Resource] which will be created only when first accessing one of its members. + */ +public open class LazyResource( + override val source: Url? = null, + private val factory: suspend () -> R +) : Resource { + + private lateinit var _resource: R + + protected suspend fun resource(): R { + if (!::_resource.isInitialized) { + _resource = factory() + } + + return _resource + } + + override suspend fun mediaType(): ResourceTry = + resource().mediaType() + + override suspend fun properties(): ResourceTry = + resource().properties() + + override suspend fun length(): ResourceTry = + resource().length() + + override suspend fun read(range: LongRange?): ResourceTry = + resource().read(range) + + override suspend fun close() { + if (::_resource.isInitialized) { + _resource.close() + } + } + + override fun toString(): String = + if (::_resource.isInitialized) { + "${javaClass.simpleName}($_resource)" + } else { + "${javaClass.simpleName}(...)" + } +} + +public fun Resource.flatMap(transform: suspend (Resource) -> R): LazyResource = + LazyResource { transform(this) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/MediaTypeExt.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/MediaTypeExt.kt new file mode 100644 index 0000000000..91922234d7 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/MediaTypeExt.kt @@ -0,0 +1,23 @@ +package org.readium.r2.shared.resource + +import org.readium.r2.shared.util.mediatype.ContainerMediaTypeSnifferContent +import org.readium.r2.shared.util.mediatype.ResourceMediaTypeSnifferContent + +public class ResourceMediaTypeSnifferContent( + private val resource: Resource +) : ResourceMediaTypeSnifferContent { + + override suspend fun read(range: LongRange?): ByteArray? = + resource.read(range).getOrNull() +} + +public class ContainerMediaTypeSnifferContent( + private val container: Container +) : ContainerMediaTypeSnifferContent { + + override suspend fun entries(): Set? = + container.entries()?.map { it.path }?.toSet() + + override suspend fun read(path: String, range: LongRange?): ByteArray? = + container.get(path).read(range).getOrNull() +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt index 35a8fbd590..ea5515dccb 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt @@ -10,7 +10,6 @@ import android.graphics.Bitmap import android.graphics.BitmapFactory import androidx.annotation.StringRes import java.io.ByteArrayInputStream -import java.io.File import java.nio.charset.Charset import org.json.JSONObject import org.readium.r2.shared.R @@ -20,6 +19,8 @@ import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.parser.xml.XmlParser import org.readium.r2.shared.util.SuspendingCloseable +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType public typealias ResourceTry = Try @@ -29,24 +30,37 @@ public typealias ResourceTry = Try public interface Resource : SuspendingCloseable { /** - * Direct file to this resource, when available. - * - * This is meant to be used as an optimization for consumers which can't work efficiently - * with streams. However, [file] is not guaranteed to be set, for example if the resource - * underwent transformations or is being read from an archive. Therefore, consumers should - * always fallback on regular stream reading, using [read] or [ResourceInputStream]. + * URL locating this resource, if any. */ - public val file: File? get() = null + public val source: Url? /** * Returns the resource media type if known. */ - public suspend fun mediaType(): ResourceTry = ResourceTry.success(null) + public suspend fun mediaType(): ResourceTry /** - * Returns the name of the resource if any. + * Properties associated to the resource. + * + * This is opened for extensions. */ - public suspend fun name(): ResourceTry = ResourceTry.success(null) + public suspend fun properties(): ResourceTry + + public class Properties( + properties: Map = emptyMap() + ) : Map by properties { + + public companion object { + public inline operator fun invoke(build: Builder.() -> Unit): Properties = + Properties(Builder().apply(build)) + } + + public inline fun copy(build: Builder.() -> Unit): Properties = + Properties(Builder(this).apply(build)) + + public class Builder(properties: Map = emptyMap()) : + MutableMap by properties.toMutableMap() + } /** * Returns data length from metadata if available, or calculated from reading the bytes otherwise. @@ -67,7 +81,10 @@ public interface Resource : SuspendingCloseable { /** * Errors occurring while accessing a resource. */ - public sealed class Exception(@StringRes userMessageId: Int, cause: Throwable? = null) : UserException(userMessageId, cause = cause) { + public sealed class Exception(@StringRes userMessageId: Int, cause: Throwable? = null) : UserException( + userMessageId, + cause = cause + ) { /** Equivalent to a 400 HTTP error. */ public class BadRequest( @@ -112,7 +129,10 @@ public interface Resource : SuspendingCloseable { Exception(R.string.readium_shared_resource_exception_out_of_memory) /** For any other error, such as HTTP 500. */ - public class Other(cause: Throwable) : Exception(R.string.readium_shared_resource_exception_other, cause) + public class Other(cause: Throwable) : Exception( + R.string.readium_shared_resource_exception_other, + cause + ) public companion object { @@ -127,14 +147,17 @@ public interface Resource : SuspendingCloseable { } /** Creates a Resource that will always return the given [error]. */ -public class FailureResource(private val error: Resource.Exception) : Resource { +public class FailureResource( + private val error: Resource.Exception +) : Resource { internal constructor(cause: Throwable) : this(Resource.Exception.wrap(cause)) - override suspend fun read(range: LongRange?): ResourceTry = Try.failure(error) - + override val source: Url? = null + override suspend fun mediaType(): ResourceTry = Try.failure(error) + override suspend fun properties(): ResourceTry = Try.failure(error) override suspend fun length(): ResourceTry = Try.failure(error) - + override suspend fun read(range: LongRange?): ResourceTry = Try.failure(error) override suspend fun close() {} override fun toString(): String = diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt index 51b45148ab..8b2ceb014b 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt @@ -31,9 +31,9 @@ public class ResourceInputStream( throw IOException("Can't get resource length", e) } - if (range == null) + if (range == null) { resourceLength - else { + } else { kotlin.math.min(resourceLength, range.last + 1) } } @@ -127,8 +127,9 @@ public class ResourceInputStream( */ override fun close() { synchronized(this) { - if (isClosed) + if (isClosed) { return + } isClosed = true runBlocking { resource.close() } @@ -136,7 +137,8 @@ public class ResourceInputStream( } private fun checkNotClosed() { - if (isClosed) + if (isClosed) { throw IOException("InputStream is closed.") + } } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/RoutingContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/RoutingContainer.kt new file mode 100644 index 0000000000..df32dc7f2d --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/RoutingContainer.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.isHttp + +/** + * Routes requests to child containers, depending on a provided predicate. + * + * This can be used for example to serve a publication containing both local and remote resources, + * and more generally to concatenate different content sources. + * + * The [routes] will be tested in the given order. + */ +public class RoutingContainer(private val routes: List) : Container { + + /** + * Holds a child fetcher and the predicate used to determine if it can answer a request. + * + * The default value for [accepts] means that the fetcher will accept any link. + */ + public class Route( + public val container: Container, + public val accepts: (String) -> Boolean = { true } + ) + + public constructor(local: Container, remote: Container) : + this( + listOf( + Route(local, accepts = ::isLocal), + Route(remote) + ) + ) + + override suspend fun entries(): Set? = + null // We can't guarantee the list of entries is exhaustive, so we return null + + override fun get(path: String): Container.Entry = + routes.firstOrNull { it.accepts(path) }?.container?.get(path) + ?: FailureResource(Resource.Exception.NotFound()).toEntry(path) + + override suspend fun close() { + routes.forEach { it.container.close() } + } +} + +private fun isLocal(path: String): Boolean { + val url = Url(path) ?: return true + return !url.isHttp() +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/SynchronizedResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/SynchronizedResource.kt new file mode 100644 index 0000000000..31d1f473c8 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/SynchronizedResource.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * Protects the access to a wrapped resource with a mutex to make it thread-safe. + */ +public class SynchronizedResource( + private val resource: Resource +) : Resource { + + // This doesn't use `Resource by resource` to avoid forgetting the synchronization for a future API. + + private val mutex = Mutex() + + override val source: Url? get() = resource.source + + override suspend fun properties(): ResourceTry = + mutex.withLock { resource.properties() } + + override suspend fun mediaType(): ResourceTry = + mutex.withLock { resource.mediaType() } + + override suspend fun length(): ResourceTry = + mutex.withLock { resource.length() } + + override suspend fun read(range: LongRange?): ResourceTry = + mutex.withLock { resource.read(range) } + + override suspend fun close() { + mutex.withLock { resource.close() } + } + + override fun toString(): String = + "${javaClass.simpleName}($resource)" +} + +/** + * Wraps this resource in a [SynchronizedResource] to protect the access from multiple threads. + */ +public fun Resource.synchronized(): SynchronizedResource = + SynchronizedResource(this) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingContainer.kt new file mode 100644 index 0000000000..7e836c5e96 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingContainer.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +/** + * Implements the transformation of a Resource. It can be used, for example, to decrypt, + * deobfuscate, inject CSS or JavaScript, correct content – e.g. adding a missing dir="rtl" in an + * HTML document, pre-process – e.g. before indexing a publication's content, etc. + * + * If the transformation doesn't apply, simply return the resource unchanged. + */ +public typealias ResourceTransformer = (Resource) -> Resource + +/** + * Transforms the resources' content of a child fetcher using a list of [ResourceTransformer] + * functions. + */ +public class TransformingContainer( + private val container: Container, + private val transformers: List +) : Container { + + public constructor(fetcher: Container, transformer: ResourceTransformer) : + this(fetcher, listOf(transformer)) + + override suspend fun entries(): Set? = + container.entries() + + override fun get(path: String): Container.Entry = + transformers + .fold(container.get(path) as Resource) { acc, transformer -> + transformer(acc) + } + .toEntry(path) + + override suspend fun close() { + container.close() + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt new file mode 100644 index 0000000000..a7a055aba4 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.resource + +import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.extensions.coerceIn +import org.readium.r2.shared.extensions.requireLengthFitInt +import org.readium.r2.shared.util.Url + +/** + * Transforms the bytes of [resource] on-the-fly. + * + * If you set [cacheBytes] to false, consider providing your own implementation of [length] to avoid + * unnecessary transformations. + * + * Warning: The transformation runs on the full content of [resource], so it's not appropriate for + * large resources which can't be held in memory. + */ +public abstract class TransformingResource( + private val resource: Resource, + private val cacheBytes: Boolean = true +) : Resource by resource { + + public companion object { + /** + * Creates a [TransformingResource] using the given [transform] function. + */ + public operator fun invoke( + resource: Resource, + transform: suspend (ByteArray) -> ResourceTry + ): TransformingResource = + object : TransformingResource(resource) { + override suspend fun transform(data: ResourceTry): ResourceTry = + data.flatMap { transform(it) } + } + } + + override val source: Url? = null + + private lateinit var _bytes: ResourceTry + + public abstract suspend fun transform(data: ResourceTry): ResourceTry + + private suspend fun bytes(): ResourceTry { + if (::_bytes.isInitialized) { + return _bytes + } + + val bytes = transform(resource.read()) + if (cacheBytes) { + _bytes = bytes + } + + return bytes + } + + override suspend fun read(range: LongRange?): ResourceTry = + bytes().map { + if (range == null) { + return bytes() + } + + @Suppress("NAME_SHADOWING") + val range = range + .coerceIn(0L until it.size) + .requireLengthFitInt() + + it.sliceArray(range.map(Long::toInt)) + } + + override suspend fun length(): ResourceTry = bytes().map { it.size.toLong() } +} + +public fun Resource.map(transform: suspend (ByteArray) -> ResourceTry): Resource = + TransformingResource(this, transform = transform) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt index 3c29f8cd53..665f449976 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt @@ -12,33 +12,94 @@ import java.util.zip.ZipEntry import java.util.zip.ZipFile import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.json.JSONObject +import org.readium.r2.shared.JSONable import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.extensions.addPrefix +import org.readium.r2.shared.extensions.optNullableBoolean +import org.readium.r2.shared.extensions.optNullableLong import org.readium.r2.shared.extensions.readFully +import org.readium.r2.shared.extensions.toMap import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.io.CountingInputStream +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeHints +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.util.toUrl /** - * A [Container] representing a Zip archive. + * Holds information about how the resource is stored in the archive. + * + * @param entryLength The length of the entry stored in the archive. It might be a compressed length + * if the entry is deflated. + * @param isEntryCompressed Indicates whether the entry was compressed before being stored in the + * archive. */ -public interface ZipContainer : Container { +public data class ArchiveProperties( + val entryLength: Long, + val isEntryCompressed: Boolean +) : JSONable { + + override fun toJSON(): JSONObject = JSONObject().apply { + put("entryLength", entryLength) + put("isEntryCompressed", isEntryCompressed) + } - public interface Entry : Container.Entry { + public companion object { + public fun fromJSON(json: JSONObject?): ArchiveProperties? { + json ?: return null - /** - * Compressed data length. - */ - public val compressedLength: Long? + val entryLength = json.optNullableLong("entryLength") + val isEntryCompressed = json.optNullableBoolean("isEntryCompressed") + if (entryLength == null || isEntryCompressed == null) { + return null + } + return ArchiveProperties( + entryLength = entryLength, + isEntryCompressed = isEntryCompressed + ) + } } } -internal class JavaZipContainer(private val archive: ZipFile, source: File) : ZipContainer { +private const val archiveKey = "archive" + +public val Resource.Properties.archive: ArchiveProperties? + get() = (this[archiveKey] as? Map<*, *>) + ?.let { ArchiveProperties.fromJSON(JSONObject(it)) } - private inner class FailureEntry(override val path: String) : ZipContainer.Entry { +public var Resource.Properties.Builder.archive: ArchiveProperties? + get() = (this[archiveKey] as? Map<*, *>) + ?.let { ArchiveProperties.fromJSON(JSONObject(it)) } + set(value) { + if (value == null) { + remove(archiveKey) + } else { + put(archiveKey, value.toJSON().toMap()) + } + } - override val compressedLength: Long? = null +internal class JavaZipContainer( + private val archive: ZipFile, + file: File, + private val mediaTypeRetriever: MediaTypeRetriever +) : Container { - override suspend fun name(): ResourceTry = + private inner class FailureEntry(override val path: String) : Container.Entry { + + override val source: Url? = null + + override suspend fun mediaType(): ResourceTry = + Try.success( + mediaTypeRetriever.retrieve( + hints = MediaTypeHints(fileExtension = File(path).extension), + content = ResourceMediaTypeSnifferContent(this) + ) ?: MediaType.BINARY + ) + + override suspend fun properties(): ResourceTry = Try.failure(Resource.Exception.NotFound()) override suspend fun length(): ResourceTry = @@ -51,33 +112,53 @@ internal class JavaZipContainer(private val archive: ZipFile, source: File) : Zi } } - private inner class Entry(private val entry: ZipEntry) : ZipContainer.Entry { + private inner class Entry(private val entry: ZipEntry) : Container.Entry { override val path: String = entry.name.addPrefix("/") - override suspend fun name(): ResourceTry = - ResourceTry.success(File(path).name) + override val source: Url? = null + + override suspend fun mediaType(): ResourceTry = + Try.success( + mediaTypeRetriever.retrieve( + hints = MediaTypeHints(fileExtension = File(path).extension), + content = ResourceMediaTypeSnifferContent(this) + ) ?: MediaType.BINARY + ) + + override suspend fun properties(): ResourceTry = + ResourceTry.success( + Resource.Properties { + archive = ArchiveProperties( + entryLength = compressedLength + ?: length().getOrElse { return ResourceTry.failure(it) }, + isEntryCompressed = compressedLength != null + ) + } + ) override suspend fun length(): Try = entry.size.takeUnless { it == -1L } ?.let { Try.success(it) } ?: Try.failure(Resource.Exception.Other(Exception("Unsupported operation"))) - override val compressedLength: Long? = - if (entry.method == ZipEntry.STORED || entry.method == -1) + private val compressedLength: Long? = + if (entry.method == ZipEntry.STORED || entry.method == -1) { null - else + } else { entry.compressedSize.takeUnless { it == -1L } + } override suspend fun read(range: LongRange?): Try = try { withContext(Dispatchers.IO) { val bytes = - if (range == null) + if (range == null) { readFully() - else + } else { readRange(range) + } Try.success(bytes) } } catch (e: IOException) { @@ -128,21 +209,18 @@ internal class JavaZipContainer(private val archive: ZipFile, source: File) : Zi } } - override val file: File = source - - override suspend fun name(): ResourceTry = - ResourceTry.success(file.name) + override val source: Url = file.toUrl() - override suspend fun entries(): List = + override suspend fun entries(): Set = archive.entries().toList() .filterNot { it.isDirectory } .mapNotNull { Entry(it) } + .toSet() - override suspend fun entry(path: String): Container.Entry { - return archive.getEntry(path.removePrefix("/")) + override fun get(path: String): Container.Entry = + archive.getEntry(path.removePrefix("/")) ?.let { Entry(it) } ?: FailureEntry(path) - } override suspend fun close() { tryOrLog { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceContentExtractor.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/content/ResourceContentExtractor.kt similarity index 73% rename from readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceContentExtractor.kt rename to readium/shared/src/main/java/org/readium/r2/shared/resource/content/ResourceContentExtractor.kt index 2127d82ebc..f6d811b057 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/fetcher/ResourceContentExtractor.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/content/ResourceContentExtractor.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.shared.fetcher +package org.readium.r2.shared.resource.content import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -12,7 +12,9 @@ import org.jsoup.Jsoup import org.jsoup.parser.Parser import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.error.Try +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.mapCatching import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.mediatype.MediaType @@ -25,7 +27,7 @@ public interface ResourceContentExtractor { /** * Extracts the text content of the given [resource]. */ - public suspend fun extractText(resource: Fetcher.Resource): ResourceTry = Try.success("") + public suspend fun extractText(resource: Resource): ResourceTry = Try.success("") public interface Factory { /** @@ -33,15 +35,15 @@ public interface ResourceContentExtractor { * * Return null if the resource format is not supported. */ - public suspend fun createExtractor(resource: Fetcher.Resource): ResourceContentExtractor? + public suspend fun createExtractor(resource: Resource): ResourceContentExtractor? } } @ExperimentalReadiumApi public class DefaultResourceContentExtractorFactory : ResourceContentExtractor.Factory { - override suspend fun createExtractor(resource: Fetcher.Resource): ResourceContentExtractor? = - when (resource.link().mediaType) { + override suspend fun createExtractor(resource: Resource): ResourceContentExtractor? = + when (resource.mediaType().getOrNull()) { MediaType.HTML, MediaType.XHTML -> HtmlResourceContentExtractor() else -> null } @@ -53,7 +55,9 @@ public class DefaultResourceContentExtractorFactory : ResourceContentExtractor.F @ExperimentalReadiumApi public class HtmlResourceContentExtractor : ResourceContentExtractor { - override suspend fun extractText(resource: Fetcher.Resource): ResourceTry = withContext(Dispatchers.IO) { + override suspend fun extractText(resource: Resource): ResourceTry = withContext( + Dispatchers.IO + ) { resource.readAsString().mapCatching { html -> val body = Jsoup.parse(html).body().text() // Transform HTML entities into their actual characters. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Closeable.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Closeable.kt index 01bc8566dc..1e91b3892d 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Closeable.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Closeable.kt @@ -41,13 +41,14 @@ public suspend inline fun T.use(block: (T) -> R): exception = e throw e } finally { - if (exception == null) + if (exception == null) { this?.close() - else + } else { try { this?.close() } catch (closeException: Throwable) { exception.addSuppressed(closeException) } + } } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt index 19726b7d56..19150d9244 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/CursorList.kt @@ -36,8 +36,9 @@ public class CursorList( * Moves the cursor backward and returns the element, or null when reaching the beginning. */ public fun previous(): E? { - if (!hasPrevious()) + if (!hasPrevious()) { return null + } index-- return list[index] @@ -51,8 +52,9 @@ public class CursorList( * Moves the cursor forward and returns the element, or null when reaching the end. */ public fun next(): E? { - if (!hasNext()) + if (!hasNext()) { return null + } index++ return list[index] diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt index 66ef1b0c62..9f60ac91af 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt @@ -15,6 +15,10 @@ import org.readium.r2.shared.error.Try * if this instance represents failure or the original encapsulated value if it is success. */ @Suppress("Unused_parameter") -@Deprecated(message = "Use getOrElse instead.", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("getOrElse")) +@Deprecated( + message = "Use getOrElse instead.", + level = DeprecationLevel.ERROR, + replaceWith = ReplaceWith("getOrElse") +) public inline fun Try.recover(transform: (exception: F) -> R): Try = TODO() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Either.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Either.kt index df1eed3d27..8d2eed5693 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Either.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Either.kt @@ -18,7 +18,9 @@ public sealed class Either { when (value) { is A -> Left(value) is B -> Right(value) - else -> throw IllegalArgumentException("Provided value must be an instance of ${A::class.simpleName} or ${B::class.simpleName}") + else -> throw IllegalArgumentException( + "Provided value must be an instance of ${A::class.simpleName} or ${B::class.simpleName}" + ) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Href.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Href.kt index 42202a374f..e897a824f0 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Href.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Href.kt @@ -8,7 +8,7 @@ package org.readium.r2.shared.util import android.net.Uri import android.net.UrlQuerySanitizer -import android.webkit.URLUtil +import java.io.File import java.net.IDN import java.net.URI import java.net.URL @@ -16,70 +16,120 @@ import org.readium.r2.shared.extensions.addPrefix import timber.log.Timber /** - * Represents an HREF, optionally relative to another one. - * - * This is used to normalize the string representation. + * Represents an HREF in its absolute percent-decoded form. */ -public class Href( - private val href: String, - baseHref: String = "/" +@JvmInline +public value class Href private constructor( + public val string: String ) { - public data class QueryParameter(val name: String, val value: String?) - - private val baseHref = if (baseHref.isEmpty()) "/" else baseHref - - /** Returns the normalized string representation for this HREF. */ - public val string: String get() { - val baseHref = baseHref.removePercentEncoding() - val href = href.removePercentEncoding() - - // HREF is just an anchor inside the base. - if (href.isBlank() || href.startsWith("#")) { - return baseHref + href - } - - // HREF is already absolute. - if (Uri.parse(href).isAbsolute) { - return href + public companion object { + + /** + * Builds an HREF, which can be relative to a [baseHref]. + * + * @param href The HREF string, which can be absolute or relative. + * @param baseHref The base HREF to use when the [href] is relative. + */ + public operator fun invoke(href: String, baseHref: String? = null): Href { + @Suppress("Name_Shadowing") + val baseHref: String = (baseHref?.takeUnless { it.isBlank() } ?: "/") + .removePercentEncoding() + + @Suppress("Name_Shadowing") + val href = href.removePercentEncoding() + + // HREF is just an anchor inside the base. + if (href.isBlank() || href.startsWith("#")) { + return Href(baseHref + href) + } + + // HREF is already absolute. + if (Uri.parse(href).isAbsolute) { + return Href(href) + } + + // Isolates the path from the anchor/query portion, which would be lost otherwise. + val splitIndex = href.indexOf("?").takeIf { it != -1 } + ?: href.indexOf("#").takeIf { it != -1 } + ?: (href.lastIndex + 1) + + return try { + val baseUri = URI.create(baseHref.percentEncodedPath()) + if (baseUri.scheme?.lowercase() == "file") { + return if (href.startsWith("/")) { + Href("file://$href") + } else { + Href("file://" + File(baseUri.path, href).canonicalPath) + } + } + + val path = href.substring(0, splitIndex) + val suffix = href.substring(splitIndex) + val uri = baseUri.resolve(path.percentEncodedPath()) + val url = (if (uri.scheme != null) uri.toString() else uri.path.addPrefix("/")) + suffix + return Href(url.removePercentEncoding()) + } catch (e: Exception) { + Timber.e(e) + Href("$baseHref/$href") + } } - // Isolates the path from the anchor/query portion, which would be lost otherwise. - val splitIndex = href.indexOf("?").takeIf { it != -1 } - ?: href.indexOf("#").takeIf { it != -1 } - ?: (href.lastIndex + 1) + private fun String.removePercentEncoding(): String = + Uri.decode(this) + // If the string contains invalid percent-encoded characters, assumes that it is already + // percent-decoded. For example, if the string contains a standalone % character. + .takeIf { !it.contains("\uFFFD") } ?: this + + /** + * Percent-encodes an URL path section. + * + * Equivalent to Swift's `string.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)` + */ + private fun String.percentEncodedPath(): String = + Uri.encode(this, "$&+,/:=@") + } - val path = href.substring(0, splitIndex) - val suffix = href.substring(splitIndex) + public data class QueryParameter(val name: String, val value: String?) - return try { - val uri = URI.create(baseHref.percentEncodedPath()).resolve(path.percentEncodedPath()) - val url = (if (URLUtil.isNetworkUrl(uri.toString())) uri.toString() else uri.path.addPrefix("/")) + suffix - return url.removePercentEncoding() - } catch (e: Exception) { - Timber.e(e) - "$baseHref/$href" - } - } + /** + * Percent-encode the HREF to use in an URL. + */ + public val percentEncodedString: String get() = + percentEncode(string) /** - * Returns the normalized string representation for this HREF, encoded for URL uses. + * Returns the normalized string representation for [href], encoded for URL uses. * * Taken from https://stackoverflow.com/a/49796882/1474476 */ - public val percentEncodedString: String get() { - var string = string - if (string.startsWith("/")) { - string = string.addPrefix("file://") + private fun percentEncode(href: String): String { + @Suppress("NAME_SHADOWING") + var href = href + val hasScheme = !href.startsWith("/") + if (!hasScheme) { + href = href.addPrefix("file://") } return try { - val url = URL(string) - val uri = URI(url.protocol, url.userInfo, IDN.toASCII(url.host), url.port, url.path, url.query, url.ref) - uri.toASCIIString().removePrefix("file://") + val url = URL(href) + val uri = URI( + url.protocol, + url.userInfo, + IDN.toASCII(url.host), + url.port, + url.path, + url.query, + url.ref + ) + var result = uri.toASCIIString() + if (!hasScheme) { + result = result.removePrefix("file://") + } + return result } catch (e: Exception) { Timber.e(e) - this.string + href } } @@ -87,25 +137,19 @@ public class Href( public val queryParameters: List get() { val url = percentEncodedString.substringBefore("#") return UrlQuerySanitizer(url).parameterList - .map { p -> QueryParameter(name = p.mParameter, value = p.mValue.takeUnless { it.isBlank() }) } + .map { p -> + QueryParameter( + name = p.mParameter, + value = p.mValue.takeUnless { it.isBlank() } + ) + } } - /** - * Percent-encodes an URL path section. - * - * Equivalent to Swift's `string.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)` - */ - private fun String.percentEncodedPath(): String = - Uri.encode(this, "$&+,/:=@") - /** * Expands percent-encoded characters. */ - private fun String.removePercentEncoding(): String = - Uri.decode(this) - // If the string contains invalid percent-encoded characters, assumes that it is already - // percent-decoded. For example, if the string contains a standalone % character. - .takeIf { !it.contains("\uFFFD") } ?: this + public fun toUrl(): Url? = + Url(percentEncodedString) } public fun List.firstNamedOrNull(name: String): String? = diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Language.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Language.kt index 543cc93c34..9b351dd7d9 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Language.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Language.kt @@ -58,7 +58,10 @@ public class Language(code: String) { code.hashCode() internal object Serializer : KSerializer { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Language", PrimitiveKind.STRING) + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor( + "Language", + PrimitiveKind.STRING + ) override fun serialize(encoder: Encoder, value: Language) { encoder.encodeString(value.code) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt index 008253d883..5d0e13d260 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt @@ -49,14 +49,20 @@ public open class MapCompanion(protected val map: Map) { */ public open operator fun invoke(key: K?): E? = get(key) - @Deprecated("Use `Enum(\"value\")` instead", ReplaceWith("get(key)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `Enum(\"value\")` instead", + ReplaceWith("get(key)"), + level = DeprecationLevel.ERROR + ) public open fun from(key: K?): E? = get(key) } /** * Extends a [MapCompanion] by adding a [default] value as a fallback. */ -public open class MapWithDefaultCompanion(map: Map, public val default: E) : MapCompanion(map) { +public open class MapWithDefaultCompanion(map: Map, public val default: E) : MapCompanion( + map +) { public constructor(elements: Array, keySelector: (E) -> K, default: E) : this(elements.associateBy(keySelector), default) @@ -72,6 +78,10 @@ public open class MapWithDefaultCompanion(map: Map, public val defau */ override operator fun invoke(key: K?): E = getOrDefault(key) - @Deprecated("Use `Enum(\"value\")` instead", ReplaceWith("getOrDefault(key)"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use `Enum(\"value\")` instead", + ReplaceWith("getOrDefault(key)"), + level = DeprecationLevel.ERROR + ) override fun from(key: K?): E? = getOrDefault(key) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/URITemplate.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/URITemplate.kt index f1440b7012..251ecfc575 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/URITemplate.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/URITemplate.kt @@ -36,11 +36,11 @@ public data class URITemplate(val uri: String) { * Expands the HREF by replacing URI template variables by the given parameters. */ public fun expand(parameters: Map): String { - @Suppress("NAME_SHADOWING") // `+` is considered like an encoded space, and will not be properly encoded in parameters. // This is an issue for ISO 8601 date for example. // As a workaround, we encode manually this character. We don't do it in the full URI, // because it could contain some legitimate +-as-space characters. + @Suppress("NAME_SHADOWING") val parameters = parameters.mapValues { it.value.replace("+", "~~+~~") } @@ -54,10 +54,11 @@ public data class URITemplate(val uri: String) { // Escaping the last } is somehow required, otherwise the regex can't be parsed on a Pixel // 3a. However, without it works with the unit tests. val expanded = "\\{(\\??)([^}]+)\\}".toRegex().replace(uri) { - if (it.groupValues[1].isEmpty()) + if (it.groupValues[1].isEmpty()) { expandSimpleString(it.groupValues[2], parameters) - else + } else { expandFormStyle(it.groupValues[2], parameters) + } } return Href(expanded).percentEncodedString diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt index a041cb8d09..5ee8182154 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt @@ -8,6 +8,8 @@ package org.readium.r2.shared.util import android.net.Uri import java.io.File +import java.net.URL +import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.extensions.tryOrNull /** @@ -47,12 +49,19 @@ public value class Url private constructor(internal val uri: Uri) { requireNotNull(uri.path) Url(uri) } + + @InternalReadiumApi + public operator fun invoke(url: URL): Url = + Url(Uri.parse(url.toString())) } } public fun Url.isFile(): Boolean = scheme == "file" +public fun Url.toFile(): File? = + if (isFile()) File(path) else null + public fun Url.isHttp(): Boolean = scheme == "http" || scheme == "https" diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt index 56a0e830fb..6d465f46f5 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt @@ -10,54 +10,83 @@ import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.extensions.readFully import org.readium.r2.shared.extensions.tryOrLog -import org.readium.r2.shared.resource.* +import org.readium.r2.shared.resource.ArchiveFactory +import org.readium.r2.shared.resource.ArchiveProperties +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.FailureResource +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceMediaTypeSnifferContent +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.archive +import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipArchiveEntry import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipFile import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel import org.readium.r2.shared.util.io.CountingInputStream +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeHints +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever internal class ChannelZipContainer( private val archive: ZipFile, - private val fetchName: suspend () -> ResourceTry -) : ZipContainer { + private val mediaTypeRetriever: MediaTypeRetriever +) : Container { private inner class FailureEntry( override val path: String - ) : ZipContainer.Entry, Resource by FailureResource(Resource.Exception.NotFound()) { + ) : Container.Entry, Resource by FailureResource(Resource.Exception.NotFound()) - override val compressedLength: Long? = null - } + private inner class Entry(private val entry: ZipArchiveEntry) : Container.Entry { + + override val path: String = entry.name.addPrefix("/") - private inner class Entry(private val entry: ZipArchiveEntry) : ZipContainer.Entry { + override val source: Url? get() = null - override val path: String get() = entry.name.addPrefix("/") + override suspend fun properties(): ResourceTry = + ResourceTry.success( + Resource.Properties { + archive = ArchiveProperties( + entryLength = compressedLength + ?: length().getOrElse { return ResourceTry.failure(it) }, + isEntryCompressed = compressedLength != null + ) + } + ) - override suspend fun name(): ResourceTry = - ResourceTry.success(File(path).name) + override suspend fun mediaType(): ResourceTry = + Try.success( + mediaTypeRetriever.retrieve( + hints = MediaTypeHints(fileExtension = File(path).extension), + content = ResourceMediaTypeSnifferContent(this) + ) ?: MediaType.BINARY + ) override suspend fun length(): ResourceTry = entry.size.takeUnless { it == -1L } ?.let { Try.success(it) } ?: Try.failure(Resource.Exception.Other(UnsupportedOperationException())) - override val compressedLength: Long? + private val compressedLength: Long? get() = - if (entry.method == ZipArchiveEntry.STORED || entry.method == -1) + if (entry.method == ZipArchiveEntry.STORED || entry.method == -1) { null - else + } else { entry.compressedSize.takeUnless { it == -1L } + } override suspend fun read(range: LongRange?): ResourceTry = withContext(Dispatchers.IO) { try { val bytes = - if (range == null) + if (range == null) { readFully() - else + } else { readRange(range) + } Try.success(bytes) } catch (e: Exception) { Try.failure(Resource.Exception.wrap(e)) @@ -113,21 +142,17 @@ internal class ChannelZipContainer( } } - override suspend fun name(): ResourceTry { - return fetchName.invoke() - } - - override suspend fun entries(): List = + override suspend fun entries(): Set = archive.entries.toList() .filterNot { it.isDirectory } .mapNotNull { Entry(it) } + .toSet() - override suspend fun entry(path: String): Container.Entry { - return archive.getEntry(path.removePrefix("/")) + override fun get(path: String): Container.Entry = + archive.getEntry(path.removePrefix("/")) ?.takeUnless { it.isDirectory } ?.let { Entry(it) } ?: FailureEntry(path) - } override suspend fun close() { withContext(Dispatchers.IO) { @@ -139,7 +164,9 @@ internal class ChannelZipContainer( /** * An [ArchiveFactory] able to open a ZIP archive served through an HTTP server. */ -public class ChannelZipArchiveFactory : ArchiveFactory { +public class ChannelZipArchiveFactory( + private val mediaTypeRetriever: MediaTypeRetriever +) : ArchiveFactory { override suspend fun create( resource: Resource, @@ -153,7 +180,7 @@ public class ChannelZipArchiveFactory : ArchiveFactory { val resourceChannel = ResourceChannel(resource) val channel = wrapBaseChannel(resourceChannel) val zipFile = ZipFile(channel, true) - val channelZip = ChannelZipContainer(zipFile, resource::name) + val channelZip = ChannelZipContainer(zipFile, mediaTypeRetriever) Try.success(channelZip) } catch (e: Resource.Exception) { Try.failure(ArchiveFactory.Error.ResourceReading(e)) @@ -165,7 +192,7 @@ public class ChannelZipArchiveFactory : ArchiveFactory { internal fun openFile(file: File): Container { val fileChannel = FileChannelAdapter(file, "r") val channel = wrapBaseChannel(fileChannel) - return ChannelZipContainer(ZipFile(channel)) { Try.success(file.name) } + return ChannelZipContainer(ZipFile(channel), mediaTypeRetriever) } private fun wrapBaseChannel(channel: SeekableByteChannel): SeekableByteChannel { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt index deddfda83a..e8762de0c4 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt @@ -43,8 +43,9 @@ internal class HttpChannel( private lateinit var _headResponse: Try private suspend fun headResponse(): Try { - if (::_headResponse.isInitialized) + if (::_headResponse.isInitialized) { return _headResponse + } _headResponse = client.fetch(HttpRequest(url, method = HttpRequest.Method.HEAD)) .map { it.response } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt index b6d0fb51d7..6c577ae1de 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt @@ -53,7 +53,7 @@ internal class ResourceChannel( .getOrElse { throw IOException("Content length not available.", it) } if (position >= size) { - return@withContext - 1 + return@withContext -1 } val available = size - position diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt index 429c3fc25f..1792b07168 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt @@ -18,13 +18,16 @@ import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.error.tryRecover import org.readium.r2.shared.util.http.HttpRequest.Method +import org.readium.r2.shared.util.mediatype.BytesResourceMediaTypeSnifferContent import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeHints import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber /** * An implementation of [HttpClient] using the native [HttpURLConnection]. * + * @param mediaTypeRetriever Component used to sniff the media type of the HTTP response. * @param userAgent Custom user agent to use for requests. * @param additionalHeaders A dictionary of additional headers to send with requests. * @param connectTimeout Timeout used when establishing a connection to the resource. A null timeout @@ -33,11 +36,12 @@ import timber.log.Timber * as the default value, while a timeout of zero as an infinite timeout. */ public class DefaultHttpClient( + private val mediaTypeRetriever: MediaTypeRetriever, private val userAgent: String? = null, private val additionalHeaders: Map = mapOf(), private val connectTimeout: Duration? = null, private val readTimeout: Duration? = null, - public var callback: Callback = object : Callback {}, + public var callback: Callback = object : Callback {} ) : HttpClient { public companion object { /** @@ -112,12 +116,8 @@ public class DefaultHttpClient( public suspend fun onRequestFailed(request: HttpRequest, error: HttpException) {} } - private val mediaTypeRetriever: MediaTypeRetriever = - MediaTypeRetriever() - // We are using Dispatchers.IO but we still get this warning... override suspend fun stream(request: HttpRequest): HttpTry { - suspend fun tryStream(request: HttpRequest): HttpTry = withContext(Dispatchers.IO) { Timber.i("HTTP ${request.method.name} ${request.url}, headers: ${request.headers}") @@ -143,24 +143,21 @@ public class DefaultHttpClient( val body = connection.errorStream?.use { it.readBytes() } val mediaType = body?.let { mediaTypeRetriever.retrieve( - connection = connection, - bytes = { it } + hints = MediaTypeHints(connection), + content = BytesResourceMediaTypeSnifferContent { it } ) } throw HttpException(kind, mediaType, body) } - val mediaType = - mediaTypeRetriever.retrieve( - connection = connection - ) ?: MediaType.BINARY + val mediaType = mediaTypeRetriever.retrieve(MediaTypeHints(connection)) val response = HttpResponse( request = request, url = connection.url.toString(), statusCode = statusCode, headers = connection.safeHeaders, - mediaType = mediaType + mediaType = mediaType ?: MediaType.BINARY ) callback.onResponseReceived(request, response) @@ -171,7 +168,7 @@ public class DefaultHttpClient( Try.success( HttpStreamResponse( response = response, - body = connection.inputStream, + body = connection.inputStream ) ) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt index a3b450750b..7e93c8a047 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt @@ -85,12 +85,12 @@ public suspend fun HttpClient.fetchJSONObject(request: HttpRequest): HttpTry>, - val mediaType: MediaType, + val mediaType: MediaType ) { private val httpHeaders = HttpHeaders(headers) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpContainer.kt new file mode 100644 index 0000000000..a336d9b231 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpContainer.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2021 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.http + +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.FailureResource +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.toEntry +import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.isHttp +import timber.log.Timber + +/** + * Fetches remote resources through HTTP. + * + * Since this fetcher is used when doing progressive download streaming (e.g. audiobook), the HTTP + * byte range requests are open-ended and reused. This helps to avoid issuing too many requests. + * + * @param client HTTP client used to perform HTTP requests. + * @param baseUrl Base URL from which relative HREF are served. + */ +public class HttpContainer( + private val client: HttpClient, + private val baseUrl: String? = null +) : Container { + + override suspend fun entries(): Set? = null + + override fun get(path: String): Container.Entry { + val url = Href(path.removePrefix("/"), baseHref = baseUrl ?: "/").toUrl() + + return if (url == null || !url.isHttp()) { + val cause = IllegalArgumentException("Invalid HREF: $path, produced URL: $url") + Timber.e(cause) + FailureResource(Resource.Exception.BadRequest(cause = cause)) + } else { + HttpResource(client, url) + } + .toEntry(path) + } + + override suspend fun close() {} +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt index e65a5e0c97..462303680e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt @@ -32,32 +32,43 @@ public class HttpException( public val kind: Kind, public val mediaType: MediaType? = null, public val body: ByteArray? = null, - cause: Throwable? = null, + cause: Throwable? = null ) : UserException(kind.userMessageId, cause = cause) { public enum class Kind(@StringRes public val userMessageId: Int) { /** The provided request was not valid. */ MalformedRequest(R.string.readium_shared_http_exception_malformed_request), + /** The received response couldn't be decoded. */ MalformedResponse(R.string.readium_shared_http_exception_malformed_response), + /** The client, server or gateways timed out. */ Timeout(R.string.readium_shared_http_exception_timeout), + /** (400) The server cannot or will not process the request due to an apparent client error. */ BadRequest(R.string.readium_shared_http_exception_bad_request), + /** (401) Authentication is required and has failed or has not yet been provided. */ Unauthorized(R.string.readium_shared_http_exception_unauthorized), + /** (403) The server refuses the action, probably because we don't have the necessary permissions. */ Forbidden(R.string.readium_shared_http_exception_forbidden), + /** (404) The requested resource could not be found. */ NotFound(R.string.readium_shared_http_exception_not_found), + /** (4xx) Other client errors */ ClientError(R.string.readium_shared_http_exception_client_error), + /** (5xx) Server errors */ ServerError(R.string.readium_shared_http_exception_server_error), + /** The device is offline. */ Offline(R.string.readium_shared_http_exception_offline), + /** The request was cancelled. */ Cancelled(R.string.readium_shared_http_exception_cancelled), + /** An error whose kind is not recognized. */ Other(R.string.readium_shared_http_exception_other); diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt deleted file mode 100644 index 40d03c226c..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpFetcher.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2021 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.util.http - -import android.webkit.URLUtil -import org.readium.r2.shared.error.getOrDefault -import org.readium.r2.shared.fetcher.FailureResource -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.resource.Resource -import timber.log.Timber - -/** - * Fetches remote resources through HTTP. - * - * Since this fetcher is used when doing progressive download streaming (e.g. audiobook), the HTTP - * byte range requests are open-ended and reused. This helps to avoid issuing too many requests. - * - * @param client HTTP client used to perform HTTP requests. - * @param baseUrl Base URL from which relative HREF are served. - * @param links A set of links that are known to be available through this fetcher. - */ -public class HttpFetcher( - private val client: HttpClient, - private val baseUrl: String? = null, - private val links: List = emptyList(), -) : Fetcher { - - override suspend fun links(): List = links - - override fun get(link: Link): Fetcher.Resource { - val url = link.toUrl(baseUrl) - - return if (url == null || !URLUtil.isNetworkUrl(url)) { - val cause = IllegalArgumentException("Invalid HREF: ${link.href}, produced URL: $url") - Timber.e(cause) - FailureResource(link, error = Resource.Exception.BadRequest(cause = cause)) - } else { - HttpResource(link, url, client) - } - } - - override suspend fun close() {} - - /** Provides access to an external URL. */ - public class HttpResource( - private val link: Link, - private val resource: org.readium.r2.shared.util.http.HttpResource - ) : Resource by resource, Fetcher.Resource { - - public companion object { - - public operator fun invoke( - link: Link, - url: String, - client: HttpClient, - ): HttpResource = - HttpResource(link, HttpResource(client, url)) - } - - override suspend fun link(): Link = - link.copy( - type = resource.mediaType().getOrDefault(link.type) - ) - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpHeaders.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpHeaders.kt index 48c65fef04..c1718722f7 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpHeaders.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpHeaders.kt @@ -26,8 +26,11 @@ public data class HttpHeaders(val headers: Map>) { public operator fun get(name: String): String? { val n = name.lowercase() return headers.firstNotNullOfOrNull { (key, value) -> - if (key.lowercase() == n) value.firstOrNull() - else null + if (key.lowercase() == n) { + value.firstOrNull() + } else { + null + } } } @@ -39,8 +42,11 @@ public data class HttpHeaders(val headers: Map>) { val n = name.lowercase() return headers .mapNotNull { (key, value) -> - if (key.lowercase() == n) value - else null + if (key.lowercase() == n) { + value + } else { + null + } } .flatten() } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpRequest.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpRequest.kt index fa8c8f14f2..b16b4d68db 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpRequest.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpRequest.kt @@ -30,7 +30,7 @@ public class HttpRequest( public val extras: Bundle = Bundle(), public val connectTimeout: Duration? = null, public val readTimeout: Duration? = null, - public val allowUserInteraction: Boolean = false, + public val allowUserInteraction: Boolean = false ) : Serializable { /** Supported HTTP methods. */ @@ -68,7 +68,7 @@ public class HttpRequest( public var extras: Bundle = Bundle(), public var connectTimeout: Duration? = null, public var readTimeout: Duration? = null, - public var allowUserInteraction: Boolean = false, + public var allowUserInteraction: Boolean = false ) { public var url: String @@ -136,7 +136,7 @@ public class HttpRequest( extras = extras, connectTimeout = connectTimeout, readTimeout = readTimeout, - allowUserInteraction = allowUserInteraction, + allowUserInteraction = allowUserInteraction ) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt index 49733e7ec1..39f42720f7 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt @@ -1,6 +1,5 @@ package org.readium.r2.shared.util.http -import java.io.File import java.io.InputStream import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -10,30 +9,22 @@ import org.readium.r2.shared.extensions.read import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.io.CountingInputStream +import org.readium.r2.shared.util.mediatype.MediaType /** Provides access to an external URL. */ public class HttpResource( private val client: HttpClient, - private val url: String, + override val source: Url, private val maxSkipBytes: Long = MAX_SKIP_BYTES ) : Resource { - override suspend fun name(): ResourceTry = - headResponse().map { r -> - r.valuesForHeader("Content-Disposition") - .flatMap { it.split(";") } - .map { it.trim() } - .firstOrNull { it.startsWith("filename=") } - ?.dropWhile { it != '=' } - ?.trim('=', '"') - ?.let { File(it).name } - } + override suspend fun mediaType(): ResourceTry = + headResponse().map { it.mediaType } - override suspend fun mediaType(): ResourceTry = - headResponse().map { - it.mediaType.toString() - } + override suspend fun properties(): ResourceTry = + ResourceTry.success(Resource.Properties()) override suspend fun length(): ResourceTry = headResponse().flatMap { @@ -47,7 +38,9 @@ public class HttpResource( override suspend fun close() {} - override suspend fun read(range: LongRange?): ResourceTry = withContext(Dispatchers.IO) { + override suspend fun read(range: LongRange?): ResourceTry = withContext( + Dispatchers.IO + ) { try { stream(range?.first.takeUnless { it == 0L }).map { stream -> if (range != null) { @@ -67,10 +60,13 @@ public class HttpResource( private lateinit var _headResponse: ResourceTry private suspend fun headResponse(): ResourceTry { - if (::_headResponse.isInitialized) + if (::_headResponse.isInitialized) { return _headResponse + } - _headResponse = client.fetch(HttpRequest(url, method = HttpRequest.Method.HEAD)) + _headResponse = client.fetch( + HttpRequest(source.toString(), method = HttpRequest.Method.HEAD) + ) .map { it.response } .mapFailure { Resource.Exception.wrapHttp(it) } @@ -96,7 +92,7 @@ public class HttpResource( } tryOrLog { inputStream?.close() } - val request = HttpRequest(url) { + val request = HttpRequest(source.toString()) { from?.let { setRange(from..-1) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt index 37386ce2f4..b89bb74546 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt @@ -21,7 +21,7 @@ public class HttpResourceFactory( return Try.failure(ResourceFactory.Error.SchemeNotSupported(url.scheme)) } - val resource = HttpResource(httpClient, url.toString()) + val resource = HttpResource(httpClient, url) return Try.success(resource) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpURLConnectionExt.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpURLConnectionExt.kt new file mode 100644 index 0000000000..c203773cb2 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpURLConnectionExt.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.http + +import java.net.HttpURLConnection +import org.readium.r2.shared.extensions.extension +import org.readium.r2.shared.util.mediatype.MediaTypeHints + +public operator fun MediaTypeHints.Companion.invoke( + connection: HttpURLConnection, + mediaType: String? = null +): MediaTypeHints = + MediaTypeHints( + mediaTypes = listOfNotNull(connection.contentType, mediaType), + fileExtensions = listOfNotNull( + connection.url.extension + // TODO: The suggested filename extension, part of the HTTP header `Content-Disposition`. + ) + ) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt deleted file mode 100644 index b9dd67f1fe..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/MediaType.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2023 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.util.http - -import java.net.HttpURLConnection -import org.readium.r2.shared.extensions.extension -import org.readium.r2.shared.resource.DefaultArchiveFactory -import org.readium.r2.shared.util.mediatype.BytesSnifferContextFactory -import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever - -/** - * Resolves the format for this [HttpURLConnection], with optional extra file extension and media type - * hints. - */ -public suspend fun MediaTypeRetriever.retrieve( - connection: HttpURLConnection, - bytes: (() -> ByteArray)?, - mediaTypes: List, - fileExtensions: List, -): MediaType? { - val allMediaTypes = mediaTypes.toMutableList() - val allFileExtensions = fileExtensions.toMutableList() - - // The value of the `Content-Type` HTTP header. - connection.contentType?.let { - allMediaTypes.add(0, it) - } - - // The URL file extension. - connection.url.extension?.let { - allFileExtensions.add(0, it) - } - - // TODO: The suggested filename extension, part of the HTTP header `Content-Disposition`. - - return if (bytes != null) { - doRetrieve( - { - BytesSnifferContextFactory(DefaultArchiveFactory()) - .createContext(bytes.invoke(), mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) - }, - mediaTypes = allMediaTypes, - fileExtensions = allFileExtensions - ) - } else { - retrieve(mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) - } -} - -/** - * Resolves the format for this [HttpURLConnection], with optional extra file extension and media type - * hints. - */ -public suspend fun MediaTypeRetriever.retrieve( - connection: HttpURLConnection, - bytes: (() -> ByteArray)? = null, - mediaType: String? = null, - fileExtension: String? = null -): MediaType? = retrieve(connection, bytes, listOfNotNull(mediaType), listOfNotNull(fileExtension)) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt index 6a7c046ea8..7712eabd4e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/io/CountingInputStream.kt @@ -71,8 +71,9 @@ public class CountingInputStream( .coerceFirstNonNegative() .requireLengthFitInt() - if (range.isEmpty()) + if (range.isEmpty()) { return ByteArray(0) + } skip(range.first - count) val length = range.last - range.first + 1 diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt index de9fee044e..e96284c5df 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Extensions.kt @@ -8,67 +8,16 @@ package org.readium.r2.shared.util.mediatype import java.io.File import java.net.HttpURLConnection -import org.readium.r2.shared.extensions.extension -import org.readium.r2.shared.resource.DefaultArchiveFactory -/** - * Resolves the format for this [HttpURLConnection], with optional extra file extension and media type - * hints. - */ -@Deprecated( - "Use the MediaTypeRetriever extension instead.", - replaceWith = ReplaceWith( - "mediaTypeRetriever.retrieve(connection, bytes, mediaTypes, fileExtensions)", - "org.readium.r2.shared.util.http.retrieve" - ), - level = DeprecationLevel.ERROR -) +@Suppress("UnusedReceiverParameter", "RedundantSuspendModifier", "UNUSED_PARAMETER") +@Deprecated("Use your own solution instead", level = DeprecationLevel.ERROR) public suspend fun HttpURLConnection.sniffMediaType( bytes: (() -> ByteArray)? = null, mediaTypes: List = emptyList(), - fileExtensions: List = emptyList(), - sniffers: List = MediaType.sniffers -): MediaType? { - val allMediaTypes = mediaTypes.toMutableList() - val allFileExtensions = fileExtensions.toMutableList() - - // The value of the `Content-Type` HTTP header. - contentType?.let { - allMediaTypes.add(0, it) - } - - // The URL file extension. - url.extension?.let { - allFileExtensions.add(0, it) - } - - // TODO: The suggested filename extension, part of the HTTP header `Content-Disposition`. - - val mediaTypeRetriever = MediaTypeRetriever(sniffers = sniffers) - - return if (bytes != null) { - mediaTypeRetriever.doRetrieve( - { - BytesSnifferContextFactory(DefaultArchiveFactory()) - .createContext(bytes.invoke(), mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) - }, - mediaTypes = allMediaTypes, - fileExtensions = allFileExtensions - ) - } else { - mediaTypeRetriever.retrieve(mediaTypes = allMediaTypes, fileExtensions = allFileExtensions) - } -} + fileExtensions: List = emptyList() +): MediaType? = throw NotImplementedError() -/** -* Sniffs the media type of the file. -* -* If unknown, fallback on `MediaType.BINARY`. -*/ -@Deprecated( - "Use MediaTypeRetriever explicitly.", - replaceWith = ReplaceWith("mediaTypeRetriever.retrieve(mediaType = mediaTypeHint)"), - level = DeprecationLevel.ERROR -) +@Suppress("UnusedReceiverParameter", "RedundantSuspendModifier", "UNUSED_PARAMETER") +@Deprecated("Use your own solution instead", level = DeprecationLevel.ERROR) public suspend fun File.mediaType(mediaTypeHint: String? = null): MediaType = - MediaTypeRetriever().retrieve(this, mediaType = mediaTypeHint) ?: MediaType.BINARY + throw NotImplementedError() diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/FormatRegistry.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/FormatRegistry.kt new file mode 100644 index 0000000000..79b19dec25 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/FormatRegistry.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.mediatype + +/** + * Registry of format metadata (e.g. file extension) associated to canonical media types. + */ +public class FormatRegistry( + fileExtensions: Map = mapOf( + MediaType.ACSM to "acsm", + MediaType.CBZ to "cbz", + MediaType.DIVINA to "divina", + MediaType.DIVINA_MANIFEST to "json", + MediaType.EPUB to "epub", + MediaType.LCP_LICENSE_DOCUMENT to "lcpl", + MediaType.LCP_PROTECTED_AUDIOBOOK to "lcpa", + MediaType.LCP_PROTECTED_PDF to "lcpdf", + MediaType.PDF to "pdf", + MediaType.READIUM_AUDIOBOOK to "audiobook", + MediaType.READIUM_AUDIOBOOK_MANIFEST to "json", + MediaType.READIUM_WEBPUB to "webpub", + MediaType.READIUM_WEBPUB_MANIFEST to "json", + MediaType.W3C_WPUB_MANIFEST to "json", + MediaType.ZAB to "zab" + ) +) { + + private val fileExtensions: MutableMap = fileExtensions.toMutableMap() + + /** + * Registers a new [fileExtension] for the given [mediaType]. + */ + public fun register(mediaType: MediaType, fileExtension: String?) { + if (fileExtension == null) { + fileExtensions.remove(mediaType) + } else { + fileExtensions[mediaType] = fileExtension + } + } + + /** + * Returns the file extension associated to this canonical [mediaType], if any. + */ + public fun fileExtension(mediaType: MediaType): String? = + fileExtensions[mediaType] +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt index 70a7757163..0235a1335a 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaType.kt @@ -11,10 +11,11 @@ package org.readium.r2.shared.util.mediatype import android.content.ContentResolver import android.net.Uri +import android.os.Parcelable import java.io.File import java.nio.charset.Charset import java.util.* -import org.readium.r2.shared.extensions.tryOrNull +import kotlinx.parcelize.Parcelize /** * Represents a document format, identified by a unique RFC 6838 media type. @@ -29,68 +30,16 @@ import org.readium.r2.shared.extensions.tryOrNull * * Specification: https://tools.ietf.org/html/rfc6838 * - * @param string String representation for this media type. - * @param name A human readable name identifying the media type, which may be presented to the user. - * @param fileExtension The default file extension to use for this media type. + * @param type The type component, e.g. `application` in `application/epub+zip`. + * @param subtype The subtype component, e.g. `epub+zip` in `application/epub+zip`. + * @param parameters The parameters in the media type, such as `charset=utf-8`. */ -public class MediaType( - string: String, - public val name: String? = null, - public val fileExtension: String? = null -) { - - /** The type component, e.g. `application` in `application/epub+zip`. */ - public val type: String - - /** The subtype component, e.g. `epub+zip` in `application/epub+zip`. */ - public val subtype: String - - /** The parameters in the media type, such as `charset=utf-8`. */ +@Parcelize +public class MediaType private constructor( + public val type: String, + public val subtype: String, public val parameters: Map - - init { - if (string.isEmpty()) { - throw IllegalArgumentException("Invalid media type: $string") - } - - // Grammar: https://tools.ietf.org/html/rfc2045#section-5.1 - val components = string.split(";") - .map { it.trim() } - val types = components[0].split("/") - if (types.size != 2) { - throw IllegalArgumentException("Invalid media type: $string") - } - - // > Both top-level type and subtype names are case-insensitive. - this.type = types[0].lowercase(Locale.ROOT) - this.subtype = types[1].lowercase(Locale.ROOT) - - // > Parameter names are case-insensitive and no meaning is attached to the order in which - // > they appear. - val parameters = components.drop(1) - .map { it.split("=") } - .filter { it.size == 2 } - .associate { Pair(it[0].lowercase(Locale.ROOT), it[1]) } - .toMutableMap() - - // For now, we only support case-insensitive `charset`. - // - // > Parameter values might or might not be case-sensitive, depending on the semantics of - // > the parameter name. - // > https://tools.ietf.org/html/rfc2616#section-3.7 - // - // > The character set names may be up to 40 characters taken from the printable characters - // > of US-ASCII. However, no distinction is made between use of upper and lower case - // > letters. - // > https://www.iana.org/assignments/character-sets/character-sets.xhtml - parameters["charset"]?.let { - parameters["charset"] = - (try { Charset.forName(it).name() } catch (e: Exception) { it }) - .uppercase(Locale.ROOT) - } - - this.parameters = parameters - } +) : Parcelable { /** * Structured syntax suffix, e.g. `+zip` in `application/epub+zip`. @@ -118,10 +67,12 @@ public class MediaType( * * Non-significant parameters are also discarded. */ - @Deprecated("Use MediaTypeRetriever instead", replaceWith = ReplaceWith("mediaTypeRetriever.canonicalMediaType()"), level = DeprecationLevel.ERROR) - public fun canonicalMediaType(): MediaType { - TODO() - } + @Deprecated( + "Use FormatRegistry.canonicalize() instead", + replaceWith = ReplaceWith("formatRegistry.canonicalize(this)"), + level = DeprecationLevel.ERROR + ) + public fun canonicalMediaType(): MediaType = TODO() /** The string representation of this media type. */ override fun toString(): String { @@ -178,7 +129,7 @@ public class MediaType( * Returns whether the given [other] media type is included in this media type. */ public fun contains(other: String?): Boolean { - val mediaType = other?.let { parse(it) } + val mediaType = other?.let { MediaType(it) } ?: return false return contains(mediaType) @@ -199,7 +150,7 @@ public class MediaType( * in both media types. */ public fun matches(other: String?): Boolean = - matches(other?.let { parse(it) }) + matches(other?.let { MediaType(it) }) /** * Returns whether this media type matches any of the `others` media types. @@ -252,7 +203,11 @@ public class MediaType( LCP_PROTECTED_PDF, LPF, PDF, W3C_WPUB_MANIFEST, READIUM_WEBPUB, READIUM_WEBPUB_MANIFEST, ZAB ) - @Deprecated("Format and MediaType got merged together", replaceWith = ReplaceWith(""), level = DeprecationLevel.ERROR) + @Deprecated( + "Format and MediaType got merged together", + replaceWith = ReplaceWith(""), + level = DeprecationLevel.ERROR + ) public val mediaType: MediaType get() = this @@ -260,76 +215,141 @@ public class MediaType( /** * Creates a [MediaType] from its RFC 6838 string representation. - * - * @param name A human readable name identifying the media type, which may be presented to the user. - * @param fileExtension The default file extension to use for this media type. */ + public operator fun invoke(string: String): MediaType? { + if (string.isEmpty()) { + return null + } + + // Grammar: https://tools.ietf.org/html/rfc2045#section-5.1 + val components = string.split(";") + .map { it.trim() } + val types = components[0].split("/") + if (types.size != 2) { + return null + } + + // > Both top-level type and subtype names are case-insensitive. + val type = types[0].lowercase(Locale.ROOT) + val subtype = types[1].lowercase(Locale.ROOT) + + // > Parameter names are case-insensitive and no meaning is attached to the order in which + // > they appear. + val parameters = components.drop(1) + .map { it.split("=") } + .filter { it.size == 2 } + .associate { Pair(it[0].lowercase(Locale.ROOT), it[1]) } + .toMutableMap() + + // For now, we only support case-insensitive `charset`. + // + // > Parameter values might or might not be case-sensitive, depending on the semantics of + // > the parameter name. + // > https://tools.ietf.org/html/rfc2616#section-3.7 + // + // > The character set names may be up to 40 characters taken from the printable characters + // > of US-ASCII. However, no distinction is made between use of upper and lower case + // > letters. + // > https://www.iana.org/assignments/character-sets/character-sets.xhtml + parameters["charset"]?.let { + parameters["charset"] = + (try { Charset.forName(it).name() } catch (e: Exception) { it }) + .uppercase(Locale.ROOT) + } + + return MediaType( + type = type, + subtype = subtype, + parameters = parameters + ) + } + + @Suppress("UNUSED_PARAMETER") + @Deprecated( + "Use `MediaType(string)` instead", + replaceWith = ReplaceWith("MediaType(string)"), + level = DeprecationLevel.ERROR + ) public fun parse(string: String, name: String? = null, fileExtension: String? = null): MediaType? = - tryOrNull { MediaType(string = string, name = name, fileExtension = fileExtension) } + MediaType(string) // Known Media Types // // Reading apps are welcome to extend the static constants with additional media types. - public val AAC: MediaType = MediaType("audio/aac", fileExtension = "aac") - public val ACSM: MediaType = MediaType("application/vnd.adobe.adept+xml", name = "Adobe Content Server Message", fileExtension = "acsm") - public val AIFF: MediaType = MediaType("audio/aiff", fileExtension = "aiff") - public val AVI: MediaType = MediaType("video/x-msvideo", fileExtension = "avi") - public val AVIF: MediaType = MediaType("image/avif", fileExtension = "avif") - public val BINARY: MediaType = MediaType("application/octet-stream") - public val BMP: MediaType = MediaType("image/bmp", fileExtension = "bmp") - public val CBZ: MediaType = MediaType("application/vnd.comicbook+zip", name = "Comic Book Archive", fileExtension = "cbz") - public val CSS: MediaType = MediaType("text/css", fileExtension = "css") - public val DIVINA: MediaType = MediaType("application/divina+zip", name = "Digital Visual Narratives", fileExtension = "divina") - public val DIVINA_MANIFEST: MediaType = MediaType("application/divina+json", name = "Digital Visual Narratives", fileExtension = "json") - public val EPUB: MediaType = MediaType("application/epub+zip", name = "EPUB", fileExtension = "epub") - public val GIF: MediaType = MediaType("image/gif", fileExtension = "gif") - public val GZ: MediaType = MediaType("application/gzip", fileExtension = "gz") - public val HTML: MediaType = MediaType("text/html", fileExtension = "html") - public val JAVASCRIPT: MediaType = MediaType("text/javascript", fileExtension = "js") - public val JPEG: MediaType = MediaType("image/jpeg", fileExtension = "jpeg") - public val JSON: MediaType = MediaType("application/json") - public val JSON_PROBLEM_DETAILS: MediaType = MediaType("application/problem+json", name = "HTTP Problem Details", fileExtension = "json") - public val JXL: MediaType = MediaType("image/jxl", fileExtension = "jxl") - public val LCP_LICENSE_DOCUMENT: MediaType = MediaType("application/vnd.readium.lcp.license.v1.0+json", name = "LCP License", fileExtension = "lcpl") - public val LCP_PROTECTED_AUDIOBOOK: MediaType = MediaType("application/audiobook+lcp", name = "LCP Protected Audiobook", fileExtension = "lcpa") - public val LCP_PROTECTED_PDF: MediaType = MediaType("application/pdf+lcp", name = "LCP Protected PDF", fileExtension = "lcpdf") - public val LCP_STATUS_DOCUMENT: MediaType = MediaType("application/vnd.readium.license.status.v1.0+json") - public val LPF: MediaType = MediaType("application/lpf+zip", fileExtension = "lpf") - public val MP3: MediaType = MediaType("audio/mpeg", fileExtension = "mp3") - public val MPEG: MediaType = MediaType("video/mpeg", fileExtension = "mpeg") - public val NCX: MediaType = MediaType("application/x-dtbncx+xml", fileExtension = "ncx") - public val OGG: MediaType = MediaType("audio/ogg", fileExtension = "oga") - public val OGV: MediaType = MediaType("video/ogg", fileExtension = "ogv") - public val OPDS1: MediaType = MediaType("application/atom+xml;profile=opds-catalog") - public val OPDS1_ENTRY: MediaType = MediaType("application/atom+xml;type=entry;profile=opds-catalog") - public val OPDS2: MediaType = MediaType("application/opds+json") - public val OPDS2_PUBLICATION: MediaType = MediaType("application/opds-publication+json") - public val OPDS_AUTHENTICATION: MediaType = MediaType("application/opds-authentication+json") - public val OPUS: MediaType = MediaType("audio/opus", fileExtension = "opus") - public val OTF: MediaType = MediaType("font/otf", fileExtension = "otf") - public val PDF: MediaType = MediaType("application/pdf", name = "PDF", fileExtension = "pdf") - public val PNG: MediaType = MediaType("image/png", fileExtension = "png") - public val READIUM_AUDIOBOOK: MediaType = MediaType("application/audiobook+zip", name = "Readium Audiobook", fileExtension = "audiobook") - public val READIUM_AUDIOBOOK_MANIFEST: MediaType = MediaType("application/audiobook+json", name = "Readium Audiobook", fileExtension = "json") - public val READIUM_WEBPUB: MediaType = MediaType("application/webpub+zip", name = "Readium Web Publication", fileExtension = "webpub") - public val READIUM_WEBPUB_MANIFEST: MediaType = MediaType("application/webpub+json", name = "Readium Web Publication", fileExtension = "json") - public val SMIL: MediaType = MediaType("application/smil+xml", fileExtension = "smil") - public val SVG: MediaType = MediaType("image/svg+xml", fileExtension = "svg") - public val TEXT: MediaType = MediaType("text/plain", fileExtension = "txt") - public val TIFF: MediaType = MediaType("image/tiff", fileExtension = "tiff") - public val TTF: MediaType = MediaType("font/ttf", fileExtension = "ttf") - public val W3C_WPUB_MANIFEST: MediaType = MediaType("application/x.readium.w3c.wpub+json", name = "Web Publication", fileExtension = "json") // non-existent - public val WAV: MediaType = MediaType("audio/wav", fileExtension = "wav") - public val WEBM_AUDIO: MediaType = MediaType("audio/webm", fileExtension = "webm") - public val WEBM_VIDEO: MediaType = MediaType("video/webm", fileExtension = "webm") - public val WEBP: MediaType = MediaType("image/webp", fileExtension = "webp") - public val WOFF: MediaType = MediaType("font/woff", fileExtension = "woff") - public val WOFF2: MediaType = MediaType("font/woff2", fileExtension = "woff2") - public val XHTML: MediaType = MediaType("application/xhtml+xml", fileExtension = "xhtml") - public val XML: MediaType = MediaType("application/xml", fileExtension = "xml") - public val ZAB: MediaType = MediaType("application/x.readium.zab+zip", name = "Zipped Audio Book", fileExtension = "zab") // non-existent - public val ZIP: MediaType = MediaType("application/zip", fileExtension = "zip") + public val AAC: MediaType = MediaType("audio/aac")!! + public val ACSM: MediaType = MediaType("application/vnd.adobe.adept+xml")!! + public val AIFF: MediaType = MediaType("audio/aiff")!! + public val AVI: MediaType = MediaType("video/x-msvideo")!! + public val AVIF: MediaType = MediaType("image/avif")!! + public val BINARY: MediaType = MediaType("application/octet-stream")!! + public val BMP: MediaType = MediaType("image/bmp")!! + public val CBZ: MediaType = MediaType("application/vnd.comicbook+zip")!! + public val CSS: MediaType = MediaType("text/css")!! + public val DIVINA: MediaType = MediaType("application/divina+zip")!! + public val DIVINA_MANIFEST: MediaType = MediaType("application/divina+json")!! + public val EPUB: MediaType = MediaType("application/epub+zip")!! + public val GIF: MediaType = MediaType("image/gif")!! + public val GZ: MediaType = MediaType("application/gzip")!! + public val HTML: MediaType = MediaType("text/html")!! + public val JAVASCRIPT: MediaType = MediaType("text/javascript")!! + public val JPEG: MediaType = MediaType("image/jpeg")!! + public val JSON: MediaType = MediaType("application/json")!! + public val JSON_PROBLEM_DETAILS: MediaType = MediaType("application/problem+json")!! + public val JXL: MediaType = MediaType("image/jxl")!! + public val LCP_LICENSE_DOCUMENT: MediaType = MediaType( + "application/vnd.readium.lcp.license.v1.0+json" + )!! + public val LCP_PROTECTED_AUDIOBOOK: MediaType = MediaType("application/audiobook+lcp")!! + public val LCP_PROTECTED_PDF: MediaType = MediaType("application/pdf+lcp")!! + public val LCP_STATUS_DOCUMENT: MediaType = MediaType( + "application/vnd.readium.license.status.v1.0+json" + )!! + public val LPF: MediaType = MediaType("application/lpf+zip")!! + public val MP3: MediaType = MediaType("audio/mpeg")!! + public val MPEG: MediaType = MediaType("video/mpeg")!! + public val NCX: MediaType = MediaType("application/x-dtbncx+xml")!! + public val OGG: MediaType = MediaType("audio/ogg")!! + public val OGV: MediaType = MediaType("video/ogg")!! + public val OPDS1: MediaType = MediaType("application/atom+xml;profile=opds-catalog")!! + public val OPDS1_NAVIGATION_FEED: MediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=navigation" + )!! + public val OPDS1_ACQUISITION_FEED: MediaType = MediaType( + "application/atom+xml;profile=opds-catalog;kind=acquisition" + )!! + public val OPDS1_ENTRY: MediaType = MediaType( + "application/atom+xml;type=entry;profile=opds-catalog" + )!! + public val OPDS2: MediaType = MediaType("application/opds+json")!! + public val OPDS2_PUBLICATION: MediaType = MediaType("application/opds-publication+json")!! + public val OPDS_AUTHENTICATION: MediaType = MediaType( + "application/opds-authentication+json" + )!! + public val OPUS: MediaType = MediaType("audio/opus")!! + public val OTF: MediaType = MediaType("font/otf")!! + public val PDF: MediaType = MediaType("application/pdf")!! + public val PNG: MediaType = MediaType("image/png")!! + public val READIUM_AUDIOBOOK: MediaType = MediaType("application/audiobook+zip")!! + public val READIUM_AUDIOBOOK_MANIFEST: MediaType = MediaType("application/audiobook+json")!! + public val READIUM_WEBPUB: MediaType = MediaType("application/webpub+zip")!! + public val READIUM_WEBPUB_MANIFEST: MediaType = MediaType("application/webpub+json")!! + public val SMIL: MediaType = MediaType("application/smil+xml")!! + public val SVG: MediaType = MediaType("image/svg+xml")!! + public val TEXT: MediaType = MediaType("text/plain")!! + public val TIFF: MediaType = MediaType("image/tiff")!! + public val TTF: MediaType = MediaType("font/ttf")!! + public val W3C_WPUB_MANIFEST: MediaType = MediaType("application/x.readium.w3c.wpub+json")!! // non-existent + public val WAV: MediaType = MediaType("audio/wav")!! + public val WEBM_AUDIO: MediaType = MediaType("audio/webm")!! + public val WEBM_VIDEO: MediaType = MediaType("video/webm")!! + public val WEBP: MediaType = MediaType("image/webp")!! + public val WOFF: MediaType = MediaType("font/woff")!! + public val WOFF2: MediaType = MediaType("font/woff2")!! + public val XHTML: MediaType = MediaType("application/xhtml+xml")!! + public val XML: MediaType = MediaType("application/xml")!! + public val ZAB: MediaType = MediaType("application/x.readium.zab+zip")!! // non-existent + public val ZIP: MediaType = MediaType("application/zip")!! // Sniffing @@ -338,18 +358,24 @@ public class MediaType( * You can register additional sniffers globally by modifying this list. * The sniffers order is important, because some formats are subsets of other formats. */ - public val sniffers: MutableList = Sniffers.all.toMutableList() + @Deprecated(message = "Use FormatRegistry instead", level = DeprecationLevel.ERROR) + public val sniffers: MutableList = mutableListOf() /** * Resolves a format from a single file extension and media type hint, without checking the actual * content. */ - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(mediaType = mediaType, fileExtension = fileExtension)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith( + "MediaTypeRetriever().retrieve(mediaType = mediaType, fileExtension = fileExtension)" + ), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun of( mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? { TODO() } @@ -358,12 +384,17 @@ public class MediaType( * Resolves a format from file extension and media type hints, without checking the actual * content. */ - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(mediaTypes = mediaTypes, fileExtensions = fileExtensions)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith( + "MediaTypeRetriever().retrieve(mediaTypes = mediaTypes, fileExtensions = fileExtensions)" + ), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun of( mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? { TODO() } @@ -372,12 +403,15 @@ public class MediaType( * Resolves a format from a local file path. */ @Suppress("UNUSED_PARAMETER") - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(file)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(file)"), + level = DeprecationLevel.ERROR + ) public fun ofFile( file: File, mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? { TODO() } @@ -385,13 +419,18 @@ public class MediaType( /** * Resolves a format from a local file path. */ - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(file, mediaTypes = mediaTypes, fileExtensions = fileExtensions)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith( + "MediaTypeRetriever().retrieve(file, mediaTypes = mediaTypes, fileExtensions = fileExtensions)" + ), + level = DeprecationLevel.ERROR + ) @Suppress("UNUSED_PARAMETER") public fun ofFile( file: File, mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? { TODO() } @@ -400,12 +439,15 @@ public class MediaType( * Resolves a format from a local file path. */ @Suppress("UNUSED_PARAMETER") - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(File(path))"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(File(path))"), + level = DeprecationLevel.ERROR + ) public fun ofFile( path: String, mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? { TODO() } @@ -414,12 +456,17 @@ public class MediaType( * Resolves a format from a local file path. */ @Suppress("UNUSED_PARAMETER") - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(File(path), mediaTypes = mediaTypes, fileExtensions = fileExtensions)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith( + "MediaTypeRetriever().retrieve(File(path), mediaTypes = mediaTypes, fileExtensions = fileExtensions)" + ), + level = DeprecationLevel.ERROR + ) public fun ofFile( path: String, mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? { TODO() } @@ -428,12 +475,15 @@ public class MediaType( * Resolves a format from bytes, e.g. from an HTTP response. */ @Suppress("UNUSED_PARAMETER") - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(bytes)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(bytes)"), + level = DeprecationLevel.ERROR + ) public fun ofBytes( bytes: () -> ByteArray, mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? { TODO() } @@ -442,12 +492,17 @@ public class MediaType( * Resolves a format from bytes, e.g. from an HTTP response. */ @Suppress("UNUSED_PARAMETER") - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever().retrieve(bytes, mediaTypes = mediaTypes, fileExtensions = fileExtensions)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith( + "MediaTypeRetriever().retrieve(bytes, mediaTypes = mediaTypes, fileExtensions = fileExtensions)" + ), + level = DeprecationLevel.ERROR + ) public fun ofBytes( bytes: () -> ByteArray, mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? { TODO() } @@ -457,13 +512,18 @@ public class MediaType( * Accepts the following URI schemes: content, android.resource, file. */ @Suppress("UNUSED_PARAMETER") - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever(contentResolver = contentResolver).retrieve(uri)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith( + "MediaTypeRetriever(contentResolver = contentResolver).retrieve(uri)" + ), + level = DeprecationLevel.ERROR + ) public fun ofUri( uri: Uri, contentResolver: ContentResolver, mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? { TODO() } @@ -473,32 +533,71 @@ public class MediaType( * Accepts the following URI schemes: content, android.resource, file. */ @Suppress("UNUSED_PARAMETER") - @Deprecated(message = "Use MediaTypeRetriever instead", replaceWith = ReplaceWith("MediaTypeRetriever(contentResolver = contentResolver).retrieve(uri, mediaTypes = mediaTypes, fileExtensions = fileExtensions)"), level = DeprecationLevel.ERROR) + @Deprecated( + message = "Use MediaTypeRetriever instead", + replaceWith = ReplaceWith( + "MediaTypeRetriever(contentResolver = contentResolver).retrieve(uri, mediaTypes = mediaTypes, fileExtensions = fileExtensions)" + ), + level = DeprecationLevel.ERROR + ) public fun ofUri( uri: Uri, contentResolver: ContentResolver, mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? { TODO() } /* Deprecated */ - @Deprecated("Use [READIUM_AUDIOBOOK] instead", ReplaceWith("MediaType.READIUM_AUDIOBOOK"), level = DeprecationLevel.ERROR) + @Deprecated( + "Use [READIUM_AUDIOBOOK] instead", + ReplaceWith("MediaType.READIUM_AUDIOBOOK"), + level = DeprecationLevel.ERROR + ) public val AUDIOBOOK: MediaType get() = READIUM_AUDIOBOOK - @Deprecated("Use [READIUM_AUDIOBOOK_MANIFEST] instead", ReplaceWith("MediaType.READIUM_AUDIOBOOK_MANIFEST"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [READIUM_AUDIOBOOK_MANIFEST] instead", + ReplaceWith("MediaType.READIUM_AUDIOBOOK_MANIFEST"), + level = DeprecationLevel.ERROR + ) public val AUDIOBOOK_MANIFEST: MediaType get() = READIUM_AUDIOBOOK_MANIFEST - @Deprecated("Use [READIUM_WEBPUB] instead", ReplaceWith("MediaType.READIUM_WEBPUB"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [READIUM_WEBPUB] instead", + ReplaceWith("MediaType.READIUM_WEBPUB"), + level = DeprecationLevel.ERROR + ) public val WEBPUB: MediaType get() = READIUM_WEBPUB - @Deprecated("Use [READIUM_WEBPUB_MANIFEST] instead", ReplaceWith("MediaType.READIUM_WEBPUB_MANIFEST"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [READIUM_WEBPUB_MANIFEST] instead", + ReplaceWith("MediaType.READIUM_WEBPUB_MANIFEST"), + level = DeprecationLevel.ERROR + ) public val WEBPUB_MANIFEST: MediaType get() = READIUM_WEBPUB_MANIFEST - @Deprecated("Use [OPDS1] instead", ReplaceWith("MediaType.OPDS1"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [OPDS1] instead", + ReplaceWith("MediaType.OPDS1"), + level = DeprecationLevel.ERROR + ) public val OPDS1_FEED: MediaType get() = OPDS1 - @Deprecated("Use [OPDS2] instead", ReplaceWith("MediaType.OPDS2"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [OPDS2] instead", + ReplaceWith("MediaType.OPDS2"), + level = DeprecationLevel.ERROR + ) public val OPDS2_FEED: MediaType get() = OPDS2 - @Deprecated("Use [LCP_LICENSE_DOCUMENT] instead", ReplaceWith("MediaType.LCP_LICENSE_DOCUMENT"), level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [LCP_LICENSE_DOCUMENT] instead", + ReplaceWith("MediaType.LCP_LICENSE_DOCUMENT"), + level = DeprecationLevel.ERROR + ) public val LCP_LICENSE: MediaType get() = LCP_LICENSE_DOCUMENT @Suppress("UNUSED_PARAMETER") @@ -506,8 +605,7 @@ public class MediaType( public fun of( file: File, mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? = null @Suppress("UNUSED_PARAMETER") @@ -515,8 +613,7 @@ public class MediaType( public fun of( file: File, mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? = null @Suppress("UNUSED_PARAMETER") @@ -524,8 +621,7 @@ public class MediaType( public fun of( bytes: () -> ByteArray, mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? = null @Suppress("UNUSED_PARAMETER") @@ -533,8 +629,7 @@ public class MediaType( public fun of( bytes: () -> ByteArray, mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? = null @Suppress("UNUSED_PARAMETER") @@ -543,8 +638,7 @@ public class MediaType( uri: Uri, contentResolver: ContentResolver, mediaType: String? = null, - fileExtension: String? = null, - sniffers: List = MediaType.sniffers + fileExtension: String? = null ): MediaType? = null @Suppress("UNUSED_PARAMETER") @@ -553,8 +647,7 @@ public class MediaType( uri: Uri, contentResolver: ContentResolver, mediaTypes: List, - fileExtensions: List, - sniffers: List = MediaType.sniffers + fileExtensions: List ): MediaType? = null } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeHints.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeHints.kt new file mode 100644 index 0000000000..22d905db11 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeHints.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.mediatype + +import java.nio.charset.Charset + +/** + * Bundle of media type and file extension hints for the [MediaTypeSniffer]. + */ +public data class MediaTypeHints( + val mediaTypes: List = emptyList(), + val fileExtensions: List = emptyList() +) { + public companion object { + public operator fun invoke(mediaType: MediaType? = null, fileExtension: String? = null): MediaTypeHints = + MediaTypeHints( + mediaTypes = listOfNotNull(mediaType), + fileExtensions = listOfNotNull(fileExtension) + ) + + public operator fun invoke( + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList() + ): MediaTypeHints = + MediaTypeHints(mediaTypes.mapNotNull { MediaType(it) }, fileExtensions = fileExtensions) + } + + public operator fun plus(other: MediaTypeHints): MediaTypeHints = + MediaTypeHints( + mediaTypes = mediaTypes + other.mediaTypes, + fileExtensions = fileExtensions + other.fileExtensions + ) + + /** + * Returns a new [MediaTypeHints] after appending the given [fileExtension] hint. + */ + public fun addFileExtension(fileExtension: String?): MediaTypeHints { + fileExtension ?: return this + return copy(fileExtensions = fileExtensions + fileExtension) + } + + /** Finds the first [Charset] declared in the media types' `charset` parameter. */ + public val charset: Charset? get() = + mediaTypes.firstNotNullOfOrNull { it.charset } + + /** Returns whether this context has any of the given file extensions, ignoring case. */ + public fun hasFileExtension(vararg fileExtensions: String): Boolean { + val fileExtensionsHints = this.fileExtensions.map { it.lowercase() } + for (fileExtension in fileExtensions.map { it.lowercase() }) { + if (fileExtensionsHints.contains(fileExtension)) { + return true + } + } + return false + } + + /** + * Returns whether this context has any of the given media type, ignoring case and extra + * parameters. + * + * Implementation note: Use [MediaType] to handle the comparison to avoid edge cases. + */ + public fun hasMediaType(vararg mediaTypes: String): Boolean { + @Suppress("NAME_SHADOWING") + val mediaTypes = mediaTypes.mapNotNull { MediaType(it) } + for (mediaType in mediaTypes) { + if (this.mediaTypes.any { mediaType.contains(it) }) { + return true + } + } + return false + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt index 212d793bd2..8ebc1cb406 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeRetriever.kt @@ -6,241 +6,103 @@ package org.readium.r2.shared.util.mediatype -import android.content.ContentResolver -import android.net.Uri -import android.provider.MediaStore -import java.io.File -import org.readium.r2.shared.BuildConfig -import org.readium.r2.shared.extensions.queryProjection -import org.readium.r2.shared.resource.* -import org.readium.r2.shared.util.Either -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.toUrl - +/** + * Retrieves a canonical [MediaType] for the provided media type and file extension hints and/or + * asset content. + * + * The actual format sniffing is done by the provided [sniffers]. The [defaultSniffers] cover the + * formats supported with Readium by default. + */ public class MediaTypeRetriever( - resourceFactory: ResourceFactory = FileResourceFactory(), - containerFactory: ContainerFactory = DirectoryContainerFactory(), - archiveFactory: ArchiveFactory = DefaultArchiveFactory(), - private val contentResolver: ContentResolver? = null, - private val sniffers: List = Sniffers.all, + private val sniffers: List = defaultSniffers ) { - private val urlSnifferContextFactory: UrlSnifferContextFactory = - UrlSnifferContextFactory(resourceFactory, containerFactory, archiveFactory) - - private val bytesSnifferContextFactory: BytesSnifferContextFactory = - BytesSnifferContextFactory(archiveFactory) - - public suspend fun canonicalMediaType(mediaType: MediaType): MediaType = - retrieve(mediaType = mediaType.toString()) ?: mediaType - /** - * Resolves a media type from a single file extension and media type hint, without checking the actual - * content. - */ - public suspend fun retrieve( - mediaType: String? = null, - fileExtension: String? = null, - ): MediaType? { - if (BuildConfig.DEBUG && mediaType?.startsWith("/") == true) { - throw IllegalArgumentException("The provided media type is incorrect: $mediaType. To pass a file path, you must wrap it in a File().") - } - return retrieve(mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) + public companion object { + /** + * The default sniffers provided by Readium 2 for all known formats. + * The sniffers order is important, because some formats are subsets of other formats. + */ + public val defaultSniffers: List = listOf( + XhtmlMediaTypeSniffer, + HtmlMediaTypeSniffer, + OpdsMediaTypeSniffer, + LcpLicenseMediaTypeSniffer, + BitmapMediaTypeSniffer, + WebPubManifestMediaTypeSniffer, + WebPubMediaTypeSniffer, + W3cWpubMediaTypeSniffer, + EpubMediaTypeSniffer, + LpfMediaTypeSniffer, + ArchiveMediaTypeSniffer, + PdfMediaTypeSniffer, + JsonMediaTypeSniffer + ) } /** - * Resolves a media type from file extension and media type hints without checking the actual - * content. + * Retrieves a canonical [MediaType] for the provided media type and file extension [hints]. */ - public suspend fun retrieve( - mediaTypes: List, - fileExtensions: List - ): MediaType? { - return doRetrieve(null, mediaTypes, fileExtensions) + public fun retrieve(hints: MediaTypeHints): MediaType? { + sniffers.firstNotNullOfOrNull { it.sniffHints(hints) } + ?.let { return it } + + // Falls back on the system-wide registered media types using MimeTypeMap. + // Note: This is done after the default sniffers, because otherwise it will detect + // JSON, XML or ZIP formats before we have a chance of sniffing their content (for example, + // for RWPM). + SystemMediaTypeSniffer.sniffHints(hints) + ?.let { return it } + + return hints.mediaTypes.firstOrNull() } /** - * Resolves a media type from a local file. + * Retrieves a canonical [MediaType] for the provided [mediaType] and [fileExtension] hints. */ - public suspend fun retrieve( - file: File, - mediaType: String? = null, - fileExtension: String? = null, - ): MediaType? { - return retrieve(file, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) - } + public fun retrieve(mediaType: String? = null, fileExtension: String? = null): MediaType? = + retrieve( + MediaTypeHints( + mediaType = mediaType?.let { MediaType(it) }, + fileExtension = fileExtension + ) + ) /** - * Resolves a media type from a local file. + * Retrieves a canonical [MediaType] for the provided [mediaType] and [fileExtension] hints. */ - public suspend fun retrieve( - file: File, - mediaTypes: List, - fileExtensions: List, - ): MediaType? { - return retrieve(content = Either.Right(file.toUrl()), mediaTypes = mediaTypes, fileExtensions = listOf(file.extension) + fileExtensions) - } - - /** - * Resolves a media type from bytes, e.g. from an HTTP response. - */ - public suspend fun retrieve( - bytes: () -> ByteArray, - mediaType: String? = null, - fileExtension: String? = null, - ): MediaType? { - return retrieve(bytes, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) - } - - /** - * Resolves a media type from bytes, e.g. from an HTTP response. - */ - public suspend fun retrieve( - bytes: () -> ByteArray, - mediaTypes: List, - fileExtensions: List, - ): MediaType? { - return retrieve(content = Either.Left(bytes), mediaTypes = mediaTypes, fileExtensions = fileExtensions) - } + public fun retrieve(mediaType: MediaType, fileExtension: String? = null): MediaType = + retrieve(MediaTypeHints(mediaType = mediaType, fileExtension = fileExtension)) ?: mediaType /** - * Resolves a media type from a Uri. + * Retrieves a canonical [MediaType] for the provided [mediaTypes] and [fileExtensions] hints. */ - public suspend fun retrieve( - uri: Uri, - mediaType: String? = null, - fileExtension: String? = null, - ): MediaType? { - return retrieve(uri, mediaTypes = listOfNotNull(mediaType), fileExtensions = listOfNotNull(fileExtension)) - } + public fun retrieve( + mediaTypes: List = emptyList(), + fileExtensions: List = emptyList() + ): MediaType? = + retrieve(MediaTypeHints(mediaTypes = mediaTypes, fileExtensions = fileExtensions)) /** - * Resolves a media type from a Uri. + * Retrieves a canonical [MediaType] for the provided media type and file extensions [hints] and + * asset [content]. */ public suspend fun retrieve( - uri: Uri, - mediaTypes: List, - fileExtensions: List, - ): MediaType? { - val url = uri.toUrl() ?: return null - return retrieve(content = Either.Right(url), mediaTypes = mediaTypes, fileExtensions = fileExtensions) - } - - /** - * Resolves a media type from a sniffer context. - * - * Sniffing a media type is done in two rounds, because we want to give an opportunity to all - * sniffers to return a [MediaType] quickly before inspecting the content itself: - * - Light Sniffing checks only the provided file extension or media type hints. - * - Heavy Sniffing reads the bytes to perform more advanced sniffing. - */ - private suspend fun retrieve( - content: Either<() -> ByteArray, Url>?, - mediaTypes: List, - fileExtensions: List + hints: MediaTypeHints = MediaTypeHints(), + content: MediaTypeSnifferContent? = null ): MediaType? { - val fullContext = suspend { - when (content) { - is Either.Left -> - bytesSnifferContextFactory.createContext( - content.value.invoke(), - mediaTypes, - fileExtensions - ) - is Either.Right -> - urlSnifferContextFactory.createContext( - content.value, - mediaTypes, - fileExtensions - ) - null -> null - } - } - - doRetrieve(fullContext, mediaTypes, fileExtensions)?.let { return it } - - // Falls back on the [contentResolver] in case of content Uri. - // Note: This is done after the heavy sniffing of the provided [sniffers], because - // otherwise it will detect JSON, XML or ZIP formats before we have a chance of sniffing - // their content (for example, for RWPM). - - val url = (content as? Either.Right)?.value - ?: return null - - val allMediaTypes = mediaTypes.toMutableList() - val allFileExtensions = fileExtensions.toMutableList() - - if (url.scheme == ContentResolver.SCHEME_CONTENT && contentResolver != null) { - contentResolver.getType(url.uri) - ?.takeUnless { MediaType.BINARY.matches(it) } - ?.let { allMediaTypes.add(0, it) } - - contentResolver.queryProjection(url.uri, MediaStore.MediaColumns.DISPLAY_NAME)?.let { filename -> - allFileExtensions.add(0, File(filename).extension) - } - } - - return doRetrieve(fullContext, allMediaTypes, allFileExtensions) - } - - /** - * Resolves a media type from a sniffer context. - * - * Sniffing a media type is done in two rounds, because we want to give an opportunity to all - * sniffers to return a [MediaType] quickly before inspecting the content itself: - * - Light Sniffing checks only the provided file extension or media type hints. - * - Heavy Sniffing reads the bytes to perform more advanced sniffing. - */ - internal suspend fun doRetrieve( - fullContext: (suspend () -> SnifferContext?)?, - mediaTypes: List, - fileExtensions: List - ): MediaType? { - // Light sniffing with only media type hints - if (mediaTypes.isNotEmpty()) { - val context = HintSnifferContext(mediaTypes = mediaTypes) - for (sniffer in sniffers) { - val mediaType = sniffer(context) - if (mediaType != null) { - return mediaType - } - } - } - - // Light sniffing with both media type hints and file extensions - if (fileExtensions.isNotEmpty()) { - val context = HintSnifferContext(mediaTypes = mediaTypes, fileExtensions = fileExtensions) - for (sniffer in sniffers) { - val mediaType = sniffer(context) - if (mediaType != null) { - return mediaType - } - } - } - - // Heavy sniffing - val context = fullContext?.invoke() - - if (context != null) { - for (sniffer in sniffers) { - val mediaType = sniffer(context) - if (mediaType != null) { - return mediaType - } - } - } - - // Falls back on the system-wide registered media types using [MimeTypeMap]. - // Note: This is done after the heavy sniffing of the provided [sniffers], because - // otherwise it will detect JSON, XML or ZIP formats before we have a chance of sniffing - // their content (for example, for RWPM). - val systemContext = context ?: HintSnifferContext(mediaTypes, fileExtensions) - Sniffers.system(systemContext)?.let { return it } - - // If nothing else worked, we try to parse the first valid media type hint. - for (mediaType in mediaTypes) { - MediaType.parse(mediaType)?.let { return it } - } - - return null + sniffers.run { + firstNotNullOfOrNull { it.sniffHints(hints) } + ?: content?.let { firstNotNullOfOrNull { it.sniffContent(content) } } + }?.let { return it } + + // Falls back on the system-wide registered media types using MimeTypeMap. + // Note: This is done after the default sniffers, because otherwise it will detect + // JSON, XML or ZIP formats before we have a chance of sniffing their content (for example, + // for RWPM). + SystemMediaTypeSniffer.run { + sniffHints(hints) ?: content?.let { sniffContent(it) } + }?.let { return it } + + return hints.mediaTypes.firstOrNull() } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSniffer.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSniffer.kt new file mode 100644 index 0000000000..63d59d9f66 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSniffer.kt @@ -0,0 +1,665 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.mediatype + +import android.webkit.MimeTypeMap +import java.io.File +import java.net.URLConnection +import java.util.Locale +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.json.JSONObject +import org.readium.r2.shared.extensions.tryOrNull +import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.publication.Manifest +import org.readium.r2.shared.publication.Publication + +/** + * Sniffs a [MediaType] from media type and file extension hints or asset content. + */ +public interface MediaTypeSniffer { + + /** + * Sniffs a [MediaType] from media type and file extension hints. + */ + public fun sniffHints(hints: MediaTypeHints): MediaType? = null + + /** + * Sniffs a [MediaType] from an asset [content]. + */ + public suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? = null +} + +/** + * Sniffs an XHTML document. + * + * Must precede the HTML sniffer. + */ +public object XhtmlMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("xht", "xhtml") || + hints.hasMediaType("application/xhtml+xml") + ) { + return MediaType.XHTML + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + content.contentAsXml()?.let { + if ( + it.name.lowercase(Locale.ROOT) == "html" && + it.namespace.lowercase(Locale.ROOT).contains("xhtml") + ) { + return MediaType.XHTML + } + } + return null + } +} + +/** Sniffs an HTML document. */ +public object HtmlMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("htm", "html") || + hints.hasMediaType("text/html") + ) { + return MediaType.HTML + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + // [contentAsXml] will fail if the HTML is not a proper XML document, hence the doctype check. + if ( + content.contentAsXml()?.name?.lowercase(Locale.ROOT) == "html" || + content.contentAsString()?.trimStart()?.take(15)?.lowercase() == "" + ) { + return MediaType.HTML + } + return null + } +} + +/** Sniffs an OPDS document. */ +public object OpdsMediaTypeSniffer : MediaTypeSniffer { + + override fun sniffHints(hints: MediaTypeHints): MediaType? { + // OPDS 1 + if (hints.hasMediaType("application/atom+xml;type=entry;profile=opds-catalog")) { + return MediaType.OPDS1_ENTRY + } + if (hints.hasMediaType("application/atom+xml;profile=opds-catalog;kind=navigation")) { + return MediaType.OPDS1_NAVIGATION_FEED + } + if (hints.hasMediaType("application/atom+xml;profile=opds-catalog;kind=acquisition")) { + return MediaType.OPDS1_ACQUISITION_FEED + } + if (hints.hasMediaType("application/atom+xml;profile=opds-catalog")) { + return MediaType.OPDS1 + } + + // OPDS 2 + if (hints.hasMediaType("application/opds+json")) { + return MediaType.OPDS2 + } + if (hints.hasMediaType("application/opds-publication+json")) { + return MediaType.OPDS2_PUBLICATION + } + + // OPDS Authentication Document. + if ( + hints.hasMediaType("application/opds-authentication+json") || + hints.hasMediaType("application/vnd.opds.authentication.v1.0+json") + ) { + return MediaType.OPDS_AUTHENTICATION + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + // OPDS 1 + content.contentAsXml()?.let { xml -> + if (xml.namespace == "http://www.w3.org/2005/Atom") { + if (xml.name == "feed") { + return MediaType.OPDS1 + } else if (xml.name == "entry") { + return MediaType.OPDS1_ENTRY + } + } + } + + // OPDS 2 + content.contentAsRwpm()?.let { rwpm -> + if (rwpm.linkWithRel("self")?.mediaType?.matches("application/opds+json") == true) { + return MediaType.OPDS2 + } + + /** + * Finds the first [Link] having a relation matching the given [predicate]. + */ + fun List.firstWithRelMatching(predicate: (String) -> Boolean): Link? = + firstOrNull { it.rels.any(predicate) } + + if (rwpm.links.firstWithRelMatching { it.startsWith("http://opds-spec.org/acquisition") } != null) { + return MediaType.OPDS2_PUBLICATION + } + } + + // OPDS Authentication Document. + if (content.containsJsonKeys("id", "title", "authentication")) { + return MediaType.OPDS_AUTHENTICATION + } + + return null + } +} + +/** Sniffs an LCP License Document. */ +public object LcpLicenseMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("lcpl") || + hints.hasMediaType("application/vnd.readium.lcp.license.v1.0+json") + ) { + return MediaType.LCP_LICENSE_DOCUMENT + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + if (content.containsJsonKeys("id", "issued", "provider", "encryption")) { + return MediaType.LCP_LICENSE_DOCUMENT + } + return null + } +} + +/** Sniffs a bitmap image. */ +public object BitmapMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("avif") || + hints.hasMediaType("image/avif") + ) { + return MediaType.AVIF + } + if ( + hints.hasFileExtension("bmp", "dib") || + hints.hasMediaType("image/bmp", "image/x-bmp") + ) { + return MediaType.BMP + } + if ( + hints.hasFileExtension("gif") || + hints.hasMediaType("image/gif") + ) { + return MediaType.GIF + } + if ( + hints.hasFileExtension("jpg", "jpeg", "jpe", "jif", "jfif", "jfi") || + hints.hasMediaType("image/jpeg") + ) { + return MediaType.JPEG + } + if ( + hints.hasFileExtension("jxl") || + hints.hasMediaType("image/jxl") + ) { + return MediaType.JXL + } + if ( + hints.hasFileExtension("png") || + hints.hasMediaType("image/png") + ) { + return MediaType.PNG + } + if ( + hints.hasFileExtension("tiff", "tif") || + hints.hasMediaType("image/tiff", "image/tiff-fx") + ) { + return MediaType.TIFF + } + if ( + hints.hasFileExtension("webp") || + hints.hasMediaType("image/webp") + ) { + return MediaType.WEBP + } + return null + } +} + +/** Sniffs a Readium Web Manifest. */ +public object WebPubManifestMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if (hints.hasMediaType("application/audiobook+json")) { + return MediaType.READIUM_AUDIOBOOK_MANIFEST + } + + if (hints.hasMediaType("application/divina+json")) { + return MediaType.DIVINA_MANIFEST + } + + if (hints.hasMediaType("application/webpub+json")) { + return MediaType.READIUM_WEBPUB_MANIFEST + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + val manifest: Manifest = + content.contentAsRwpm() ?: return null + + if (manifest.conformsTo(Publication.Profile.AUDIOBOOK)) { + return MediaType.READIUM_AUDIOBOOK_MANIFEST + } + + if (manifest.conformsTo(Publication.Profile.DIVINA)) { + return MediaType.DIVINA_MANIFEST + } + if (manifest.linkWithRel("self")?.mediaType?.matches("application/webpub+json") == true) { + return MediaType.READIUM_WEBPUB_MANIFEST + } + + return null + } +} + +/** Sniffs a Readium Web Publication, protected or not by LCP. */ +public object WebPubMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("audiobook") || + hints.hasMediaType("application/audiobook+zip") + ) { + return MediaType.READIUM_AUDIOBOOK + } + + if ( + hints.hasFileExtension("divina") || + hints.hasMediaType("application/divina+zip") + ) { + return MediaType.DIVINA + } + + if ( + hints.hasFileExtension("webpub") || + hints.hasMediaType("application/webpub+zip") + ) { + return MediaType.READIUM_WEBPUB + } + + if ( + hints.hasFileExtension("lcpa") || + hints.hasMediaType("application/audiobook+lcp") + ) { + return MediaType.LCP_PROTECTED_AUDIOBOOK + } + if ( + hints.hasFileExtension("lcpdf") || + hints.hasMediaType("application/pdf+lcp") + ) { + return MediaType.LCP_PROTECTED_PDF + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ContainerMediaTypeSnifferContent) { + return null + } + + // Reads a RWPM from a manifest.json archive entry. + val manifest: Manifest? = + try { + content.read("manifest.json") + ?.let { + Manifest.fromJSON(JSONObject(String(it))) + } + } catch (e: Exception) { + null + } + + if (manifest != null) { + val isLcpProtected = content.contains("/license.lcpl") + + if (manifest.conformsTo(Publication.Profile.AUDIOBOOK)) { + return if (isLcpProtected) { + MediaType.LCP_PROTECTED_AUDIOBOOK + } else { + MediaType.READIUM_AUDIOBOOK + } + } + if (manifest.conformsTo(Publication.Profile.DIVINA)) { + return MediaType.DIVINA + } + if (isLcpProtected && manifest.conformsTo(Publication.Profile.PDF)) { + return MediaType.LCP_PROTECTED_PDF + } + if (manifest.linkWithRel("self")?.mediaType?.matches("application/webpub+json") == true) { + return MediaType.READIUM_WEBPUB + } + } + + return null + } +} + +/** Sniffs a W3C Web Publication Manifest. */ +public object W3cWpubMediaTypeSniffer : MediaTypeSniffer { + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + // Somehow, [JSONObject] can't access JSON-LD keys such as `@content`. + val string = content.contentAsString() ?: "" + if ( + string.contains("@context") && + string.contains("https://www.w3.org/ns/wp-context") + ) { + return MediaType.W3C_WPUB_MANIFEST + } + + return null + } +} + +/** + * Sniffs an EPUB publication. + * + * Reference: https://www.w3.org/publishing/epub3/epub-ocf.html#sec-zip-container-mime + */ +public object EpubMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("epub") || + hints.hasMediaType("application/epub+zip") + ) { + return MediaType.EPUB + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ContainerMediaTypeSnifferContent) { + return null + } + + val mimetype = content.read("mimetype") + ?.let { String(it, charset = Charsets.US_ASCII).trim() } + if (mimetype == "application/epub+zip") { + return MediaType.EPUB + } + + return null + } +} + +/** + * Sniffs a Lightweight Packaging Format (LPF). + * + * References: + * - https://www.w3.org/TR/lpf/ + * - https://www.w3.org/TR/pub-manifest/ + */ +public object LpfMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("lpf") || + hints.hasMediaType("application/lpf+zip") + ) { + return MediaType.LPF + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ContainerMediaTypeSnifferContent) { + return null + } + + if (content.contains("/index.html")) { + return MediaType.LPF + } + + // Somehow, [JSONObject] can't access JSON-LD keys such as `@content`. + content.read("publication.json") + ?.let { String(it) } + ?.let { manifest -> + if ( + manifest.contains("@context") && + manifest.contains("https://www.w3.org/ns/pub-context") + ) { + return MediaType.LPF + } + } + + return null + } +} + +/** + * Sniffs a simple Archive-based format, like Comic Book Archive or Zipped Audio Book. + * + * Reference: https://wiki.mobileread.com/wiki/CBR_and_CBZ + */ +public object ArchiveMediaTypeSniffer : MediaTypeSniffer { + + /** + * Authorized extensions for resources in a CBZ archive. + * Reference: https://wiki.mobileread.com/wiki/CBR_and_CBZ + */ + private val cbzExtensions = listOf( + // bitmap + "bmp", "dib", "gif", "jif", "jfi", "jfif", "jpg", "jpeg", "png", "tif", "tiff", "webp", + // metadata + "acbf", "xml" + ) + + /** + * Authorized extensions for resources in a ZAB archive (Zipped Audio Book). + */ + private val zabExtensions = listOf( + // audio + "aac", + "aiff", + "alac", + "flac", + "m4a", + "m4b", + "mp3", + "ogg", + "oga", + "mogg", + "opus", + "wav", + "webm", + // playlist + "asx", + "bio", + "m3u", + "m3u8", + "pla", + "pls", + "smil", + "vlc", + "wpl", + "xspf", + "zpl" + ) + + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("cbz") || + hints.hasMediaType( + "application/vnd.comicbook+zip", + "application/x-cbz", + "application/x-cbr" + ) + ) { + return MediaType.CBZ + } + if (hints.hasFileExtension("zab")) { + return MediaType.ZAB + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ContainerMediaTypeSnifferContent) { + return null + } + + fun isIgnored(file: File): Boolean = + file.name.startsWith(".") || file.name == "Thumbs.db" + + suspend fun archiveContainsOnlyExtensions(fileExtensions: List): Boolean = + content.entries()?.all { path -> + val file = File(path) + isIgnored(file) || fileExtensions.contains(file.extension.lowercase(Locale.ROOT)) + } ?: false + + if (archiveContainsOnlyExtensions(cbzExtensions)) { + return MediaType.CBZ + } + if (archiveContainsOnlyExtensions(zabExtensions)) { + return MediaType.ZAB + } + + return null + } +} + +/** + * Sniffs a PDF document. + * + * Reference: https://www.loc.gov/preservation/digital/formats/fdd/fdd000123.shtml + */ +public object PdfMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if ( + hints.hasFileExtension("pdf") || + hints.hasMediaType("application/pdf") + ) { + return MediaType.PDF + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + if (content.read(0L until 5L)?.toString(Charsets.UTF_8) == "%PDF-") { + return MediaType.PDF + } + + return null + } +} + +/** Sniffs a JSON document. */ +public object JsonMediaTypeSniffer : MediaTypeSniffer { + override fun sniffHints(hints: MediaTypeHints): MediaType? { + if (hints.hasMediaType("application/problem+json")) { + return MediaType.JSON_PROBLEM_DETAILS + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + if (content.contentAsJson() != null) { + return MediaType.JSON + } + return null + } +} + +/** + * Sniffs the system-wide registered media types using [MimeTypeMap] and + * [URLConnection.guessContentTypeFromStream]. + */ +public object SystemMediaTypeSniffer : MediaTypeSniffer { + + private val mimetypes = tryOrNull { MimeTypeMap.getSingleton() } + + override fun sniffHints(hints: MediaTypeHints): MediaType? { + for (mediaType in hints.mediaTypes) { + return sniffType(mediaType.toString()) ?: continue + } + + for (extension in hints.fileExtensions) { + return sniffExtension(extension) ?: continue + } + + return null + } + + override suspend fun sniffContent(content: MediaTypeSnifferContent): MediaType? { + if (content !is ResourceMediaTypeSnifferContent) { + return null + } + + return withContext(Dispatchers.IO) { + content.contentAsStream() + .let { URLConnection.guessContentTypeFromStream(it) } + ?.let { sniffType(it) } + } + } + + private fun sniffType(type: String): MediaType? { + val extension = mimetypes?.getExtensionFromMimeType(type) + ?: return null + val preferredType = mimetypes.getMimeTypeFromExtension(extension) + ?: return null + return MediaType(preferredType) + } + + private fun sniffExtension(extension: String): MediaType? = + mimetypes?.getMimeTypeFromExtension(extension) + ?.let { MediaType(it) } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSnifferContent.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSnifferContent.kt new file mode 100644 index 0000000000..9f7e359e14 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/MediaTypeSnifferContent.kt @@ -0,0 +1,131 @@ +package org.readium.r2.shared.util.mediatype + +import java.io.ByteArrayInputStream +import java.io.InputStream +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.json.JSONObject +import org.readium.r2.shared.extensions.read +import org.readium.r2.shared.extensions.tryOrNull +import org.readium.r2.shared.parser.xml.ElementNode +import org.readium.r2.shared.parser.xml.XmlParser +import org.readium.r2.shared.publication.Manifest + +/** + * Provides read access to an asset content. + */ +public sealed interface MediaTypeSnifferContent + +/** + * Provides read access to a resource content. + */ +public interface ResourceMediaTypeSnifferContent : MediaTypeSnifferContent { + + /** + * Reads all the bytes or the given [range]. + * + * It can be used to check a file signature, aka magic number. + * See https://en.wikipedia.org/wiki/List_of_file_signatures + */ + public suspend fun read(range: LongRange? = null): ByteArray? + + /** + * Content as plain text. + * + * It will extract the charset parameter from the media type hints to figure out an encoding. + * Otherwise, fallback on UTF-8. + */ + public suspend fun contentAsString(): String? = + read()?.let { + tryOrNull { + withContext(Dispatchers.Default) { String(it) } + } + } + + /** Content as an XML document. */ + public suspend fun contentAsXml(): ElementNode? = + read()?.let { + tryOrNull { + withContext(Dispatchers.Default) { + XmlParser().parse(ByteArrayInputStream(it)) + } + } + } + + /** + * Content parsed from JSON. + */ + public suspend fun contentAsJson(): JSONObject? = + contentAsString()?.let { + tryOrNull { + withContext(Dispatchers.Default) { + JSONObject(it) + } + } + } + + /** Readium Web Publication Manifest parsed from the content. */ + public suspend fun contentAsRwpm(): Manifest? = + Manifest.fromJSON(contentAsJson()) + + /** + * Raw bytes stream of the content. + * + * A byte stream can be useful when sniffers only need to read a few bytes at the beginning of + * the file. + */ + public suspend fun contentAsStream(): InputStream = + ByteArrayInputStream(read() ?: ByteArray(0)) +} + +/** + * Returns whether the content is a JSON object containing all of the given root keys. + */ +public suspend fun ResourceMediaTypeSnifferContent.containsJsonKeys(vararg keys: String): Boolean { + val json = contentAsJson() ?: return false + return json.keys().asSequence().toSet().containsAll(keys.toList()) +} + +/** + * Provides read access to a container's resources. + */ +public interface ContainerMediaTypeSnifferContent : MediaTypeSnifferContent { + /** + * Returns all the known entry paths in the container. + */ + public suspend fun entries(): Set? + + /** + * Returns the entry data at the given [path] in this container. + */ + public suspend fun read(path: String, range: LongRange? = null): ByteArray? +} + +/** + * Returns whether an entry exists in the container. + */ +public suspend fun ContainerMediaTypeSnifferContent.contains(path: String): Boolean = + entries()?.contains(path) + ?: (read(path, range = 0L..1L) != null) + +/** + * A [ResourceMediaTypeSnifferContent] built from a raw byte array. + */ +public class BytesResourceMediaTypeSnifferContent( + bytes: suspend () -> ByteArray +) : ResourceMediaTypeSnifferContent { + + private val bytesFactory = bytes + private lateinit var _bytes: ByteArray + + private suspend fun bytes(): ByteArray { + if (::_bytes.isInitialized) { + return _bytes + } + _bytes = bytesFactory() + return _bytes + } + + override suspend fun read(range: LongRange?): ByteArray = + bytes().read(range) +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt deleted file mode 100644 index 374d4cbba7..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/Sniffer.kt +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.util.mediatype - -import android.webkit.MimeTypeMap -import java.io.File -import java.net.URLConnection -import java.util.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.json.JSONObject -import org.readium.r2.shared.extensions.tryOrNull -import org.readium.r2.shared.publication.* - -/** - * Determines if the provided content matches a known media type. - * - * The context holds the file metadata and cached content, which are shared among the sniffers. - */ -public typealias Sniffer = suspend (context: SnifferContext) -> MediaType? - -/** - * Default media type sniffers provided by Readium. - */ -public object Sniffers { - - /** - * The default sniffers provided by Readium 2 to resolve a [MediaType]. - * The sniffers order is important, because some formats are subsets of other formats. - */ - public val all: List = listOf( - ::xhtml, ::html, ::opds, ::lcpLicense, ::bitmap, ::webpubManifest, ::webpub, ::w3cWPUB, - ::epub, ::lpf, ::archive, ::pdf, ::json - ) - - /** - * Sniffs an XHTML document. - * - * Must precede the HTML sniffer. - */ - public suspend fun xhtml(context: SnifferContext): MediaType? { - if (context.hasFileExtension("xht", "xhtml") || context.hasMediaType("application/xhtml+xml")) { - return MediaType.XHTML - } - - if (context !is ResourceSnifferContext) { - return null - } - - context.contentAsXml()?.let { - if (it.name.lowercase(Locale.ROOT) == "html" && it.namespace.lowercase(Locale.ROOT).contains("xhtml")) { - return MediaType.XHTML - } - } - return null - } - - /** Sniffs an HTML document. */ - public suspend fun html(context: SnifferContext): MediaType? { - if (context.hasFileExtension("htm", "html") || context.hasMediaType("text/html")) { - return MediaType.HTML - } - - if (context !is ResourceSnifferContext) { - return null - } - - // [contentAsXml] will fail if the HTML is not a proper XML document, hence the doctype check. - if ( - context.contentAsXml()?.name?.lowercase(Locale.ROOT) == "html" || - context.contentAsString()?.trimStart()?.take(15)?.lowercase() == "" - ) { - return MediaType.HTML - } - return null - } - - /** Sniffs an OPDS document. */ - public suspend fun opds(context: SnifferContext): MediaType? { - // OPDS 1 - if (context.hasMediaType("application/atom+xml;type=entry;profile=opds-catalog")) { - return MediaType.OPDS1_ENTRY - } - if (context.hasMediaType("application/atom+xml;profile=opds-catalog")) { - return MediaType.OPDS1 - } - - // OPDS 2 - if (context.hasMediaType("application/opds+json")) { - return MediaType.OPDS2 - } - if (context.hasMediaType("application/opds-publication+json")) { - return MediaType.OPDS2_PUBLICATION - } - - // OPDS Authentication Document. - if (context.hasMediaType("application/opds-authentication+json") || context.hasMediaType("application/vnd.opds.authentication.v1.0+json")) { - return MediaType.OPDS_AUTHENTICATION - } - - if (context !is ResourceSnifferContext) { - return null - } - - // OPDS 1 - context.contentAsXml()?.let { xml -> - if (xml.namespace == "http://www.w3.org/2005/Atom") { - if (xml.name == "feed") { - return MediaType.OPDS1 - } else if (xml.name == "entry") { - return MediaType.OPDS1_ENTRY - } - } - } - - // OPDS 2 - context.contentAsRwpm()?.let { rwpm -> - if (rwpm.linkWithRel("self")?.mediaType?.matches("application/opds+json") == true) { - return MediaType.OPDS2 - } - if (rwpm.links.firstWithRelMatching { it.startsWith("http://opds-spec.org/acquisition") } != null) { - return MediaType.OPDS2_PUBLICATION - } - } - - // OPDS Authentication Document. - if (context.containsJsonKeys("id", "title", "authentication")) { - return MediaType.OPDS_AUTHENTICATION - } - - return null - } - - /** Sniffs an LCP License Document. */ - public suspend fun lcpLicense(context: SnifferContext): MediaType? { - if (context.hasFileExtension("lcpl") || context.hasMediaType("application/vnd.readium.lcp.license.v1.0+json")) { - return MediaType.LCP_LICENSE_DOCUMENT - } - - if (context !is ResourceSnifferContext) { - return null - } - - if (context.containsJsonKeys("id", "issued", "provider", "encryption")) { - return MediaType.LCP_LICENSE_DOCUMENT - } - return null - } - - /** Sniffs a bitmap image. */ - @Suppress("RedundantSuspendModifier") - public suspend fun bitmap(context: SnifferContext): MediaType? { - if (context.hasFileExtension("avif") || context.hasMediaType("image/avif")) { - return MediaType.AVIF - } - if (context.hasFileExtension("bmp", "dib") || context.hasMediaType("image/bmp", "image/x-bmp")) { - return MediaType.BMP - } - if (context.hasFileExtension("gif") || context.hasMediaType("image/gif")) { - return MediaType.GIF - } - if (context.hasFileExtension("jpg", "jpeg", "jpe", "jif", "jfif", "jfi") || context.hasMediaType("image/jpeg")) { - return MediaType.JPEG - } - if (context.hasFileExtension("jxl") || context.hasMediaType("image/jxl")) { - return MediaType.JXL - } - if (context.hasFileExtension("png") || context.hasMediaType("image/png")) { - return MediaType.PNG - } - if (context.hasFileExtension("tiff", "tif") || context.hasMediaType("image/tiff", "image/tiff-fx")) { - return MediaType.TIFF - } - if (context.hasFileExtension("webp") || context.hasMediaType("image/webp")) { - return MediaType.WEBP - } - return null - } - - /** Sniffs a Readium Web Manifest. */ - public suspend fun webpubManifest(context: SnifferContext): MediaType? { - if (context.hasMediaType("application/audiobook+json")) { - return MediaType.READIUM_AUDIOBOOK_MANIFEST - } - - if (context.hasMediaType("application/divina+json")) { - return MediaType.DIVINA_MANIFEST - } - - if (context.hasMediaType("application/webpub+json")) { - return MediaType.READIUM_WEBPUB_MANIFEST - } - - if (context !is ResourceSnifferContext) { - return null - } - - val manifest: Manifest = - context.contentAsRwpm() ?: return null - - if (manifest.conformsTo(Publication.Profile.AUDIOBOOK)) { - return MediaType.READIUM_AUDIOBOOK_MANIFEST - } - - if (manifest.conformsTo(Publication.Profile.DIVINA)) { - return MediaType.DIVINA_MANIFEST - } - if (manifest.linkWithRel("self")?.mediaType?.matches("application/webpub+json") == true) { - return MediaType.READIUM_WEBPUB_MANIFEST - } - - return null - } - - /** Sniffs a Readium Web Publication, protected or not by LCP. */ - public suspend fun webpub(context: SnifferContext): MediaType? { - if (context.hasFileExtension("audiobook") || context.hasMediaType("application/audiobook+zip")) { - return MediaType.READIUM_AUDIOBOOK - } - - if (context.hasFileExtension("divina") || context.hasMediaType("application/divina+zip")) { - return MediaType.DIVINA - } - - if (context.hasFileExtension("webpub") || context.hasMediaType("application/webpub+zip")) { - return MediaType.READIUM_WEBPUB - } - - if (context.hasFileExtension("lcpa") || context.hasMediaType("application/audiobook+lcp")) { - return MediaType.LCP_PROTECTED_AUDIOBOOK - } - if (context.hasFileExtension("lcpdf") || context.hasMediaType("application/pdf+lcp")) { - return MediaType.LCP_PROTECTED_PDF - } - - if (context !is ContainerSnifferContext) { - return null - } - - // Reads a RWPM from a manifest.json archive entry. - val manifest: Manifest? = - try { - context.readArchiveEntryAt("manifest.json") - ?.let { Manifest.fromJSON(JSONObject(String(it))) } - } catch (e: Exception) { - null - } - - if (manifest != null) { - val isLcpProtected = context.containsArchiveEntryAt("license.lcpl") - - if (manifest.conformsTo(Publication.Profile.AUDIOBOOK)) { - return if (isLcpProtected) MediaType.LCP_PROTECTED_AUDIOBOOK else MediaType.READIUM_AUDIOBOOK - } - if (manifest.conformsTo(Publication.Profile.DIVINA)) { - return MediaType.DIVINA - } - if (isLcpProtected && manifest.conformsTo(Publication.Profile.PDF)) { - return MediaType.LCP_PROTECTED_PDF - } - if (manifest.linkWithRel("self")?.mediaType?.matches("application/webpub+json") == true) { - return MediaType.READIUM_WEBPUB - } - } - - return null - } - - /** Sniffs a W3C Web Publication Manifest. */ - public suspend fun w3cWPUB(context: SnifferContext): MediaType? { - if (context !is ResourceSnifferContext) { - return null - } - - // Somehow, [JSONObject] can't access JSON-LD keys such as `@context`. - val content = context.contentAsString() ?: "" - if (content.contains("@context") && content.contains("https://www.w3.org/ns/wp-context")) { - return MediaType.W3C_WPUB_MANIFEST - } - - return null - } - - /** - * Sniffs an EPUB publication. - * - * Reference: https://www.w3.org/publishing/epub3/epub-ocf.html#sec-zip-container-mime - */ - public suspend fun epub(context: SnifferContext): MediaType? { - if (context.hasFileExtension("epub") || context.hasMediaType("application/epub+zip")) { - return MediaType.EPUB - } - - if (context !is ContainerSnifferContext) { - return null - } - - val mimetype = context.readArchiveEntryAt("mimetype") - ?.let { String(it, charset = Charsets.US_ASCII).trim() } - if (mimetype == "application/epub+zip") { - return MediaType.EPUB - } - - return null - } - - /** - * Sniffs a Lightweight Packaging Format (LPF). - * - * References: - * - https://www.w3.org/TR/lpf/ - * - https://www.w3.org/TR/pub-manifest/ - */ - public suspend fun lpf(context: SnifferContext): MediaType? { - if (context.hasFileExtension("lpf") || context.hasMediaType("application/lpf+zip")) { - return MediaType.LPF - } - - if (context !is ContainerSnifferContext) { - return null - } - - if (context.containsArchiveEntryAt("index.html")) { - return MediaType.LPF - } - - // Somehow, [JSONObject] can't access JSON-LD keys such as `@context`. - context.readArchiveEntryAt("publication.json") - ?.let { String(it) } - ?.let { manifest -> - if (manifest.contains("@context") && manifest.contains("https://www.w3.org/ns/pub-context")) { - return MediaType.LPF - } - } - - return null - } - - /** - * Authorized extensions for resources in a CBZ archive. - * Reference: https://wiki.mobileread.com/wiki/CBR_and_CBZ - */ - private val CBZ_EXTENSIONS = listOf( - // bitmap - "bmp", "dib", "gif", "jif", "jfi", "jfif", "jpg", "jpeg", "png", "tif", "tiff", "webp", - // metadata - "acbf", "xml" - ) - - /** - * Authorized extensions for resources in a ZAB archive (Zipped Audio Book). - */ - private val ZAB_EXTENSIONS = listOf( - // audio - "aac", "aiff", "alac", "flac", "m4a", "m4b", "mp3", "ogg", "oga", "mogg", "opus", "wav", "webm", - // playlist - "asx", "bio", "m3u", "m3u8", "pla", "pls", "smil", "vlc", "wpl", "xspf", "zpl" - ) - - /** - * Sniffs a simple Archive-based format, like Comic Book Archive or Zipped Audio Book. - * - * Reference: https://wiki.mobileread.com/wiki/CBR_and_CBZ - */ - public suspend fun archive(context: SnifferContext): MediaType? { - if (context.hasFileExtension("cbz") || context.hasMediaType("application/vnd.comicbook+zip", "application/x-cbz", "application/x-cbr")) { - return MediaType.CBZ - } - if (context.hasFileExtension("zab")) { - return MediaType.ZAB - } - - if (context !is ContainerSnifferContext) { - return null - } - - fun isIgnored(file: File): Boolean = - file.name.startsWith(".") || file.name == "Thumbs.db" - - suspend fun archiveContainsOnlyExtensions(fileExtensions: List): Boolean = - context.archiveEntriesAllSatisfy { entry -> - val file = File(entry.path) - isIgnored(file) || fileExtensions.contains(file.extension.lowercase(Locale.ROOT)) - } - - if (archiveContainsOnlyExtensions(CBZ_EXTENSIONS)) { - return MediaType.CBZ - } - if (archiveContainsOnlyExtensions(ZAB_EXTENSIONS)) { - return MediaType.ZAB - } - - return null - } - - /** - * Sniffs a PDF document. - * - * Reference: https://www.loc.gov/preservation/digital/formats/fdd/fdd000123.shtml - */ - public suspend fun pdf(context: SnifferContext): MediaType? { - if (context.hasFileExtension("pdf") || context.hasMediaType("application/pdf")) { - return MediaType.PDF - } - - if (context !is ResourceSnifferContext) { - return null - } - - if (context.read(0L until 5L)?.toString(Charsets.UTF_8) == "%PDF-") { - return MediaType.PDF - } - - return null - } - - /** Sniffs a JSON document. */ - public suspend fun json(context: SnifferContext): MediaType? { - if (context.hasMediaType("application/problem+json")) { - return MediaType.JSON_PROBLEM_DETAILS - } - - if (context !is ResourceSnifferContext) { - return null - } - - if (context.contentAsJson() != null) { - return MediaType.JSON - } - return null - } - - /** - * Sniffs the system-wide registered media types using [MimeTypeMap] and - * [URLConnection.guessContentTypeFromStream]. - */ - public suspend fun system(context: SnifferContext): MediaType? { - val mimetypes = tryOrNull { MimeTypeMap.getSingleton() } - ?: return null - - fun sniffExtension(extension: String): MediaType? { - val type = mimetypes.getMimeTypeFromExtension(extension) - ?: return null - val preferredExtension = mimetypes.getExtensionFromMimeType(type) - ?: return null - return MediaType.parse(type, fileExtension = preferredExtension) - } - - fun sniffType(type: String): MediaType? { - val extension = mimetypes.getExtensionFromMimeType(type) - ?: return null - val preferredType = mimetypes.getMimeTypeFromExtension(extension) - ?: return null - return MediaType.parse(preferredType, fileExtension = extension) - } - - for (mediaType in context.mediaTypes) { - return sniffType(mediaType.toString()) ?: continue - } - - for (extension in context.fileExtensions) { - return sniffExtension(extension) ?: continue - } - - if (context !is ResourceSnifferContext) { - return null - } - - return withContext(Dispatchers.IO) { - context.contentAsStream() - .let { URLConnection.guessContentTypeFromStream(it) } - ?.let { sniffType(it) } - } - } -} - -/** - * Finds the first [Link] having a relation matching the given [predicate]. - */ -private fun List.firstWithRelMatching(predicate: (String) -> Boolean): Link? = - firstOrNull { it.rels.any(predicate) } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt deleted file mode 100644 index 435f0fe339..0000000000 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/mediatype/SnifferContext.kt +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2020 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.util.mediatype - -import java.io.File -import java.io.InputStream -import java.nio.charset.Charset -import java.util.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.json.JSONObject -import org.readium.r2.shared.error.getOrElse -import org.readium.r2.shared.parser.xml.ElementNode -import org.readium.r2.shared.publication.Manifest -import org.readium.r2.shared.resource.* -import org.readium.r2.shared.util.Url -import timber.log.Timber - -public sealed class SnifferContext( - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList() -) { - /** Media type hints. */ - public val mediaTypes: List = mediaTypes - .mapNotNull { MediaType.parse(it) } - - /** File extension hints. */ - public val fileExtensions: List = fileExtensions - .map { it.lowercase(Locale.ROOT) } - - /** Finds the first [Charset] declared in the media types' `charset` parameter. */ - public val charset: Charset? get() = - this.mediaTypes.firstNotNullOfOrNull { it.charset } - - /** Returns whether this context has any of the given file extensions, ignoring case. */ - public fun hasFileExtension(vararg fileExtensions: String): Boolean { - for (fileExtension in fileExtensions) { - if (this.fileExtensions.contains(fileExtension.lowercase(Locale.ROOT))) { - return true - } - } - return false - } - - /** - * Returns whether this context has any of the given media type, ignoring case and extra - * parameters. - * - * Implementation note: Use [MediaType] to handle the comparison to avoid edge cases. - */ - public fun hasMediaType(vararg mediaTypes: String): Boolean { - @Suppress("NAME_SHADOWING") - val mediaTypes = mediaTypes.mapNotNull { MediaType.parse(it) } - for (mediaType in mediaTypes) { - if (this.mediaTypes.any { mediaType.contains(it) }) { - return true - } - } - return false - } - - public abstract suspend fun release() -} - -public class HintSnifferContext( - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList() -) : SnifferContext(mediaTypes, fileExtensions) { - - override suspend fun release() {} -} - -public sealed class ContentAwareSnifferContext( - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList() -) : SnifferContext(mediaTypes, fileExtensions) - -/** - * A companion type of [Sniffer] holding the type hints (file extensions, media types) and - * providing an access to the file content. - * - * @param resource Underlying content holder. - * @param mediaTypes Media type hints. - * @param fileExtensions File extension hints. - */ -public class ResourceSnifferContext internal constructor( - public val resource: Resource, - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList() -) : ContentAwareSnifferContext(mediaTypes, fileExtensions) { - - /** - * Content as plain text. - * - * It will extract the charset parameter from the media type hints to figure out an encoding. - * Otherwise, fallback on UTF-8. - */ - public suspend fun contentAsString(): String? = - try { - if (!loadedContentAsString) { - loadedContentAsString = true - _contentAsString = resource - .readAsString(charset ?: Charset.defaultCharset()) - .getOrNull() - } - _contentAsString - } catch (e: OutOfMemoryError) { // We don't want to catch any Error, only OOM. - Timber.e(e) - null - } - - private var loadedContentAsString: Boolean = false - private var _contentAsString: String? = null - - /** Content as an XML document. */ - public suspend fun contentAsXml(): ElementNode? { - if (!loadedContentAsXml) { - loadedContentAsXml = true - _contentAsXml = withContext(Dispatchers.IO) { - try { - resource.readAsXml().getOrNull() - } catch (e: Exception) { - null - } - } - } - - return _contentAsXml - } - - private var loadedContentAsXml: Boolean = false - private var _contentAsXml: ElementNode? = null - - /** - * Content parsed from JSON. - */ - public suspend fun contentAsJson(): JSONObject? = - try { - contentAsString()?.let { JSONObject(it) } - } catch (e: Exception) { - null - } - - /** Readium Web Publication Manifest parsed from the content. */ - public suspend fun contentAsRwpm(): Manifest? = - Manifest.fromJSON(contentAsJson()) - - /** - * Raw bytes stream of the content. - * - * A byte stream can be useful when sniffers only need to read a few bytes at the beginning of - * the file. - */ - public suspend fun contentAsStream(): InputStream = - ResourceInputStream(resource) - - /** - * Reads all the bytes or the given [range]. - * - * It can be used to check a file signature, aka magic number. - * See https://en.wikipedia.org/wiki/List_of_file_signatures - */ - public suspend fun read(range: LongRange? = null): ByteArray? = - resource.read(range).getOrNull() - - /** - * Returns whether the content is a JSON object containing all of the given root keys. - */ - internal suspend fun containsJsonKeys(vararg keys: String): Boolean { - val json = contentAsJson() ?: return false - return json.keys().asSequence().toSet().containsAll(keys.toList()) - } - - override suspend fun release() { - resource.close() - } -} - -/** - * A companion type of [Sniffer] holding the type hints (file extensions, media types) and - * providing an access to the file content. - * - * @param container Underlying content holder. - * @param mediaTypes Media type hints. - * @param fileExtensions File extension hints. - */ -public class ContainerSnifferContext internal constructor( - public val container: Container, - public val isExploded: Boolean, - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList() -) : ContentAwareSnifferContext(mediaTypes, fileExtensions) { - - /** - * Returns whether an Archive entry exists in this file. - */ - internal suspend fun containsArchiveEntryAt(path: String): Boolean = - container.entry(path).read(0 until 16L).isSuccess - - /** - * Returns the Archive entry data at the given [path] in this file. - */ - internal suspend fun readArchiveEntryAt(path: String): ByteArray? { - val archive = container - - return withContext(Dispatchers.IO) { - val entry = archive.entry(path) - val bytes = entry.read().getOrNull() - entry.close() - bytes - } - } - - /** - * Returns whether all the Archive entry paths satisfy the given `predicate`. - */ - internal suspend fun archiveEntriesAllSatisfy(predicate: (Container.Entry) -> Boolean): Boolean = - container.entries() - ?.all(predicate) - ?: false - - override suspend fun release() { - container.close() - } -} - -internal class UrlSnifferContextFactory( - private val resourceFactory: ResourceFactory, - private val containerFactory: ContainerFactory, - private val archiveFactory: ArchiveFactory, -) { - - suspend fun createContext( - url: Url, - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList() - ): ContentAwareSnifferContext? { - val resource = resourceFactory - .create(url) - .getOrElse { - when (it) { - is ResourceFactory.Error.NotAResource -> - return tryCreateContainerContext( - url = url, - mediaTypes = mediaTypes, - fileExtensions = fileExtensions - ) - else -> return null - } - } - - return archiveFactory.create(resource, password = null) - .fold( - { - ContainerSnifferContext( - container = it, - isExploded = false, - mediaTypes = mediaTypes, - fileExtensions = fileExtensions - ) - }, - { - ResourceSnifferContext( - resource = resource, - mediaTypes = mediaTypes + - listOfNotNull(resource.mediaType().getOrNull()), - fileExtensions = fileExtensions + - listOfNotNull(resource.name().getOrNull()?.let { File(it).extension }) - ) - } - ) - } - - private suspend fun tryCreateContainerContext( - url: Url, - mediaTypes: List, - fileExtensions: List - ): ContentAwareSnifferContext? { - val container = containerFactory.create(url) - .getOrNull() - ?: return null - - return ContainerSnifferContext( - container = container, - isExploded = true, - mediaTypes = mediaTypes, - fileExtensions = fileExtensions - ) - } -} - -internal class BytesSnifferContextFactory( - private val archiveFactory: ArchiveFactory -) { - - suspend fun createContext( - bytes: ByteArray, - mediaTypes: List = emptyList(), - fileExtensions: List = emptyList(), - ): ContentAwareSnifferContext { - val resource: Resource = BytesResource(bytes) - return archiveFactory.create(resource, password = null) - .fold( - { ContainerSnifferContext(it, false, mediaTypes, fileExtensions) }, - { ResourceSnifferContext(resource, mediaTypes, fileExtensions) } - ) - } -} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt index f283fa3bf0..bcd19dc66e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/pdf/PdfDocument.kt @@ -14,12 +14,12 @@ import android.graphics.Bitmap import java.io.File import kotlin.reflect.KClass import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.PublicationServicesHolder import org.readium.r2.shared.publication.ReadingProgression import org.readium.r2.shared.publication.services.cacheService +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.SuspendingCloseable import org.readium.r2.shared.util.cache.Cache import org.readium.r2.shared.util.mediatype.MediaType @@ -33,7 +33,7 @@ public interface PdfDocumentFactory { public suspend fun open(file: File, password: String?): T /** Opens a PDF from a Fetcher resource. */ - public suspend fun open(resource: Fetcher.Resource, password: String?): T + public suspend fun open(resource: Resource, password: String?): T } /** @@ -64,12 +64,14 @@ private class CachingPdfDocumentFactory( } } - override suspend fun open(resource: Fetcher.Resource, password: String?): T = - cache.transaction { - getOrPut(resource.link().href) { + override suspend fun open(resource: Resource, password: String?): T { + val key = resource.source?.toString() ?: return factory.open(resource, password) + return cache.transaction { + getOrPut(key) { factory.open(resource, password) } } + } } /** @@ -149,7 +151,7 @@ public fun List.toLinks(documentHref: String): List= Build.VERSION_CODES.N) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { IcuTextTokenizer(language = language, unit = unit) - else + } else { NaiveTextTokenizer(unit = unit) + } ) } @@ -54,7 +55,9 @@ public class IcuTextTokenizer(language: Language?, unit: TextUnit) : TextTokeniz iterator = when (unit) { TextUnit.Word -> BreakIterator.getWordInstance(loc) TextUnit.Sentence -> BreakIterator.getSentenceInstance(loc) - TextUnit.Paragraph -> throw IllegalArgumentException("IcuTextTokenizer does not handle TextContentUnit.Paragraph") + TextUnit.Paragraph -> throw IllegalArgumentException( + "IcuTextTokenizer does not handle TextContentUnit.Paragraph" + ) } } @@ -84,7 +87,9 @@ public class NaiveTextTokenizer(unit: TextUnit) : TextTokenizer { private val iterator: java.text.BreakIterator = when (unit) { TextUnit.Word -> java.text.BreakIterator.getWordInstance() TextUnit.Sentence -> java.text.BreakIterator.getSentenceInstance() - TextUnit.Paragraph -> throw IllegalArgumentException("NaiveTextTokenizer does not handle TextContentUnit.Paragraph") + TextUnit.Paragraph -> throw IllegalArgumentException( + "NaiveTextTokenizer does not handle TextContentUnit.Paragraph" + ) } override fun tokenize(data: String): List { diff --git a/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt b/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt index 4c6515de1f..7e7fda0700 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/TestUtils.kt @@ -17,10 +17,7 @@ import org.json.JSONObject import org.junit.Assert.assertEquals import org.readium.r2.shared.extensions.toListTest import org.readium.r2.shared.extensions.toMapTest -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.publication.Link import org.readium.r2.shared.resource.Resource -import org.readium.r2.shared.util.use /** * Asserts that two [JSONObject] are equal. @@ -52,12 +49,4 @@ class Fixtures(val path: String? = null) { internal fun Resource.readBlocking(range: LongRange? = null) = runBlocking { read(range) } -internal fun Fetcher.readBlocking(href: String) = runBlocking { get(Link(href = href)).use { it.readBlocking() } } - internal fun Resource.lengthBlocking() = runBlocking { length() } - -internal fun Fetcher.lengthBlocking(href: String) = runBlocking { get(Link(href = href)).use { it.lengthBlocking() } } - -internal fun Fetcher.Resource.linkBlocking() = runBlocking { link() } - -internal fun Fetcher.linkBlocking(href: String) = runBlocking { get(Link(href = href)).use { it.linkBlocking() } } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/extensions/URLTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/extensions/URLTest.kt index 2287a3ad89..1c17160783 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/extensions/URLTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/extensions/URLTest.kt @@ -16,13 +16,28 @@ import org.junit.Test class URLTest { @Test fun `remove last component`() { - assertEquals(URL("http://domain.com/two/"), URL("http://domain.com/two/paths").removeLastComponent()) - assertEquals(URL("http://domain.com/two/"), URL("http://domain.com/two/paths/").removeLastComponent()) + assertEquals( + URL("http://domain.com/two/"), + URL("http://domain.com/two/paths").removeLastComponent() + ) + assertEquals( + URL("http://domain.com/two/"), + URL("http://domain.com/two/paths/").removeLastComponent() + ) assertEquals(URL("http://domain.com/"), URL("http://domain.com/path").removeLastComponent()) - assertEquals(URL("http://domain.com/"), URL("http://domain.com/path/").removeLastComponent()) + assertEquals( + URL("http://domain.com/"), + URL("http://domain.com/path/").removeLastComponent() + ) assertEquals(URL("http://domain.com/"), URL("http://domain.com/").removeLastComponent()) assertEquals(URL("http://domain.com"), URL("http://domain.com").removeLastComponent()) - assertEquals(URL("http://domain.com/two/"), URL("http://domain.com/two/paths?a=1&b=2").removeLastComponent()) - assertEquals(URL("http://domain.com/two/"), URL("http://domain.com/two/paths/?a=1b=2").removeLastComponent()) + assertEquals( + URL("http://domain.com/two/"), + URL("http://domain.com/two/paths?a=1&b=2").removeLastComponent() + ) + assertEquals( + URL("http://domain.com/two/"), + URL("http://domain.com/two/paths/?a=1b=2").removeLastComponent() + ) } } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ContainerFetcherTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ContainerFetcherTest.kt deleted file mode 100644 index 21f36b7a9e..0000000000 --- a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/ContainerFetcherTest.kt +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2022 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.shared.fetcher - -import android.webkit.MimeTypeMap -import java.io.File -import java.nio.charset.StandardCharsets -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertNotNull -import kotlinx.coroutines.runBlocking -import org.json.JSONObject -import org.junit.Test -import org.junit.runner.RunWith -import org.readium.r2.shared.assertJSONEquals -import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.lengthBlocking -import org.readium.r2.shared.linkBlocking -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Properties -import org.readium.r2.shared.readBlocking -import org.readium.r2.shared.resource.DefaultArchiveFactory -import org.readium.r2.shared.resource.Resource -import org.readium.r2.shared.resource.readAsString -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever -import org.robolectric.RobolectricTestRunner -import org.robolectric.Shadows - -@RunWith(RobolectricTestRunner::class) -class ContainerFetcherTest { - - private val fetcher: Fetcher - - init { - val epub = ContainerFetcherTest::class.java.getResource("epub.epub") - assertNotNull(epub) - val archive = runBlocking { - DefaultArchiveFactory() - .open(File(epub.path)) - .getOrNull()!! - } - val zipFetcher = ContainerFetcher(archive, MediaTypeRetriever()) - assertNotNull(zipFetcher) - fetcher = zipFetcher - } - - @Test - fun `Link list is correct`() { - Shadows.shadowOf(MimeTypeMap.getSingleton()).apply { - addExtensionMimeTypMapping("css", "text/css") - addExtensionMimeTypMapping("png", "image/png") - addExtensionMimeTypMapping("xml", "text/xml") - } - - fun createLink(href: String, type: String?, entryLength: Long, isCompressed: Boolean): Link { - val props = mutableMapOf( - "archive" to mapOf( - "entryLength" to entryLength, - "isEntryCompressed" to isCompressed - ) - ) - - return Link( - href = href, - type = type, - properties = Properties(props) - ) - } - - assertEquals( - listOf( - createLink("/mimetype", null, 20, false), - createLink("/EPUB/cover.xhtml", "application/xhtml+xml", 259L, true), - createLink("/EPUB/css/epub.css", "text/css", 595L, true), - createLink("/EPUB/css/nav.css", "text/css", 306L, true), - createLink("/EPUB/images/cover.png", "image/png", 35809L, true), - createLink("/EPUB/nav.xhtml", "application/xhtml+xml", 2293L, true), - createLink("/EPUB/package.opf", null, 773L, true), - createLink("/EPUB/s04.xhtml", "application/xhtml+xml", 118269L, true), - createLink("/EPUB/toc.ncx", null, 1697, true), - createLink("/META-INF/container.xml", "text/xml", 176, true) - ), - runBlocking { fetcher.links() } - ) - } - - @Test - fun `Computing length for a missing entry returns NotFound`() { - val resource = fetcher.get(Link(href = "/unknown")) - assertFailsWith { resource.lengthBlocking().getOrThrow() } - } - - @Test - fun `Reading a missing entry returns NotFound`() { - val resource = fetcher.get(Link(href = "/unknown")) - assertFailsWith { resource.readBlocking().getOrThrow() } - } - - @Test - fun `Fully reading an entry works well`() { - val resource = fetcher.get(Link(href = "/mimetype")) - val result = resource.readBlocking().getOrNull() - assertEquals("application/epub+zip", result?.toString(StandardCharsets.UTF_8)) - } - - @Test - fun `Reading a range of an entry works well`() { - val resource = fetcher.get(Link(href = "/mimetype")) - val result = resource.readBlocking(0..10L).getOrNull() - assertEquals("application", result?.toString(StandardCharsets.UTF_8)) - assertEquals(11, result?.size) - } - - @Test - fun `Out of range indexes are clamped to the available length`() { - val resource = fetcher.get(Link(href = "/mimetype")) - val result = resource.readBlocking(-5..60L).getOrNull() - assertEquals("application/epub+zip", result?.toString(StandardCharsets.UTF_8)) - assertEquals(20, result?.size) - } - - @Test - fun `Decreasing ranges are understood as empty ones`() { - val resource = fetcher.get(Link(href = "/mimetype")) - val result = resource.readBlocking(60..20L).getOrNull() - assertEquals("", result?.toString(StandardCharsets.UTF_8)) - assertEquals(0, result?.size) - } - - @Test - fun `Computing length works well`() { - val resource = fetcher.get(Link(href = "/mimetype")) - val result = resource.lengthBlocking() - assertEquals(20L, result.getOrNull()) - } - - @Test - fun `Computing a directory length returns NotFound`() { - val resource = fetcher.get(Link(href = "/EPUB")) - assertFailsWith { resource.lengthBlocking().getOrThrow() } - } - - @Test - fun `Computing the length of a missing file returns NotFound`() { - val resource = fetcher.get(Link(href = "/unknown")) - assertFailsWith { resource.lengthBlocking().getOrThrow() } - } - - @Test - fun `Adds compressed length and archive properties to the Link`() = runBlocking { - assertJSONEquals( - JSONObject( - mapOf( - "archive" to mapOf( - "entryLength" to 595L, - "isEntryCompressed" to true - ) - ) - ), - fetcher.get(Link(href = "/EPUB/css/epub.css")).link().properties.toJSON() - ) - } - - @Test - fun `Original link properties are kept`() { - val resource = fetcher.get(Link(href = "/mimetype", properties = Properties(mapOf("other" to "property")))) - - assertEquals( - Link( - href = "/mimetype", - properties = Properties( - mapOf( - "other" to "property", - "archive" to mapOf("entryLength" to 20L, "isEntryCompressed" to false) - ) - ) - ), - resource.linkBlocking() - ) - } - - /** - * When the HREF contains query parameters, the fetcher should first be able to remove them as - * a fallback. - */ - @Test - fun `Get resource from HREF with query parameters`() = runBlocking { - val resource = fetcher.get(Link(href = "/mimetype?query=param")) - val result = resource.readAsString().getOrNull() - assertEquals("application/epub+zip", result) - } - - /** - * When the HREF contains an anchor, the fetcher should first be able to remove them as - * a fallback. - */ - @Test - fun `Get resource from HREF with anchors`() = runBlocking { - val resource = fetcher.get(Link(href = "/mimetype#anchor")) - val result = resource.readAsString().getOrNull() - assertEquals("application/epub+zip", result) - } -} diff --git a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt deleted file mode 100644 index bc3e48f3f9..0000000000 --- a/readium/shared/src/test/java/org/readium/r2/shared/fetcher/FileFetcherTest.kt +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Module: r2-shared-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.shared.fetcher - -import android.webkit.MimeTypeMap -import java.io.File -import java.nio.charset.StandardCharsets -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertNotNull -import kotlinx.coroutines.runBlocking -import org.assertj.core.api.Assertions.assertThat -import org.junit.Test -import org.junit.runner.RunWith -import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.lengthBlocking -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.readBlocking -import org.readium.r2.shared.resource.Resource -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever -import org.robolectric.RobolectricTestRunner -import org.robolectric.Shadows - -@RunWith(RobolectricTestRunner::class) -class FileFetcherTest { - - private val fetcher: Fetcher - - init { - val text = FileFetcherTest::class.java.getResource("text.txt") - assertNotNull(text) - val directory = FileFetcherTest::class.java.getResource("directory") - assertNotNull(directory) - fetcher = FileFetcher( - mapOf("/file_href" to File(text.path), "/dir_href" to File(directory.path)), - MediaTypeRetriever() - ) - } - - @Test - fun `Computing length for a missing file returns NotFound`() { - val resource = fetcher.get(Link(href = "/unknown")) - assertFailsWith { resource.lengthBlocking().getOrThrow() } - } - - @Test - fun `Reading a missing file returns NotFound`() { - val resource = fetcher.get(Link(href = "/unknown")) - assertFailsWith { resource.readBlocking().getOrThrow() } - } - - @Test - fun `Reading an href in the map works well`() { - val resource = fetcher.get(Link(href = "/file_href")) - val result = resource.readBlocking().getOrNull() - assertEquals("text", result?.toString(StandardCharsets.UTF_8)) - } - - @Test - fun `Reading a file in a directory works well`() { - val resource = fetcher.get(Link(href = "/dir_href/text1.txt")) - val result = resource.readBlocking().getOrNull() - assertEquals("text1", result?.toString(StandardCharsets.UTF_8)) - } - - @Test - fun `Reading a file in a subdirectory works well`() { - val resource = fetcher.get(Link(href = "/dir_href/subdirectory/text2.txt")) - val result = resource.readBlocking().getOrNull() - assertEquals("text2", result?.toString(StandardCharsets.UTF_8)) - } - - @Test - fun `Reading a directory returns NotFound`() { - val resource = fetcher.get(Link(href = "/dir_href/subdirectory")) - assertFailsWith { resource.readBlocking().getOrThrow() } - } - - @Test - fun `Reading a file outside the allowed directory returns NotFound`() { - val resource = fetcher.get(Link(href = "/dir_href/../text.txt")) - assertFailsWith { resource.readBlocking().getOrThrow() } - } - - @Test - fun `Reading a range works well`() { - val resource = fetcher.get(Link(href = "/file_href")) - val result = resource.readBlocking(0..2L).getOrNull() - assertEquals("tex", result?.toString(StandardCharsets.UTF_8)) - } - - @Test - fun `Reading two ranges with the same resource work well`() { - val resource = fetcher.get(Link(href = "/file_href")) - val result1 = resource.readBlocking(0..1L).getOrNull() - assertEquals("te", result1?.toString(StandardCharsets.UTF_8)) - val result2 = resource.readBlocking(1..3L).getOrNull() - assertEquals("ext", result2?.toString(StandardCharsets.UTF_8)) - } - - @Test - fun `Out of range indexes are clamped to the available length`() { - val resource = fetcher.get(Link(href = "/file_href")) - val result = resource.readBlocking(-5..60L).getOrNull() - assertEquals("text", result?.toString(StandardCharsets.UTF_8)) - assertEquals(4, result?.size) - } - - @Test - @Suppress("EmptyRange") - fun `Decreasing ranges are understood as empty ones`() { - val resource = fetcher.get(Link(href = "/file_href")) - val result = resource.readBlocking(60..20L).getOrNull() - assertEquals("", result?.toString(StandardCharsets.UTF_8)) - assertEquals(0, result?.size) - } - - @Test - fun `Computing length works well`() { - val resource = fetcher.get(Link(href = "/file_href")) - val result = resource.lengthBlocking().getOrNull() - assertEquals(4L, result) - } - - @Test - fun `Computing a directory length returns NotFound`() { - val resource = fetcher.get(Link(href = "/dir_href/subdirectory")) - assertFailsWith { resource.lengthBlocking().getOrThrow() } - } - - @Test - fun `Computing the length of a missing file returns NotFound`() { - val resource = fetcher.get(Link(href = "/unknown")) - assertFailsWith { resource.lengthBlocking().getOrThrow() } - } - - @Test - fun `Computing links works well`() { - Shadows.shadowOf(MimeTypeMap.getSingleton()).apply { - addExtensionMimeTypMapping("txt", "text/plain") - addExtensionMimeTypMapping("mp3", "audio/mpeg") - } - - assertThat(runBlocking { fetcher.links() }).containsExactlyInAnyOrder( - Link(href = "/dir_href/subdirectory/hello.mp3", type = "audio/mpeg"), - Link(href = "/dir_href/subdirectory/text2.txt", type = "text/plain"), - Link(href = "/dir_href/text1.txt", type = "text/plain"), - Link(href = "/file_href", type = "text/plain") - ) - } -} diff --git a/readium/shared/src/test/java/org/readium/r2/shared/parser/xml/XmlParserTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/parser/xml/XmlParserTest.kt index 54e5a0c9c1..506ce250c8 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/parser/xml/XmlParserTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/parser/xml/XmlParserTest.kt @@ -67,7 +67,13 @@ class XmlParserTest { "meta", "", "fr", - mapOf("" to mapOf("refines" to "#title", "property" to "alternate-script", "xml:lang" to "fr")), + mapOf( + "" to mapOf( + "refines" to "#title", + "property" to "alternate-script", + "xml:lang" to "fr" + ) + ), listOf(TextNode("Moby Dick")) ) val expectedCreator = ElementNode( diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/AccessibilityTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/AccessibilityTest.kt index d0a294a078..0cc8852a2e 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/AccessibilityTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/AccessibilityTest.kt @@ -67,7 +67,7 @@ class AccessibilityTest { hazards = emptySet(), features = emptySet() ), - Accessibility.fromJSON(JSONObject("{}")), + Accessibility.fromJSON(JSONObject("{}")) ) } @@ -211,7 +211,10 @@ class AccessibilityTest { accessModes = emptySet(), accessModesSufficient = setOf( setOf(Accessibility.PrimaryAccessMode.AUDITORY), - setOf(Accessibility.PrimaryAccessMode.VISUAL, Accessibility.PrimaryAccessMode.TACTILE), + setOf( + Accessibility.PrimaryAccessMode.VISUAL, + Accessibility.PrimaryAccessMode.TACTILE + ), setOf(Accessibility.PrimaryAccessMode.VISUAL) ), features = emptySet(), @@ -298,21 +301,36 @@ class AccessibilityTest { }""" ), Accessibility( - conformsTo = setOf(Accessibility.Profile.EPUB_A11Y_10_WCAG_20_A, Accessibility.Profile("https://profile2")), + conformsTo = setOf( + Accessibility.Profile.EPUB_A11Y_10_WCAG_20_A, + Accessibility.Profile("https://profile2") + ), certification = Accessibility.Certification( certifiedBy = "company1", credential = "credential1", report = "https://report1" ), summary = "Summary", - accessModes = setOf(Accessibility.AccessMode.AUDITORY, Accessibility.AccessMode.CHART_ON_VISUAL), + accessModes = setOf( + Accessibility.AccessMode.AUDITORY, + Accessibility.AccessMode.CHART_ON_VISUAL + ), accessModesSufficient = setOf( setOf(Accessibility.PrimaryAccessMode.AUDITORY), - setOf(Accessibility.PrimaryAccessMode.VISUAL, Accessibility.PrimaryAccessMode.TACTILE), + setOf( + Accessibility.PrimaryAccessMode.VISUAL, + Accessibility.PrimaryAccessMode.TACTILE + ), setOf(Accessibility.PrimaryAccessMode.VISUAL) ), - features = setOf(Accessibility.Feature.READING_ORDER, Accessibility.Feature.ALTERNATIVE_TEXT), - hazards = setOf(Accessibility.Hazard.FLASHING, Accessibility.Hazard.MOTION_SIMULATION) + features = setOf( + Accessibility.Feature.READING_ORDER, + Accessibility.Feature.ALTERNATIVE_TEXT + ), + hazards = setOf( + Accessibility.Hazard.FLASHING, + Accessibility.Hazard.MOTION_SIMULATION + ) ).toJSON() ) } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/LinkTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/LinkTest.kt index 86b064dde9..05f9b71264 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/LinkTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/LinkTest.kt @@ -54,7 +54,7 @@ class LinkTest { assertEquals( Link( href = "http://href", - type = "application/pdf", + mediaType = MediaType.PDF, templated = true, title = "Link Title", rels = setOf("publication", "cover"), @@ -228,7 +228,7 @@ class LinkTest { ), Link( href = "http://href", - type = "application/pdf", + mediaType = MediaType.PDF, templated = true, title = "Link Title", rels = setOf("publication", "cover"), @@ -265,13 +265,9 @@ class LinkTest { ) } - @Test fun `get unknown media type`() { - assertEquals(MediaType.BINARY, Link(href = "file").mediaType) - } - @Test fun `get media type from type`() { - assertEquals(MediaType.EPUB, Link(href = "file", type = "application/epub+zip").mediaType) - assertEquals(MediaType.PDF, Link(href = "file", type = "application/pdf").mediaType) + assertEquals(MediaType.EPUB, Link(href = "file", mediaType = MediaType.EPUB).mediaType) + assertEquals(MediaType.PDF, Link(href = "file", mediaType = MediaType.PDF).mediaType) } @Test @@ -323,7 +319,7 @@ class LinkTest { fun `Make a copy after adding the given {properties}`() { val link = Link( href = "http://href", - type = "application/pdf", + mediaType = MediaType.PDF, templated = true, title = "Link Title", rels = setOf("publication", "cover"), diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/LocalizedStringTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/LocalizedStringTest.kt index 09fa467aa4..6395589b5a 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/LocalizedStringTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/LocalizedStringTest.kt @@ -198,10 +198,11 @@ class LocalizedStringTest { "fr" to "une chaîne" ) ).mapLanguages { (language, translation) -> - if (translation.string == "a string") + if (translation.string == "a string") { "en" - else + } else { language + } } ) } @@ -220,10 +221,11 @@ class LocalizedStringTest { "fr" to "une chaîne" ) ).mapTranslations { (language, translation) -> - if (language == "en") + if (language == "en") { translation.copy(string = "a string") - else + } else { translation + } } ) } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt index d09043efd9..89337e2ca2 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt @@ -15,6 +15,7 @@ import org.junit.Assert.assertNull import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.assertJSONEquals +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -195,25 +196,64 @@ class LocatorTest { } @Test fun `parse {Locations} ignores {position} smaller than 1`() { - assertEquals(Locator.Locations(position = 1), Locator.Locations.fromJSON(JSONObject("{ 'position': 1 }"))) - assertEquals(Locator.Locations(), Locator.Locations.fromJSON(JSONObject("{ 'position': 0 }"))) - assertEquals(Locator.Locations(), Locator.Locations.fromJSON(JSONObject("{ 'position': -1 }"))) + assertEquals( + Locator.Locations(position = 1), + Locator.Locations.fromJSON(JSONObject("{ 'position': 1 }")) + ) + assertEquals( + Locator.Locations(), + Locator.Locations.fromJSON(JSONObject("{ 'position': 0 }")) + ) + assertEquals( + Locator.Locations(), + Locator.Locations.fromJSON(JSONObject("{ 'position': -1 }")) + ) } @Test fun `parse {Locations} ignores {progression} outside of 0-1 range`() { - assertEquals(Locator.Locations(progression = 0.5), Locator.Locations.fromJSON(JSONObject("{ 'progression': 0.5 }"))) - assertEquals(Locator.Locations(progression = 0.0), Locator.Locations.fromJSON(JSONObject("{ 'progression': 0 }"))) - assertEquals(Locator.Locations(progression = 1.0), Locator.Locations.fromJSON(JSONObject("{ 'progression': 1 }"))) - assertEquals(Locator.Locations(), Locator.Locations.fromJSON(JSONObject("{ 'progression': -0.5 }"))) - assertEquals(Locator.Locations(), Locator.Locations.fromJSON(JSONObject("{ 'progression': 1.2 }"))) + assertEquals( + Locator.Locations(progression = 0.5), + Locator.Locations.fromJSON(JSONObject("{ 'progression': 0.5 }")) + ) + assertEquals( + Locator.Locations(progression = 0.0), + Locator.Locations.fromJSON(JSONObject("{ 'progression': 0 }")) + ) + assertEquals( + Locator.Locations(progression = 1.0), + Locator.Locations.fromJSON(JSONObject("{ 'progression': 1 }")) + ) + assertEquals( + Locator.Locations(), + Locator.Locations.fromJSON(JSONObject("{ 'progression': -0.5 }")) + ) + assertEquals( + Locator.Locations(), + Locator.Locations.fromJSON(JSONObject("{ 'progression': 1.2 }")) + ) } @Test fun `parse {Locations} ignores {totalProgression} outside of 0-1 range`() { - assertEquals(Locator.Locations(totalProgression = 0.5), Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 0.5 }"))) - assertEquals(Locator.Locations(totalProgression = 0.0), Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 0 }"))) - assertEquals(Locator.Locations(totalProgression = 1.0), Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 1 }"))) - assertEquals(Locator.Locations(), Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': -0.5 }"))) - assertEquals(Locator.Locations(), Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 1.2 }"))) + assertEquals( + Locator.Locations(totalProgression = 0.5), + Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 0.5 }")) + ) + assertEquals( + Locator.Locations(totalProgression = 0.0), + Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 0 }")) + ) + assertEquals( + Locator.Locations(totalProgression = 1.0), + Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 1 }")) + ) + assertEquals( + Locator.Locations(), + Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': -0.5 }")) + ) + assertEquals( + Locator.Locations(), + Locator.Locations.fromJSON(JSONObject("{ 'totalProgression': 1.2 }")) + ) } @Test fun `get {Locations} minimal JSON`() { @@ -325,8 +365,16 @@ class LocatorCollectionTest { ) ), links = listOf( - Link(rels = setOf("self"), href = "/978-1503222687/search?query=apple", type = "application/vnd.readium.locators+json"), - Link(rels = setOf("next"), href = "/978-1503222687/search?query=apple&page=2", type = "application/vnd.readium.locators+json"), + Link( + rels = setOf("self"), + href = "/978-1503222687/search?query=apple", + mediaType = MediaType("application/vnd.readium.locators+json")!! + ), + Link( + rels = setOf("next"), + href = "/978-1503222687/search?query=apple&page=2", + mediaType = MediaType("application/vnd.readium.locators+json")!! + ) ), locators = listOf( Locator( @@ -485,8 +533,16 @@ class LocatorCollectionTest { ) ), links = listOf( - Link(rels = setOf("self"), href = "/978-1503222687/search?query=apple", type = "application/vnd.readium.locators+json"), - Link(rels = setOf("next"), href = "/978-1503222687/search?query=apple&page=2", type = "application/vnd.readium.locators+json"), + Link( + rels = setOf("self"), + href = "/978-1503222687/search?query=apple", + mediaType = MediaType("application/vnd.readium.locators+json")!! + ), + Link( + rels = setOf("next"), + href = "/978-1503222687/search?query=apple&page=2", + mediaType = MediaType("application/vnd.readium.locators+json")!! + ) ), locators = listOf( Locator( diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt index f91a3865d4..3ee6693549 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt @@ -15,6 +15,7 @@ import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.assertJSONEquals +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -47,10 +48,12 @@ class ManifestTest { context = listOf("https://readium.org/webpub-manifest/context.jsonld"), metadata = Metadata(localizedTitle = LocalizedString("Title")), links = listOf(Link(href = "/manifest.json", rels = setOf("self"))), - readingOrder = listOf(Link(href = "/chap1.html", type = "text/html")), - resources = listOf(Link(href = "/image.png", type = "image/png")), + readingOrder = listOf(Link(href = "/chap1.html", mediaType = MediaType.HTML)), + resources = listOf(Link(href = "/image.png", mediaType = MediaType.PNG)), tableOfContents = listOf(Link(href = "/cover.html"), Link(href = "/chap1.html")), - subcollections = mapOf("sub" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink"))))) + subcollections = mapOf( + "sub" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink")))) + ) ), Manifest.fromJSON( JSONObject( @@ -88,7 +91,7 @@ class ManifestTest { context = listOf("context1", "context2"), metadata = Metadata(localizedTitle = LocalizedString("Title")), links = listOf(Link(href = "/manifest.json", rels = setOf("self"))), - readingOrder = listOf(Link(href = "/chap1.html", type = "text/html")) + readingOrder = listOf(Link(href = "/chap1.html", mediaType = MediaType.HTML)) ), Manifest.fromJSON( JSONObject( @@ -132,7 +135,7 @@ class ManifestTest { Manifest( metadata = Metadata(localizedTitle = LocalizedString("Title")), links = listOf(Link(href = "/manifest.json", rels = setOf("self"))), - readingOrder = listOf(Link(href = "/chap1.html", type = "text/html")) + readingOrder = listOf(Link(href = "/chap1.html", mediaType = MediaType.HTML)) ), Manifest.fromJSON( JSONObject( @@ -156,7 +159,7 @@ class ManifestTest { Manifest( metadata = Metadata(localizedTitle = LocalizedString("Title")), links = listOf(Link(href = "/manifest.json", rels = setOf("self"))), - readingOrder = listOf(Link(href = "/chap1.html", type = "text/html")) + readingOrder = listOf(Link(href = "/chap1.html", mediaType = MediaType.HTML)) ), Manifest.fromJSON( JSONObject( @@ -181,8 +184,8 @@ class ManifestTest { Manifest( metadata = Metadata(localizedTitle = LocalizedString("Title")), links = listOf(Link(href = "/manifest.json", rels = setOf("self"))), - readingOrder = listOf(Link(href = "/chap1.html", type = "text/html")), - resources = listOf(Link(href = "/withtype", type = "text/html")) + readingOrder = listOf(Link(href = "/chap1.html", mediaType = MediaType.HTML)), + resources = listOf(Link(href = "/withtype", mediaType = MediaType.HTML)) ), Manifest.fromJSON( JSONObject( @@ -254,10 +257,12 @@ class ManifestTest { context = listOf("https://readium.org/webpub-manifest/context.jsonld"), metadata = Metadata(localizedTitle = LocalizedString("Title")), links = listOf(Link(href = "/manifest.json", rels = setOf("self"))), - readingOrder = listOf(Link(href = "/chap1.html", type = "text/html")), - resources = listOf(Link(href = "/image.png", type = "image/png")), + readingOrder = listOf(Link(href = "/chap1.html", mediaType = MediaType.HTML)), + resources = listOf(Link(href = "/image.png", mediaType = MediaType.PNG)), tableOfContents = listOf(Link(href = "/cover.html"), Link(href = "/chap1.html")), - subcollections = mapOf("sub" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink"))))) + subcollections = mapOf( + "sub" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink")))) + ) ).toJSON() ) } @@ -346,10 +351,17 @@ class ManifestTest { @Test fun `get a {Locator} from a minimal {Link}`() { val manifest = Manifest( metadata = Metadata(localizedTitle = LocalizedString()), - readingOrder = listOf(Link(href = "/href", type = "text/html", title = "Resource")) + readingOrder = listOf( + Link(href = "/href", mediaType = MediaType.HTML, title = "Resource") + ) ) Assert.assertEquals( - Locator(href = "/href", type = "text/html", title = "Resource", locations = Locator.Locations(progression = 0.0)), + Locator( + href = "/href", + type = "text/html", + title = "Resource", + locations = Locator.Locations(progression = 0.0) + ), manifest.locatorFromLink(Link(href = "/href")) ) } @@ -357,20 +369,32 @@ class ManifestTest { @Test fun `get a {Locator} from a link in the reading order, resources or links`() { val manifest = Manifest( metadata = Metadata(localizedTitle = LocalizedString()), - readingOrder = listOf(Link(href = "/href1", type = "text/html")), - resources = listOf(Link(href = "/href2", type = "text/html")), - links = listOf(Link(href = "/href3", type = "text/html")), + readingOrder = listOf(Link(href = "/href1", mediaType = MediaType.HTML)), + resources = listOf(Link(href = "/href2", mediaType = MediaType.HTML)), + links = listOf(Link(href = "/href3", mediaType = MediaType.HTML)) ) Assert.assertEquals( - Locator(href = "/href1", type = "text/html", locations = Locator.Locations(progression = 0.0)), + Locator( + href = "/href1", + type = "text/html", + locations = Locator.Locations(progression = 0.0) + ), manifest.locatorFromLink(Link(href = "/href1")) ) Assert.assertEquals( - Locator(href = "/href2", type = "text/html", locations = Locator.Locations(progression = 0.0)), + Locator( + href = "/href2", + type = "text/html", + locations = Locator.Locations(progression = 0.0) + ), manifest.locatorFromLink(Link(href = "/href2")) ) Assert.assertEquals( - Locator(href = "/href3", type = "text/html", locations = Locator.Locations(progression = 0.0)), + Locator( + href = "/href3", + type = "text/html", + locations = Locator.Locations(progression = 0.0) + ), manifest.locatorFromLink(Link(href = "/href3")) ) } @@ -378,29 +402,45 @@ class ManifestTest { @Test fun `get a {Locator} from a full {Link} with fragment`() { val manifest = Manifest( metadata = Metadata(localizedTitle = LocalizedString()), - readingOrder = listOf(Link(href = "/href", type = "text/html", title = "Resource")) + readingOrder = listOf( + Link(href = "/href", mediaType = MediaType.HTML, title = "Resource") + ) ) Assert.assertEquals( - Locator(href = "/href", type = "text/html", title = "Resource", locations = Locator.Locations(fragments = listOf("page=42"))), - manifest.locatorFromLink(Link(href = "/href#page=42", type = "text/xml", title = "My link")) + Locator( + href = "/href", + type = "text/html", + title = "Resource", + locations = Locator.Locations(fragments = listOf("page=42")) + ), + manifest.locatorFromLink( + Link(href = "/href#page=42", mediaType = MediaType.XML, title = "My link") + ) ) } @Test fun `get a {Locator} falling back on the {Link} title`() { val manifest = Manifest( metadata = Metadata(localizedTitle = LocalizedString()), - readingOrder = listOf(Link(href = "/href", type = "text/html")) + readingOrder = listOf(Link(href = "/href", mediaType = MediaType.HTML)) ) Assert.assertEquals( - Locator(href = "/href", type = "text/html", title = "My link", locations = Locator.Locations(fragments = listOf("page=42"))), - manifest.locatorFromLink(Link(href = "/href#page=42", type = "text/xml", title = "My link")) + Locator( + href = "/href", + type = "text/html", + title = "My link", + locations = Locator.Locations(fragments = listOf("page=42")) + ), + manifest.locatorFromLink( + Link(href = "/href#page=42", mediaType = MediaType.XML, title = "My link") + ) ) } @Test fun `get a {Locator} from a {Link} not found in the manifest`() { val manifest = Manifest( metadata = Metadata(localizedTitle = LocalizedString()), - readingOrder = listOf(Link(href = "/href", type = "text/html")) + readingOrder = listOf(Link(href = "/href", mediaType = MediaType.HTML)) ) Assert.assertNull(manifest.locatorFromLink(Link(href = "notfound"))) } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt index 9906ee0d09..7729ee16a4 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/MetadataTest.kt @@ -150,7 +150,7 @@ class MetadataTest { assertEquals( Metadata( conformsTo = setOf(Publication.Profile.DIVINA), - localizedTitle = LocalizedString("Title"), + localizedTitle = LocalizedString("Title") ), Metadata.fromJSON( JSONObject( @@ -180,10 +180,6 @@ class MetadataTest { ) } - @Test fun `parse JSON requires {title}`() { - assertNull(Metadata.fromJSON(JSONObject("{'duration': 4.24}"))) - } - @Test fun `parse JSON {duration} requires positive`() { assertEquals( Metadata(localizedTitle = LocalizedString("t")), @@ -326,8 +322,12 @@ class MetadataTest { @Test fun `get primary language with no language`() { assertNull(createMetadata(languages = listOf(), readingProgression = null).language) - assertNull(createMetadata(languages = listOf(), readingProgression = ReadingProgression.LTR).language) - assertNull(createMetadata(languages = listOf(), readingProgression = ReadingProgression.RTL).language) + assertNull( + createMetadata(languages = listOf(), readingProgression = ReadingProgression.LTR).language + ) + assertNull( + createMetadata(languages = listOf(), readingProgression = ReadingProgression.RTL).language + ) } @Test fun `get primary language with a single language`() { @@ -346,5 +346,9 @@ class MetadataTest { } private fun createMetadata(languages: List, readingProgression: ReadingProgression?): Metadata = - Metadata(localizedTitle = LocalizedString("Title"), languages = languages, readingProgression = readingProgression) + Metadata( + localizedTitle = LocalizedString("Title"), + languages = languages, + readingProgression = readingProgression + ) } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationCollectionTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationCollectionTest.kt index 8796489503..5811c250fc 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationCollectionTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationCollectionTest.kt @@ -43,7 +43,11 @@ class PublicationCollectionTest { links = listOf(Link(href = "/link")), subcollections = mapOf( "sub1" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink")))), - "sub2" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")))), + "sub2" to listOf( + PublicationCollection( + links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")) + ) + ), "sub3" to listOf( PublicationCollection(links = listOf(Link(href = "/sublink3"))), PublicationCollection(links = listOf(Link(href = "/sublink4"))) @@ -94,7 +98,11 @@ class PublicationCollectionTest { assertEquals( mapOf( "sub1" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink")))), - "sub2" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")))), + "sub2" to listOf( + PublicationCollection( + links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")) + ) + ), "sub3" to listOf( PublicationCollection(links = listOf(Link(href = "/sublink3"))), PublicationCollection(links = listOf(Link(href = "/sublink4"))) @@ -186,7 +194,11 @@ class PublicationCollectionTest { links = listOf(Link(href = "/link")), subcollections = mapOf( "sub1" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink")))), - "sub2" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")))), + "sub2" to listOf( + PublicationCollection( + links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")) + ) + ), "sub3" to listOf( PublicationCollection(links = listOf(Link(href = "/sublink3"))), PublicationCollection(links = listOf(Link(href = "/sublink4"))) @@ -231,7 +243,11 @@ class PublicationCollectionTest { ), mapOf( "sub1" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink")))), - "sub2" to listOf(PublicationCollection(links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")))), + "sub2" to listOf( + PublicationCollection( + links = listOf(Link(href = "/sublink1"), Link(href = "/sublink2")) + ) + ), "sub3" to listOf( PublicationCollection(links = listOf(Link(href = "/sublink3"))), PublicationCollection(links = listOf(Link(href = "/sublink4"))) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt index 10df7b011a..a3225c7207 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/PublicationTest.kt @@ -14,16 +14,18 @@ import kotlinx.coroutines.runBlocking import org.junit.Assert.* import org.junit.Test import org.junit.runner.RunWith -import org.readium.r2.shared.fetcher.EmptyFetcher -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.StringResource import org.readium.r2.shared.publication.Publication.Profile import org.readium.r2.shared.publication.services.DefaultLocatorService import org.readium.r2.shared.publication.services.PositionsService import org.readium.r2.shared.publication.services.WebPositionsService import org.readium.r2.shared.publication.services.positions import org.readium.r2.shared.publication.services.positionsByReadingOrder +import org.readium.r2.shared.resource.EmptyContainer +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.StringResource import org.readium.r2.shared.resource.readAsString +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -64,7 +66,9 @@ class PublicationTest { servicesBuilder = Publication.ServicesBuilder( positions = { object : PositionsService { - override suspend fun positionsByReadingOrder(): List> = listOf(listOf(Locator(href = "locator", type = ""))) + override suspend fun positionsByReadingOrder(): List> = listOf( + listOf(Locator(href = "locator", type = "")) + ) } } ) @@ -103,7 +107,9 @@ class PublicationTest { @Test fun `get {baseUrl} computes the URL from the {self} link`() { val publication = createPublication( - links = listOf(Link(href = "http://domain.com/path/manifest.json", rels = setOf("self"))) + links = listOf( + Link(href = "http://domain.com/path/manifest.json", rels = setOf("self")) + ) ) assertEquals( URL("http://domain.com/path/"), @@ -135,24 +141,24 @@ class PublicationTest { assertTrue( createPublication( readingOrder = listOf( - Link(href = "c1.mp3", type = "audio/mpeg"), - Link(href = "c2.aac", type = "audio/aac"), + Link(href = "c1.mp3", mediaType = MediaType.MP3), + Link(href = "c2.aac", mediaType = MediaType.AAC) ) ).conformsTo(Profile.AUDIOBOOK) ) assertTrue( createPublication( readingOrder = listOf( - Link(href = "c1.jpg", type = "image/jpeg"), - Link(href = "c2.png", type = "image/png"), + Link(href = "c1.jpg", mediaType = MediaType.JPEG), + Link(href = "c2.png", mediaType = MediaType.PNG) ) ).conformsTo(Profile.DIVINA) ) assertTrue( createPublication( readingOrder = listOf( - Link(href = "c1.pdf", type = "application/pdf"), - Link(href = "c2.pdf", type = "application/pdf"), + Link(href = "c1.pdf", mediaType = MediaType.PDF), + Link(href = "c2.pdf", mediaType = MediaType.PDF) ) ).conformsTo(Profile.PDF) ) @@ -161,16 +167,16 @@ class PublicationTest { assertFalse( createPublication( readingOrder = listOf( - Link(href = "c1.mp3", type = "audio/mpeg"), - Link(href = "c2.jpg", type = "image/jpeg"), + Link(href = "c1.mp3", mediaType = MediaType.MP3), + Link(href = "c2.jpg", mediaType = MediaType.JPEG) ) ).conformsTo(Profile.AUDIOBOOK) ) assertFalse( createPublication( readingOrder = listOf( - Link(href = "c1.mp3", type = "audio/mpeg"), - Link(href = "c2.jpg", type = "image/jpeg"), + Link(href = "c1.mp3", mediaType = MediaType.MP3), + Link(href = "c2.jpg", mediaType = MediaType.JPEG) ) ).conformsTo(Profile.DIVINA) ) @@ -179,8 +185,8 @@ class PublicationTest { assertTrue( createPublication( readingOrder = listOf( - Link(href = "c1.xhtml", type = "application/xhtml+xml"), - Link(href = "c2.xhtml", type = "application/xhtml+xml"), + Link(href = "c1.xhtml", mediaType = MediaType.XHTML), + Link(href = "c2.xhtml", mediaType = MediaType.XHTML) ), conformsTo = setOf(Profile.EPUB) ).conformsTo(Profile.EPUB) @@ -188,8 +194,8 @@ class PublicationTest { assertTrue( createPublication( readingOrder = listOf( - Link(href = "c1.html", type = "text/html"), - Link(href = "c2.html", type = "text/html"), + Link(href = "c1.html", mediaType = MediaType.HTML), + Link(href = "c2.html", mediaType = MediaType.HTML) ), conformsTo = setOf(Profile.EPUB) ).conformsTo(Profile.EPUB) @@ -197,24 +203,24 @@ class PublicationTest { assertFalse( createPublication( readingOrder = listOf( - Link(href = "c1.xhtml", type = "application/xhtml+xml"), - Link(href = "c2.xhtml", type = "application/xhtml+xml"), + Link(href = "c1.xhtml", mediaType = MediaType.XHTML), + Link(href = "c2.xhtml", mediaType = MediaType.XHTML) ) ).conformsTo(Profile.EPUB) ) assertFalse( createPublication( readingOrder = listOf( - Link(href = "c1.html", type = "text/html"), - Link(href = "c2.html", type = "text/html"), + Link(href = "c1.html", mediaType = MediaType.HTML), + Link(href = "c2.html", mediaType = MediaType.HTML) ) ).conformsTo(Profile.EPUB) ) assertFalse( createPublication( readingOrder = listOf( - Link(href = "c1.pdf", type = "application/pdf"), - Link(href = "c2.pdf", type = "application/pdf"), + Link(href = "c1.pdf", mediaType = MediaType.PDF), + Link(href = "c2.pdf", mediaType = MediaType.PDF) ), conformsTo = setOf(Profile.EPUB) ).conformsTo(Profile.EPUB) @@ -224,8 +230,8 @@ class PublicationTest { assertTrue( createPublication( readingOrder = listOf( - Link(href = "c1.mp3", type = "audio/mpeg"), - Link(href = "c2.aac", type = "audio/aac"), + Link(href = "c1.mp3", mediaType = MediaType.MP3), + Link(href = "c2.aac", mediaType = MediaType.AAC) ), conformsTo = setOf(Profile.DIVINA) ).conformsTo(Profile.AUDIOBOOK) @@ -233,8 +239,8 @@ class PublicationTest { assertFalse( createPublication( readingOrder = listOf( - Link(href = "c1.mp3", type = "audio/mpeg"), - Link(href = "c2.aac", type = "audio/aac"), + Link(href = "c1.mp3", mediaType = MediaType.MP3), + Link(href = "c2.aac", mediaType = MediaType.AAC) ), conformsTo = setOf(Profile.DIVINA) ).conformsTo(Profile.DIVINA) @@ -355,7 +361,10 @@ class PublicationTest { readingOrder = listOf(Link(href = "other"), link) ) - assertEquals(link, publication.linkWithHref("http://example.com/index.html?title=titre&action=edit")) + assertEquals( + link, + publication.linkWithHref("http://example.com/index.html?title=titre&action=edit") + ) } @Test fun `find the first {Link} with the given {href} without anchor`() { @@ -373,10 +382,10 @@ class PublicationTest { @Test fun `get method passes on href parameters to services`() { val service = object : Publication.Service { - override fun get(link: Link): Fetcher.Resource? { + override fun get(link: Link): Resource? { assertFalse(link.templated) assertEquals("param1=a¶m2=b", link.href.substringAfter("?")) - return StringResource(link, "test passed") + return StringResource("test passed", MediaType.TEXT, url = Url(link.href)) } } @@ -387,7 +396,10 @@ class PublicationTest { positions = { service } ) ) - assertEquals("test passed", runBlocking { publication.get(link).readAsString().getOrNull() }) + assertEquals( + "test passed", + runBlocking { publication.get(link).readAsString().getOrNull() } + ) } @Test fun `find the first resource {Link} with the given {href}`() { @@ -422,7 +434,7 @@ class ServicesBuilderTest { private val context = Publication.Service.Context( manifest = Manifest(metadata = Metadata(localizedTitle = LocalizedString())), - fetcher = EmptyFetcher(), + container = EmptyContainer(), services = ListPublicationServicesHolder() ) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/opds/PropertiesTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/opds/PropertiesTest.kt index 7ebb65b635..d654325932 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/opds/PropertiesTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/opds/PropertiesTest.kt @@ -16,6 +16,7 @@ import org.junit.runner.RunWith import org.readium.r2.shared.opds.* import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Properties +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -39,7 +40,9 @@ class PropertiesTest { @Test fun `get Properties {price} when available`() { assertEquals( Price(currency = "EUR", value = 4.36), - Properties(otherProperties = mapOf("price" to mapOf("currency" to "EUR", "value" to 4.36))).price + Properties( + otherProperties = mapOf("price" to mapOf("currency" to "EUR", "value" to 4.36)) + ).price ) } @@ -109,13 +112,13 @@ class PropertiesTest { assertEquals( Link( href = "https://example.com/authentication.json", - type = "application/opds-authentication+json" + mediaType = MediaType("application/opds-authentication+json")!! ), Properties( otherProperties = mapOf( "authenticate" to mapOf( "href" to "https://example.com/authentication.json", - "type" to "application/opds-authentication+json", + "type" to "application/opds-authentication+json" ) ) ).authenticate @@ -127,7 +130,7 @@ class PropertiesTest { Properties( otherProperties = mapOf( "authenticate" to mapOf( - "type" to "application/opds-authentication+json", + "type" to "application/opds-authentication+json" ) ) ).authenticate diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt index 5021f70a9e..2e5b62b5e9 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtectionTest.kt @@ -73,7 +73,6 @@ class AdeptFallbackContentProtectionTest { private fun supports(mediaType: MediaType, resources: Map): Boolean = runBlocking { AdeptFallbackContentProtection().supports( Asset.Container( - name = "fake name", mediaType = mediaType, exploded = false, container = TestContainer(resources) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt index 31d3fe3d88..5eb2359d77 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtectionTest.kt @@ -13,6 +13,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -88,9 +89,8 @@ class LcpFallbackContentProtectionTest { } private fun supports(mediaType: MediaType, resources: Map): Boolean = runBlocking { - LcpFallbackContentProtection().supports( + LcpFallbackContentProtection(MediaTypeRetriever()).supports( Asset.Container( - name = "fake name", mediaType = mediaType, exploded = false, container = TestContainer(resources) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt index 28297f66dc..ff815d84bd 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt @@ -6,25 +6,23 @@ package org.readium.r2.shared.publication.protection -import java.io.File import org.readium.r2.shared.error.Try import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.resource.StringResource +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType class TestContainer(resources: Map = emptyMap()) : Container { private val entries: Map = - resources.mapValues { Entry(it.key, StringResource(it.value)) } + resources.mapValues { Entry(it.key, StringResource(it.value, MediaType.TEXT)) } - override suspend fun name(): ResourceTry = - Try.success(null) + override suspend fun entries(): Set = + entries.values.toSet() - override suspend fun entries(): Iterable = - entries.values - - override suspend fun entry(path: String): Container.Entry = + override fun get(path: String): Container.Entry = entries[path] ?: NotFoundEntry(path) override suspend fun close() {} @@ -33,8 +31,13 @@ class TestContainer(resources: Map = emptyMap()) : Container { override val path: String ) : Container.Entry { - override suspend fun name(): ResourceTry = - ResourceTry.success(File(path).name) + override val source: Url? = null + + override suspend fun mediaType(): ResourceTry = + Try.failure(Resource.Exception.NotFound()) + + override suspend fun properties(): ResourceTry = + Try.failure(Resource.Exception.NotFound()) override suspend fun length(): ResourceTry = Try.failure(Resource.Exception.NotFound()) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt index b2e97029dd..ae00051dae 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/CoverServiceTest.kt @@ -19,11 +19,11 @@ import kotlin.test.assertTrue import kotlinx.coroutines.runBlocking import org.junit.Test import org.junit.runner.RunWith -import org.readium.r2.shared.fetcher.FileFetcher -import org.readium.r2.shared.linkBlocking import org.readium.r2.shared.publication.* import org.readium.r2.shared.readBlocking -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.resource.FileResource +import org.readium.r2.shared.resource.ResourceContainer +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -41,7 +41,7 @@ class CoverServiceTest { coverBytes = cover.readBytes() coverBitmap = BitmapFactory.decodeByteArray(coverBytes, 0, coverBytes.size) coverPath = cover.path - coverLink = Link(href = coverPath, type = "image/jpeg", width = 598, height = 800) + coverLink = Link(href = coverPath, mediaType = MediaType.JPEG, width = 598, height = 800) publication = Publication( manifest = Manifest( @@ -52,19 +52,18 @@ class CoverServiceTest { Link(href = coverPath, rels = setOf("cover")) ) ), - fetcher = FileFetcher(coverPath, File(coverPath), MediaTypeRetriever()) + container = ResourceContainer( + coverPath, + FileResource(File(coverPath), mediaType = MediaType.JPEG) + ) ) } @Test - fun `get works fine`() { + fun `get works fine`() = runBlocking { val service = InMemoryCoverService(coverBitmap) val res = service.get(Link("/~readium/cover", rels = setOf("cover"))) assertNotNull(res) - assertEquals( - Link(href = "/~readium/cover", type = "image/png", width = 598, height = 800, rels = setOf("cover")), - res.linkBlocking() - ) val bytes = res.readBlocking().getOrNull() assertNotNull(bytes) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/LocatorServiceTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/LocatorServiceTest.kt index ed13fb1bc8..94c0cb83d5 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/LocatorServiceTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/LocatorServiceTest.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Test import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.util.mediatype.MediaType @OptIn(ExperimentalCoroutinesApi::class) class LocatorServiceTest { @@ -22,19 +23,27 @@ class LocatorServiceTest { fun `locate from Locator`() = runTest { val service = createService( readingOrder = listOf( - Link(href = "chap1", type = "application/xml"), - Link(href = "chap2", type = "application/xml"), - Link(href = "chap3", type = "application/xml") + Link(href = "chap1", mediaType = MediaType.XML), + Link(href = "chap2", mediaType = MediaType.XML), + Link(href = "chap3", mediaType = MediaType.XML) ) ) - val locator = Locator(href = "chap2", type = "text/html", text = Locator.Text(highlight = "Highlight")) + val locator = Locator( + href = "chap2", + type = "text/html", + text = Locator.Text(highlight = "Highlight") + ) assertEquals(locator, service.locate(locator)) } @Test fun `locate from Locator with empty reading order`() = runTest { val service = createService(readingOrder = emptyList()) - val locator = Locator(href = "chap2", type = "text/html", text = Locator.Text(highlight = "Highlight")) + val locator = Locator( + href = "chap2", + type = "text/html", + text = Locator.Text(highlight = "Highlight") + ) assertNull(service.locate(locator)) } @@ -42,11 +51,15 @@ class LocatorServiceTest { fun `locate from Locator not found`() = runTest { val service = createService( readingOrder = listOf( - Link(href = "chap1", type = "application/xml"), - Link(href = "chap3", type = "application/xml") + Link(href = "chap1", mediaType = MediaType.XML), + Link(href = "chap3", mediaType = MediaType.XML) ) ) - val locator = Locator(href = "chap2", type = "text/html", text = Locator.Text(highlight = "Highlight")) + val locator = Locator( + href = "chap2", + type = "text/html", + text = Locator.Text(highlight = "Highlight") + ) assertNull(service.locate(locator)) } diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt index c7bce03ca8..bb328b9fbd 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/PositionsServiceTest.kt @@ -21,6 +21,7 @@ import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.readAsString +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -109,7 +110,10 @@ class PerResourcePositionsServiceTest { @Test fun `Positions from an empty {readingOrder}`() { - val service = PerResourcePositionsService(readingOrder = emptyList(), fallbackMediaType = "") + val service = PerResourcePositionsService( + readingOrder = emptyList(), + fallbackMediaType = "" + ) Assert.assertEquals(0, runBlocking { service.positions().size }) } @@ -117,7 +121,7 @@ class PerResourcePositionsServiceTest { @Test fun `Positions from a {readingOrder} with one resource`() { val service = PerResourcePositionsService( - readingOrder = listOf(Link(href = "res", type = "image/png")), + readingOrder = listOf(Link(href = "res", mediaType = MediaType.PNG)), fallbackMediaType = "" ) @@ -141,8 +145,8 @@ class PerResourcePositionsServiceTest { val service = PerResourcePositionsService( readingOrder = listOf( Link(href = "res"), - Link(href = "chap1", type = "image/png"), - Link(href = "chap2", type = "image/png", title = "Chapter 2") + Link(href = "chap1", mediaType = MediaType.PNG), + Link(href = "chap2", mediaType = MediaType.PNG, title = "Chapter 2") ), fallbackMediaType = "" ) diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt index 50e3ca6469..40544c9e11 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt @@ -8,7 +8,6 @@ import org.junit.Assert.* import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.fetcher.StringResource import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.services.content.Content @@ -17,14 +16,17 @@ import org.readium.r2.shared.publication.services.content.Content.AttributeKey.C import org.readium.r2.shared.publication.services.content.Content.AttributeKey.Companion.LANGUAGE import org.readium.r2.shared.publication.services.content.Content.TextElement import org.readium.r2.shared.publication.services.content.Content.TextElement.Segment +import org.readium.r2.shared.resource.StringResource import org.readium.r2.shared.util.Language +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @OptIn(ExperimentalReadiumApi::class) @RunWith(RobolectricTestRunner::class) class HtmlResourceContentIteratorTest { - private val link = Link(href = "/dir/res.xhtml", type = "application/xhtml+xml") + private val link = Link(href = "/dir/res.xhtml", mediaType = MediaType.XHTML) private val locator = Locator(href = "/dir/res.xhtml", type = "application/xhtml+xml") private val html = """ @@ -88,7 +90,7 @@ class HtmlResourceContentIteratorTest { ), text = "INTRODUCTORY", attributes = listOf(Attribute(LANGUAGE, Language("en"))) - ), + ) ) ), TextElement( @@ -108,8 +110,8 @@ class HtmlResourceContentIteratorTest { highlight = "The difficulties of classification are very apparent here, and once more it must be noted that illustrative and practical purposes rather than logical ones are served by the arrangement adopted. The modern fanciful story is here placed next to the real folk story instead of after all the groups of folk products. The Hebrew stories at the beginning belong quite as well, perhaps even better, in Section V, while the stories at the end of Section VI shade off into the more modern types of short tales." ), text = "The difficulties of classification are very apparent here, and once more it must be noted that illustrative and practical purposes rather than logical ones are served by the arrangement adopted. The modern fanciful story is here placed next to the real folk story instead of after all the groups of folk products. The Hebrew stories at the beginning belong quite as well, perhaps even better, in Section V, while the stories at the end of Section VI shade off into the more modern types of short tales.", - attributes = listOf(Attribute(LANGUAGE, Language("en"))), - ), + attributes = listOf(Attribute(LANGUAGE, Language("en"))) + ) ) ), TextElement( @@ -130,7 +132,7 @@ class HtmlResourceContentIteratorTest { ), text = "The child's natural literature. The world has lost certain secrets as the price of an advancing civilization.", attributes = listOf(Attribute(LANGUAGE, Language("en"))) - ), + ) ) ), TextElement( @@ -151,7 +153,7 @@ class HtmlResourceContentIteratorTest { ), text = "Without discussing the limits of the culture-epoch theory of human development as a complete guide in education, it is clear that the young child passes through a period when his mind looks out upon the world in a manner analogous to that of the folk as expressed in their literature.", attributes = listOf(Attribute(LANGUAGE, Language("en"))) - ), + ) ) ) ) @@ -178,7 +180,11 @@ class HtmlResourceContentIteratorTest { startLocator: Locator = locator, totalProgressionRange: ClosedRange? = null ): HtmlResourceContentIterator = - HtmlResourceContentIterator(StringResource(link, html), totalProgressionRange = totalProgressionRange, startLocator) + HtmlResourceContentIterator( + StringResource(html, MediaType.HTML, Url(link.href)), + totalProgressionRange = totalProgressionRange, + startLocator + ) private suspend fun HtmlResourceContentIterator.elements(): List = buildList { @@ -305,7 +311,7 @@ class HtmlResourceContentIteratorTest { progression = 0.5, selector = "html > body > p:nth-child(2)", before = "oin sur la chaussée, aussi loin qu’on pouvait voir", - highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée.", + highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée." ), text = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée.", attributes = listOf(Attribute(LANGUAGE, Language("fr"))) @@ -346,7 +352,7 @@ class HtmlResourceContentIteratorTest { progression = 0.5, selector = "html > body > p:nth-child(2)", before = "oin sur la chaussée, aussi loin qu’on pouvait voir", - highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée.", + highlight = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée." ), text = "Lui, notre colonel, savait peut-être pourquoi ces deux gens-là tiraient [...] On buvait de la bière sucrée.", attributes = listOf(Attribute(LANGUAGE, Language("fr"))) @@ -402,7 +408,7 @@ class HtmlResourceContentIteratorTest {

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 KD%$z;0Qf&F2!+T1 diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/fetcher/text.txt b/readium/shared/src/test/resources/org/readium/r2/shared/fetcher/text.txt deleted file mode 100644 index f3a34851d4..0000000000 --- a/readium/shared/src/test/resources/org/readium/r2/shared/fetcher/text.txt +++ /dev/null @@ -1 +0,0 @@ -text \ No newline at end of file diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/fetcher/directory/subdirectory/hello.mp3 b/readium/shared/src/test/resources/org/readium/r2/shared/resource/directory/subdirectory/hello.mp3 similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/fetcher/directory/subdirectory/hello.mp3 rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/directory/subdirectory/hello.mp3 diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/fetcher/directory/subdirectory/text2.txt b/readium/shared/src/test/resources/org/readium/r2/shared/resource/directory/subdirectory/text2.txt similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/fetcher/directory/subdirectory/text2.txt rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/directory/subdirectory/text2.txt diff --git a/readium/shared/src/test/resources/org/readium/r2/shared/fetcher/directory/text1.txt b/readium/shared/src/test/resources/org/readium/r2/shared/resource/directory/text1.txt similarity index 100% rename from readium/shared/src/test/resources/org/readium/r2/shared/fetcher/directory/text1.txt rename to readium/shared/src/test/resources/org/readium/r2/shared/resource/directory/text1.txt diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt index 36136397ef..cffeb14653 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt @@ -10,64 +10,62 @@ import java.io.File import java.nio.charset.Charset import org.json.JSONObject import org.readium.r2.shared.asset.Asset -import org.readium.r2.shared.error.* -import org.readium.r2.shared.fetcher.ContainerFetcher -import org.readium.r2.shared.fetcher.ResourceFetcher -import org.readium.r2.shared.fetcher.RoutingFetcher -import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.error.MessageError +import org.readium.r2.shared.error.ThrowableError +import org.readium.r2.shared.error.Try +import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceContainer +import org.readium.r2.shared.resource.RoutingContainer +import org.readium.r2.shared.resource.StringResource import org.readium.r2.shared.util.http.HttpClient -import org.readium.r2.shared.util.http.HttpFetcher +import org.readium.r2.shared.util.http.HttpContainer import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.streamer.parser.PublicationParser internal class ParserAssetFactory( private val httpClient: HttpClient, - private val mediaTypeRetriever: MediaTypeRetriever, + private val mediaTypeRetriever: MediaTypeRetriever ) { suspend fun createParserAsset( - asset: Asset, + asset: Asset ): Try { return when (asset) { is Asset.Container -> - Try.success( - createParserAssetForContainer(asset.container, asset.mediaType, asset.name) - ) + createParserAssetForContainer(asset) is Asset.Resource -> - createParserAssetForResource(asset.resource, asset.mediaType, asset.name) + createParserAssetForResource(asset) } } private fun createParserAssetForContainer( - container: Container, - mediaType: MediaType, - assetName: String - ): PublicationParser.Asset { - val fetcher = ContainerFetcher(container, mediaTypeRetriever) - return PublicationParser.Asset(assetName, mediaType, fetcher) - } + asset: Asset.Container + ): Try = + Try.success( + PublicationParser.Asset( + mediaType = asset.mediaType, + container = asset.container + ) + ) private suspend fun createParserAssetForResource( - resource: Resource, - mediaType: MediaType, - assetName: String + asset: Asset.Resource ): Try = - if (mediaType.isRwpm) { - createParserAssetForManifest(resource, assetName) + if (asset.mediaType.isRwpm) { + createParserAssetForManifest(asset) } else { - createParserAssetForContent(resource, mediaType, assetName) + createParserAssetForContent(asset) } private suspend fun createParserAssetForManifest( - resource: Resource, - assetName: String + asset: Asset.Resource ): Try { - val manifest = resource.readAsRwpm(packaged = false) + val manifest = asset.resource.readAsRwpm(packaged = false) .mapFailure { Publication.OpeningException.ParsingFailed(ThrowableError(it)) } .getOrElse { return Try.failure(it) } @@ -81,36 +79,42 @@ internal class ParserAssetFactory( if (!baseUrl.startsWith("http")) { return Try.failure( - Publication.OpeningException.UnsupportedAsset("Self link doesn't use the HTTP(S) scheme.") + Publication.OpeningException.UnsupportedAsset( + "Self link doesn't use the HTTP(S) scheme." + ) ) } - val link = Link( - href = "/manifest.json", - type = MediaType.READIUM_WEBPUB_MANIFEST.toString() - ) - - val fetcher = - RoutingFetcher( - local = ResourceFetcher(link, resource), - remote = HttpFetcher(httpClient, baseUrl) + val container = + RoutingContainer( + local = ResourceContainer( + path = "/manifest.json", + resource = StringResource(manifest.toJSON().toString(), asset.mediaType) + ), + remote = HttpContainer(httpClient, baseUrl) ) return Try.success( - PublicationParser.Asset(assetName, MediaType.READIUM_WEBPUB, fetcher) + PublicationParser.Asset( + mediaType = MediaType.READIUM_WEBPUB, + container = container + ) ) } private fun createParserAssetForContent( - resource: Resource, - mediaType: MediaType, - assetName: String + asset: Asset.Resource ): Try { - val link = Link(href = "/$assetName", type = mediaType.toString()) - val fetcher = ResourceFetcher(link, resource) + // Historically, the reading order of a standalone file contained a single link with the + // HREF "/$assetName". This was fragile if the asset named changed, or was different on + // other devices. To avoid this, we now use a single link with the HREF ".". + val container = ResourceContainer(".", asset.resource) return Try.success( - PublicationParser.Asset(assetName, mediaType, fetcher) + PublicationParser.Asset( + mediaType = asset.mediaType, + container = container + ) ) } @@ -119,7 +123,11 @@ internal class ParserAssetFactory( val bytes = read().getOrThrow() val string = String(bytes, Charset.defaultCharset()) val json = JSONObject(string) - val manifest = Manifest.fromJSON(json, packaged = packaged) + val manifest = Manifest.fromJSON( + json, + packaged = packaged, + mediaTypeRetriever = mediaTypeRetriever + ) ?: throw Exception("Failed to parse the RWPM Manifest") Try.success(manifest) } catch (e: Exception) { diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt index 999380e135..8d87d4e5d5 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt @@ -41,37 +41,54 @@ internal typealias PublicationTry = Try = emptyList(), ignoreDefaultParsers: Boolean = false, - contentProtections: List = emptyList(), - pdfFactory: PdfDocumentFactory<*>? = null, - httpClient: HttpClient = DefaultHttpClient(), - mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), - private val onCreatePublication: Publication.Builder.() -> Unit = {}, + contentProtections: List, + mediaTypeRetriever: MediaTypeRetriever, + httpClient: HttpClient, + pdfFactory: PdfDocumentFactory<*>?, + private val onCreatePublication: Publication.Builder.() -> Unit = {} ) { + public companion object { + public operator fun invoke( + context: Context, + contentProtections: List = emptyList(), + onCreatePublication: Publication.Builder.() -> Unit + ): PublicationFactory { + val mediaTypeRetriever = MediaTypeRetriever() + return PublicationFactory( + context = context, + contentProtections = contentProtections, + mediaTypeRetriever = mediaTypeRetriever, + httpClient = DefaultHttpClient(mediaTypeRetriever), + pdfFactory = null, + onCreatePublication = onCreatePublication + ) + } + } + private val contentProtections: Map = buildList { add(LcpFallbackContentProtection(mediaTypeRetriever)) - add(AdeptFallbackContentProtection(mediaTypeRetriever)) + add(AdeptFallbackContentProtection()) addAll(contentProtections.asReversed()) }.associateBy(ContentProtection::scheme) private val defaultParsers: List = listOfNotNull( - EpubParser(), + EpubParser(mediaTypeRetriever), pdfFactory?.let { PdfParser(context, it) }, - ReadiumWebPubParser(context, pdfFactory), + ReadiumWebPubParser(context, pdfFactory, mediaTypeRetriever), ImageParser(), AudioParser() ) @@ -108,7 +125,7 @@ public class PublicationFactory constructor( * @param sender Free object that can be used by reading apps to give some UX context when * presenting dialogs. * @param onCreatePublication Transformation which will be applied on the Publication Builder. - * It can be used to modify the manifest, the root fetcher or the list of service + * It can be used to modify the manifest, the root container or the list of service * factories of the [Publication]. * @param warnings Logger used to broadcast non-fatal parsing warnings. * @return A [Publication] or a [Publication.OpeningException] in case of failure. @@ -171,9 +188,8 @@ public class PublicationFactory constructor( ?: return Try.failure(Publication.OpeningException.Forbidden()) val parserAsset = PublicationParser.Asset( - protectedAsset.name, protectedAsset.mediaType, - protectedAsset.fetcher + protectedAsset.container ) val compositeOnCreatePublication: Publication.Builder.() -> Unit = { diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt index 7049c0262e..d5a71f2b77 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/container/Container.kt @@ -25,27 +25,64 @@ import java.io.InputStream * * @func dataInputStream : return the InputStream of content */ -@Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) +@Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR +) public interface Container { - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public fun data(relativePath: String): ByteArray - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public fun dataLength(relativePath: String): Long - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public fun dataInputStream(relativePath: String): InputStream } public sealed class ContainerError : Exception() { - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public object streamInitFailed : ContainerError() - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public object fileNotFound : ContainerError() - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public object fileError : ContainerError() - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public data class missingFile(public val path: String) : ContainerError() - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public data class xmlParse(public val underlyingError: Error) : ContainerError() - @Deprecated("Use [publication.get()] to access publication content.", level = DeprecationLevel.ERROR) + + @Deprecated( + "Use [publication.get()] to access publication content.", + level = DeprecationLevel.ERROR + ) public data class missingLink(public val title: String?) : ContainerError() } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Container.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Container.kt new file mode 100644 index 0000000000..27f75c0571 --- /dev/null +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Container.kt @@ -0,0 +1,46 @@ +/* + * Module: r2-streamer-kotlin + * Developers: Mickaël Menu, Quentin Gliosca + * + * Copyright (c) 2020. Readium Foundation. All rights reserved. + * Use of this source code is governed by a BSD-style license which is detailed in the + * LICENSE file present in the project repository where this source code is maintained. + */ + +package org.readium.r2.streamer.extensions + +import java.io.File +import org.json.JSONObject +import org.readium.r2.shared.parser.xml.ElementNode +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.readAsJson +import org.readium.r2.shared.resource.readAsXml +import org.readium.r2.shared.util.use + +/** Returns the resource data as an XML Document at the given [path], or null. */ +internal suspend fun Container.readAsXmlOrNull(path: String): ElementNode? = + get(path).use { it.readAsXml().getOrNull() } + +/** Returns the resource data as a JSON object at the given [path], or null. */ +internal suspend fun Container.readAsJsonOrNull(path: String): JSONObject? = + get(path).use { it.readAsJson().getOrNull() } + +internal suspend fun Container.guessTitle(): String? { + val entries = entries() ?: return null + val firstEntry = entries.firstOrNull() ?: return null + val commonFirstComponent = entries.pathCommonFirstComponent() ?: return null + + if (commonFirstComponent.name == firstEntry.path.removePrefix("/")) { + return null + } + + return commonFirstComponent.name +} + +/** Returns a [File] to the directory containing all paths, if there is such a directory. */ +internal fun Iterable.pathCommonFirstComponent(): File? = + map { it.path.removePrefix("/").substringBefore("/") } + .distinct() + .takeIf { it.size == 1 } + ?.firstOrNull() + ?.let { File(it) } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt deleted file mode 100644 index 38cbb4a633..0000000000 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Fetcher.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Module: r2-streamer-kotlin - * Developers: Mickaël Menu, Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.streamer.extensions - -import org.json.JSONObject -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.parser.xml.ElementNode -import org.readium.r2.shared.resource.readAsJson -import org.readium.r2.shared.resource.readAsXml -import org.readium.r2.shared.util.use - -/** Returns the resource data as an XML Document at the given [href], or null. */ -internal suspend fun Fetcher.readAsXmlOrNull(href: String): ElementNode? = - get(href).use { it.readAsXml().getOrNull() } - -/** Returns the resource data as a JSON object at the given [href], or null. */ -internal suspend fun Fetcher.readAsJsonOrNull(href: String): JSONObject? = - get(href).use { it.readAsJson().getOrNull() } - -internal suspend fun Fetcher.guessTitle(): String? { - val firstLink = links().firstOrNull() ?: return null - val commonFirstComponent = links().hrefCommonFirstComponent() ?: return null - - if (commonFirstComponent.name == firstLink.href.removePrefix("/")) - return null - - return commonFirstComponent.name -} diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Link.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Link.kt index ec8db2eb94..7ad723540e 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Link.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Link.kt @@ -1,21 +1,17 @@ /* - * Module: r2-streamer-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. */ package org.readium.r2.streamer.extensions -import java.io.File import org.readium.r2.shared.publication.Link +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.util.mediatype.MediaType -/** Returns a [File] to the directory containing all links, if there is such a directory. */ -internal fun List.hrefCommonFirstComponent(): File? = - map { it.href.removePrefix("/").substringBefore("/") } - .distinct() - .takeIf { it.size == 1 } - ?.firstOrNull() - ?.let { File(it) } +internal suspend fun Container.Entry.toLink(mediaType: MediaType? = null): Link = + Link( + href = path, + mediaType = mediaType ?: mediaType().getOrNull() + ) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt index 618629d200..275cfaf7d0 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/fetcher/Fetcher.kt @@ -13,10 +13,13 @@ import java.io.InputStream import org.readium.r2.shared.publication.Publication @Suppress("UNUSED_PARAMETER", "unused") -@Deprecated("Use [publication.get(link)] to access publication content.", level = DeprecationLevel.ERROR) +@Deprecated( + "Use [publication.get(link)] to access publication content.", + level = DeprecationLevel.ERROR +) public class Fetcher( public var publication: Publication, - private val userPropertiesPath: String?, + private val userPropertiesPath: String? ) { public fun data(path: String): ByteArray? = throw NotImplementedError() diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt index a3882ffa5f..d8a86a722f 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt @@ -9,8 +9,8 @@ package org.readium.r2.streamer.parser import org.readium.r2.shared.error.MessageError import org.readium.r2.shared.error.ThrowableError import org.readium.r2.shared.error.Try -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType @@ -20,10 +20,17 @@ import org.readium.r2.shared.util.mediatype.MediaType */ public interface PublicationParser { + /** + * Full publication asset. + * + * @param mediaType Media type of the "virtual" publication asset, built from the source asset. + * For example, if the source asset was a `application/audiobook+json`, the "virtual" asset + * media type will be `application/audiobook+zip`. + * @param container Container granting access to the resources of the publication. + */ public data class Asset( - val name: String, val mediaType: MediaType, - val fetcher: Fetcher + val container: Container ) /** diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioLocatorService.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioLocatorService.kt index 6250afa947..ecfbc048b1 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioLocatorService.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioLocatorService.kt @@ -51,12 +51,15 @@ public class AudioLocatorService(private val readingOrder: List) : Locator return Locator( href = link.href, - type = link.type ?: MediaType.BINARY.toString(), + type = (link.mediaType ?: MediaType.BINARY).toString(), locations = Locator.Locations( fragments = listOf("t=${positionInResource.toInt()}"), progression = link.duration?.let { duration -> - if (duration == 0.0) 0.0 - else positionInResource / duration + if (duration == 0.0) { + 0.0 + } else { + positionInResource / duration + } }, totalProgression = totalProgression ) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt index 9bb44f4b52..de756bed98 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt @@ -8,7 +8,6 @@ package org.readium.r2.streamer.parser.audio import java.io.File import org.readium.r2.shared.error.Try -import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.LocalizedString import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Metadata @@ -18,6 +17,7 @@ import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.streamer.extensions.guessTitle import org.readium.r2.streamer.extensions.isHiddenOrThumbs import org.readium.r2.streamer.extensions.lowercasedExtension +import org.readium.r2.streamer.extensions.toLink import org.readium.r2.streamer.parser.PublicationParser /** @@ -32,19 +32,19 @@ public class AudioParser : PublicationParser { asset: PublicationParser.Asset, warnings: WarningLogger? ): Try { - - if (!asset.mediaType.matches(MediaType.ZAB) && !asset.mediaType.isAudio) + if (!asset.mediaType.matches(MediaType.ZAB) && !asset.mediaType.isAudio) { return Try.failure(PublicationParser.Error.FormatNotSupported()) + } val readingOrder = if (asset.mediaType.matches(MediaType.ZAB)) { - asset.fetcher.links() - .filter { link -> zabCanContain(link.href) } - .sortedBy(Link::href) + (asset.container.entries() ?: emptySet()) + .filter { entry -> zabCanContain(entry.path) } + .sortedBy { it.path } .toMutableList() } else { listOfNotNull( - asset.fetcher.links().firstOrNull() + asset.container.entries()?.firstOrNull() ) } @@ -54,19 +54,17 @@ public class AudioParser : PublicationParser { ) } - val title = asset.fetcher.guessTitle() ?: asset.name - val manifest = Manifest( metadata = Metadata( conformsTo = setOf(Publication.Profile.AUDIOBOOK), - localizedTitle = LocalizedString(title) + localizedTitle = asset.container.guessTitle()?.let { LocalizedString(it) } ), - readingOrder = readingOrder + readingOrder = readingOrder.map { it.toLink() } ) val publicationBuilder = Publication.Builder( manifest = manifest, - fetcher = asset.fetcher, + container = asset.container, servicesBuilder = Publication.ServicesBuilder( locator = AudioLocatorService.createFactory() ) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/AccessibilityAdapter.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/AccessibilityAdapter.kt index 9c6cc49b82..9868fb0d67 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/AccessibilityAdapter.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/AccessibilityAdapter.kt @@ -61,10 +61,14 @@ internal class AccessibilityAdapter { private fun conformedToProfileOrNull(item: MetadataItem): Accessibility.Profile? = if (item is MetadataItem.Meta && item.property == Vocabularies.DCTERMS + "conformsTo") { accessibilityProfileFromString(item.value) - } else if (item is MetadataItem.Link && item.rels.contains(Vocabularies.DCTERMS + "conformsTo")) { + } else if (item is MetadataItem.Link && item.rels.contains( + Vocabularies.DCTERMS + "conformsTo" + ) + ) { accessibilityProfileFromString(item.href) - } else + } else { null + } private fun adaptAccessModeSufficient(items: List): Pair>, List> = items .takeAllWithProperty(Vocabularies.SCHEMA + "accessModeSufficient") @@ -143,7 +147,7 @@ internal class AccessibilityAdapter { "http://idpf.org/epub/a11y/accessibility-20170105.html#wcag-a", "http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-a", "https://idpf.org/epub/a11y/accessibility-20170105.html#wcag-a", - "https://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-a", + "https://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-a" ) private fun isWCAG_20_AA(value: String) = value in setOf( @@ -151,7 +155,7 @@ internal class AccessibilityAdapter { "http://idpf.org/epub/a11y/accessibility-20170105.html#wcag-aa", "http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aa", "https://idpf.org/epub/a11y/accessibility-20170105.html#wcag-aa", - "https://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aa", + "https://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aa" ) private fun isWCAG_20_AAA(value: String) = value in setOf( @@ -159,6 +163,6 @@ internal class AccessibilityAdapter { "http://idpf.org/epub/a11y/accessibility-20170105.html#wcag-aaa", "http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aaa", "https://idpf.org/epub/a11y/accessibility-20170105.html#wcag-aaa", - "https://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aaa", + "https://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-aaa" ) } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EncryptionParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EncryptionParser.kt index d3816e7e63..84f0105952 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EncryptionParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EncryptionParser.kt @@ -23,8 +23,11 @@ internal object EncryptionParser { ?: return null val retrievalMethod = node.getFirst("KeyInfo", Namespaces.SIG) ?.getFirst("RetrievalMethod", Namespaces.SIG)?.getAttr("URI") - val scheme = if (retrievalMethod == "license.lcpl#/encryption/content_key") - ContentProtection.Scheme.Lcp.uri else null + val scheme = if (retrievalMethod == "license.lcpl#/encryption/content_key") { + ContentProtection.Scheme.Lcp.uri + } else { + null + } val algorithm = node.getFirst("EncryptionMethod", Namespaces.ENC) ?.getAttr("Algorithm") ?: return null diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscator.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscator.kt index bb51d2f4db..701f932c7a 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscator.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscator.kt @@ -9,28 +9,35 @@ package org.readium.r2.streamer.parser.epub import com.mcxiaoke.koi.HASH import com.mcxiaoke.koi.ext.toHexBytes import kotlin.experimental.xor -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.LazyResource -import org.readium.r2.shared.fetcher.TransformingResource -import org.readium.r2.shared.publication.encryption.encryption +import org.readium.r2.shared.publication.encryption.Encryption +import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.TransformingResource +import org.readium.r2.shared.resource.flatMap +import org.readium.r2.shared.util.Url /** * Deobfuscates fonts according to https://www.w3.org/TR/epub-33/#sec-font-obfuscation */ -internal class EpubDeobfuscator(private val pubId: String) { +internal class EpubDeobfuscator( + private val pubId: String, + private val retrieveEncryption: (Url) -> Encryption? +) { - fun transform(resource: Fetcher.Resource): Fetcher.Resource = LazyResource { - val algorithm = resource.link().properties.encryption?.algorithm - if (algorithm != null && algorithm2length.containsKey(algorithm)) { - DeobfuscatingResource(resource, algorithm) - } else { - resource + fun transform(resource: Resource): Resource = + resource.flatMap { + val algorithm = resource.source?.let(retrieveEncryption)?.algorithm + if (algorithm != null && algorithm2length.containsKey(algorithm)) { + DeobfuscatingResource(resource, algorithm) + } else { + resource + } } - } - inner class DeobfuscatingResource(resource: Fetcher.Resource, private val algorithm: String) : - TransformingResource(resource) { + inner class DeobfuscatingResource( + private val resource: Resource, + private val algorithm: String + ) : TransformingResource(resource) { // The obfuscation doesn't change the length of the resource. override suspend fun length(): ResourceTry = @@ -46,7 +53,11 @@ internal class EpubDeobfuscator(private val pubId: String) { else -> HASH.sha1(pubId).toHexBytes() } - deobfuscate(bytes = bytes, obfuscationKey = obfuscationKey, obfuscationLength = obfuscationLength) + deobfuscate( + bytes = bytes, + obfuscationKey = obfuscationKey, + obfuscationLength = obfuscationLength + ) bytes } } @@ -57,7 +68,6 @@ internal class EpubDeobfuscator(private val pubId: String) { ) private fun deobfuscate(bytes: ByteArray, obfuscationKey: ByteArray, obfuscationLength: Int) { - @Suppress("NAME_SHADOWING") val toDeobfuscate = 0 until obfuscationLength for (i in toDeobfuscate) bytes[i] = bytes[i].xor(obfuscationKey[i % obfuscationKey.size]) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt index c370ed7603..2c8a7fafbd 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt @@ -10,18 +10,20 @@ import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.extensions.addPrefix -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.TransformingFetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.encryption.Encryption +import org.readium.r2.shared.publication.encryption.encryption import org.readium.r2.shared.publication.services.content.DefaultContentService import org.readium.r2.shared.publication.services.content.iterators.HtmlResourceContentIterator import org.readium.r2.shared.publication.services.search.StringSearchService +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.TransformingContainer import org.readium.r2.shared.resource.readAsXml import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.shared.util.use import org.readium.r2.streamer.extensions.readAsXmlOrNull import org.readium.r2.streamer.parser.PublicationParser @@ -34,6 +36,7 @@ import org.readium.r2.streamer.parser.PublicationParser */ @OptIn(ExperimentalReadiumApi::class) public class EpubParser( + private val mediaTypeRetriever: MediaTypeRetriever, private val reflowablePositionsStrategy: EpubPositionsService.ReflowableStrategy = EpubPositionsService.ReflowableStrategy.recommended ) : PublicationParser { @@ -41,33 +44,39 @@ public class EpubParser( asset: PublicationParser.Asset, warnings: WarningLogger? ): Try { - if (asset.mediaType != MediaType.EPUB) + if (asset.mediaType != MediaType.EPUB) { return Try.failure(PublicationParser.Error.FormatNotSupported()) + } - val opfPath = getRootFilePath(asset.fetcher) + val opfPath = getRootFilePath(asset.container) .getOrElse { return Try.failure(it) } .addPrefix("/") - val opfXmlDocument = asset.fetcher.get(opfPath).readAsXml() + val opfXmlDocument = asset.container.get(opfPath).readAsXml() .getOrElse { return Try.failure(PublicationParser.Error.IO(it)) } - val packageDocument = PackageDocument.parse(opfXmlDocument, opfPath) + val packageDocument = PackageDocument.parse(opfXmlDocument, opfPath, mediaTypeRetriever) ?: return Try.failure(PublicationParser.Error.ParsingFailed("Invalid OPF file.")) val manifest = ManifestAdapter( - fallbackTitle = asset.name, packageDocument = packageDocument, - navigationData = parseNavigationData(packageDocument, asset.fetcher), - encryptionData = parseEncryptionData(asset.fetcher), - displayOptions = parseDisplayOptions(asset.fetcher) + navigationData = parseNavigationData(packageDocument, asset.container), + encryptionData = parseEncryptionData(asset.container), + displayOptions = parseDisplayOptions(asset.container), + mediaTypeRetriever = mediaTypeRetriever ).adapt() - var fetcher = asset.fetcher - manifest.metadata.identifier?.let { - fetcher = TransformingFetcher(fetcher, EpubDeobfuscator(it)::transform) + var container = asset.container + manifest.metadata.identifier?.let { id -> + val deobfuscator = EpubDeobfuscator(id) { url -> + manifest.linkWithHref(url.toString()) + ?.properties?.encryption + } + + container = TransformingContainer(container, deobfuscator::transform) } val builder = Publication.Builder( manifest = manifest, - fetcher = fetcher, + container = container, servicesBuilder = Publication.ServicesBuilder( positions = EpubPositionsService.createFactory(reflowablePositionsStrategy), search = StringSearchService.createDefaultFactory(), @@ -75,15 +84,15 @@ public class EpubParser( resourceContentIteratorFactories = listOf( HtmlResourceContentIterator.Factory() ) - ), + ) ) ) return Try.success(builder) } - private suspend fun getRootFilePath(fetcher: Fetcher): Try = - fetcher.get("/META-INF/container.xml") + private suspend fun getRootFilePath(container: Container): Try = + container.get("/META-INF/container.xml") .use { it.readAsXml() } .getOrElse { return Try.failure(PublicationParser.Error.IO(it)) } .getFirst("rootfiles", Namespaces.OPC) @@ -92,27 +101,30 @@ public class EpubParser( ?.let { Try.success(it) } ?: Try.failure(PublicationParser.Error.ParsingFailed("Cannot successfully parse OPF.")) - private suspend fun parseEncryptionData(fetcher: Fetcher): Map = - fetcher.readAsXmlOrNull("/META-INF/encryption.xml") + private suspend fun parseEncryptionData(container: Container): Map = + container.readAsXmlOrNull("/META-INF/encryption.xml") ?.let { EncryptionParser.parse(it) } ?: emptyMap() - private suspend fun parseNavigationData(packageDocument: PackageDocument, fetcher: Fetcher): Map> = - parseNavigationDocument(packageDocument, fetcher) - ?: parseNcx(packageDocument, fetcher) + private suspend fun parseNavigationData(packageDocument: PackageDocument, container: Container): Map> = + parseNavigationDocument(packageDocument, container) + ?: parseNcx(packageDocument, container) ?: emptyMap() - private suspend fun parseNavigationDocument(packageDocument: PackageDocument, fetcher: Fetcher): Map>? = + private suspend fun parseNavigationDocument( + packageDocument: PackageDocument, + container: Container + ): Map>? = packageDocument.manifest .firstOrNull { it.properties.contains(Vocabularies.ITEM + "nav") } ?.let { navItem -> val navPath = Href(navItem.href, baseHref = packageDocument.path).string - fetcher.readAsXmlOrNull(navPath) + container.readAsXmlOrNull(navPath) ?.let { NavigationDocumentParser.parse(it, navPath) } } ?.takeUnless { it.isEmpty() } - private suspend fun parseNcx(packageDocument: PackageDocument, fetcher: Fetcher): Map>? { + private suspend fun parseNcx(packageDocument: PackageDocument, container: Container): Map>? { val ncxItem = if (packageDocument.spine.toc != null) { packageDocument.manifest.firstOrNull { it.id == packageDocument.spine.toc } @@ -123,15 +135,15 @@ public class EpubParser( return ncxItem ?.let { val ncxPath = Href(ncxItem.href, baseHref = packageDocument.path).string - fetcher.readAsXmlOrNull(ncxPath)?.let { NcxParser.parse(it, ncxPath) } + container.readAsXmlOrNull(ncxPath)?.let { NcxParser.parse(it, ncxPath) } } ?.takeUnless { it.isEmpty() } } - private suspend fun parseDisplayOptions(fetcher: Fetcher): Map { + private suspend fun parseDisplayOptions(container: Container): Map { val displayOptionsXml = - fetcher.readAsXmlOrNull("/META-INF/com.apple.ibooks.display-options.xml") - ?: fetcher.readAsXmlOrNull("/META-INF/com.kobobooks.display-options.xml") + container.readAsXmlOrNull("/META-INF/com.apple.ibooks.display-options.xml") + ?: container.readAsXmlOrNull("/META-INF/com.kobobooks.display-options.xml") return displayOptionsXml?.getFirst("platform", "") ?.get("option", "") diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubPositionsService.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubPositionsService.kt index d9d2f07cd6..4f5b3e08cd 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubPositionsService.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubPositionsService.kt @@ -7,21 +7,23 @@ package org.readium.r2.streamer.parser.epub import kotlin.math.ceil -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.archive.archive import org.readium.r2.shared.publication.encryption.encryption import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.publication.epub.layoutOf import org.readium.r2.shared.publication.presentation.Presentation import org.readium.r2.shared.publication.presentation.presentation import org.readium.r2.shared.publication.services.PositionsService +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.archive +import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.use /** - * Positions Service for an EPUB from its [readingOrder] and [fetcher]. + * Positions Service for an EPUB from its [readingOrder] and [container]. * * The [presentation] is used to apply different calculation strategy if the resource has a * reflowable or fixed layout. @@ -32,7 +34,7 @@ import org.readium.r2.shared.util.use public class EpubPositionsService( private val readingOrder: List, private val presentation: Presentation, - private val fetcher: Fetcher, + private val container: Container, private val reflowableStrategy: ReflowableStrategy ) : PositionsService { @@ -47,7 +49,7 @@ public class EpubPositionsService( EpubPositionsService( readingOrder = context.manifest.readingOrder, presentation = context.manifest.metadata.presentation, - fetcher = context.fetcher, + container = context.container, reflowableStrategy = reflowableStrategy ) } @@ -60,15 +62,15 @@ public class EpubPositionsService( */ public sealed class ReflowableStrategy { /** Returns the number of positions in the given [resource] according to the strategy. */ - public abstract suspend fun positionCount(resource: Fetcher.Resource): Int + public abstract suspend fun positionCount(link: Link, resource: Resource): Int /** * Use the original length of each resource (before compression and encryption) and split it * by the given [pageLength]. */ public data class OriginalLength(val pageLength: Int) : ReflowableStrategy() { - override suspend fun positionCount(resource: Fetcher.Resource): Int { - val length = resource.link().properties.encryption?.originalLength + override suspend fun positionCount(link: Link, resource: Resource): Int { + val length = link.properties.encryption?.originalLength ?: resource.length().getOrNull() ?: 0 return ceil(length.toDouble() / pageLength.toDouble()).toInt() @@ -81,8 +83,8 @@ public class EpubPositionsService( * given [pageLength]. */ public data class ArchiveEntryLength(val pageLength: Int) : ReflowableStrategy() { - override suspend fun positionCount(resource: Fetcher.Resource): Int { - val length = resource.link().properties.archive?.entryLength + override suspend fun positionCount(link: Link, resource: Resource): Int { + val length = resource.properties().getOrNull()?.archive?.entryLength ?: resource.length().getOrNull() ?: 0 return ceil(length.toDouble() / pageLength.toDouble()).toInt() @@ -102,8 +104,9 @@ public class EpubPositionsService( } override suspend fun positionsByReadingOrder(): List> { - if (!::_positions.isInitialized) + if (!::_positions.isInitialized) { _positions = computePositions() + } return _positions } @@ -117,7 +120,7 @@ public class EpubPositionsService( if (presentation.layoutOf(link) == EpubLayout.FIXED) { createFixed(link, lastPositionOfPreviousResource) } else { - createReflowable(link, lastPositionOfPreviousResource, fetcher) + createReflowable(link, lastPositionOfPreviousResource, container) } positions.lastOrNull()?.locations?.position?.let { @@ -128,7 +131,7 @@ public class EpubPositionsService( } // Calculates [totalProgression]. - val totalPageCount = positions.map { it.size }.sum() + val totalPageCount = positions.sumOf { it.size } positions = positions.map { item -> item.map { locator -> val position = locator.locations.position @@ -153,9 +156,9 @@ public class EpubPositionsService( ) ) - private suspend fun createReflowable(link: Link, startPosition: Int, fetcher: Fetcher): List { - val positionCount = fetcher.get(link).use { resource -> - reflowableStrategy.positionCount(resource) + private suspend fun createReflowable(link: Link, startPosition: Int, container: Container): List { + val positionCount = container.get(link.href).use { resource -> + reflowableStrategy.positionCount(link, resource) } return (1..positionCount).map { position -> @@ -169,7 +172,7 @@ public class EpubPositionsService( private fun createLocator(link: Link, progression: Double, position: Int) = Locator( href = link.href, - type = link.type ?: "text/html", + type = (link.mediaType ?: MediaType.HTML).toString(), title = link.title, locations = Locator.Locations( progression = progression, diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ManifestAdapter.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ManifestAdapter.kt index 8e94f84b87..af82590f64 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ManifestAdapter.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ManifestAdapter.kt @@ -10,6 +10,7 @@ import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.PublicationCollection import org.readium.r2.shared.publication.encryption.Encryption +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever /** * Creates a [Manifest] model from an EPUB package's document. @@ -18,11 +19,11 @@ import org.readium.r2.shared.publication.encryption.Encryption * See https://github.com/readium/architecture/blob/master/streamer/parser/metadata.md#epub-2x-9 */ internal class ManifestAdapter( - private val fallbackTitle: String, private val packageDocument: PackageDocument, private val navigationData: Map> = emptyMap(), private val encryptionData: Map = emptyMap(), - private val displayOptions: Map = emptyMap() + private val displayOptions: Map = emptyMap(), + private val mediaTypeRetriever: MediaTypeRetriever ) { private val epubVersion = packageDocument.epubVersion private val spine = packageDocument.spine @@ -31,7 +32,6 @@ internal class ManifestAdapter( // Compute metadata val metadata = MetadataAdapter( epubVersion, - fallbackTitle, packageDocument.uniqueIdentifierId, spine.direction, displayOptions @@ -39,12 +39,12 @@ internal class ManifestAdapter( // Compute links val (readingOrder, resources) = ResourceAdapter( - epubVersion, packageDocument.spine, packageDocument.manifest, encryptionData, metadata.coverId, metadata.durationById, + mediaTypeRetriever = mediaTypeRetriever ).adapt() // Compute toc and otherCollections diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt index c4ff6a7a7d..9513d8b6c5 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataAdapter.kt @@ -14,7 +14,6 @@ import org.readium.r2.shared.publication.presentation.Presentation internal class MetadataAdapter( private val epubVersion: Double, - private val fallbackTitle: String, private val uniqueIdentifierId: String?, private val readingProgression: ReadingProgression?, private val displayOptions: Map @@ -65,7 +64,7 @@ internal class MetadataAdapter( ?.value val (localizedTitle, localizedSortAs, localizedSubtitle) = globalItemsHolder - .adapt(TitleAdapter(fallbackTitle)::adapt) + .adapt(TitleAdapter()::adapt) val (belongsToCollections, belongsToSeries) = globalItemsHolder .adapt(CollectionAdapter()::adapt) @@ -149,14 +148,16 @@ private class LinksAdapter { private fun mapLink(link: MetadataItem.Link): Link { val contains: MutableList = mutableListOf() if (link.rels.contains(Vocabularies.LINK + "record")) { - if (link.properties.contains(Vocabularies.LINK + "onix")) + if (link.properties.contains(Vocabularies.LINK + "onix")) { contains.add("onix") - if (link.properties.contains(Vocabularies.LINK + "xmp")) + } + if (link.properties.contains(Vocabularies.LINK + "xmp")) { contains.add("xmp") + } } return Link( href = link.href, - type = link.mediaType, + mediaType = link.mediaType, rels = link.rels, properties = Properties(mapOf("contains" to contains)) ) @@ -187,10 +188,10 @@ private class LanguageAdapter { .mapFirst { it.map(MetadataItem.Meta::value) } } -private class TitleAdapter(private val fallbackTitle: String) { +private class TitleAdapter() { data class Result( - val localizedTitle: LocalizedString, + val localizedTitle: LocalizedString?, val localizedSortAs: LocalizedString?, val localizedSubtitle: LocalizedString? ) @@ -205,7 +206,6 @@ private class TitleAdapter(private val fallbackTitle: String) { val mainTitleItem = mainTitleWithItem?.second val localizedTitle = mainTitle?.value - ?: LocalizedString(fallbackTitle) val localizedSortAs = mainTitle?.fileAs ?: items.firstWithProperty("calibre:title_sort") ?.let { LocalizedString(it.value) } @@ -221,7 +221,11 @@ private class TitleAdapter(private val fallbackTitle: String) { .removeFirstOrNull { it == mainTitleItem }.second .removeFirstOrNull { it == subtitleItem }.second - return Result(localizedTitle, localizedSortAs, localizedSubtitle) to remainingItems + return Result( + localizedTitle = localizedTitle, + localizedSortAs = localizedSortAs, + localizedSubtitle = localizedSubtitle + ) to remainingItems } } @@ -294,8 +298,11 @@ private fun MetadataItem.Meta.toContributor(): Pair { } val contributor = Contributor( - localizedString, localizedSortAs = localizedSortAs, - roles = roles, identifier = identifier, position = groupPosition + localizedString, + localizedSortAs = localizedSortAs, + roles = roles, + identifier = identifier, + position = groupPosition ) return Pair(type, contributor) @@ -357,9 +364,9 @@ private class OtherMetadataAdapter { } private fun MetadataItem.Meta.toMap(): Any = - if (children.isEmpty()) + if (children.isEmpty()) { value - else { + } else { val mappedMetaChildren = children .filterIsInstance(MetadataItem.Meta::class.java) .associate { Pair(it.property, it.toMap()) } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataParser.kt index bfddcbd072..75cd3f8ac4 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/MetadataParser.kt @@ -8,10 +8,12 @@ package org.readium.r2.streamer.parser.epub import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever internal class MetadataParser( - private val epubVersion: Double, - private val prefixMap: Map + private val prefixMap: Map, + private val mediaTypeRetriever: MediaTypeRetriever ) { fun parse(document: ElementNode, filePath: String): List? { @@ -39,7 +41,13 @@ internal class MetadataParser( val relAttr = element.getAttr("rel").orEmpty() val rel = parseProperties(relAttr).map { resolveProperty(it, prefixMap, DEFAULT_VOCAB.LINK) } val propAttr = element.getAttr("properties").orEmpty() - val properties = parseProperties(propAttr).map { resolveProperty(it, prefixMap, DEFAULT_VOCAB.LINK) } + val properties = parseProperties(propAttr).map { + resolveProperty( + it, + prefixMap, + DEFAULT_VOCAB.LINK + ) + } val mediaType = element.getAttr("media-type") val refines = element.getAttr("refines")?.removePrefix("#") return MetadataItem.Link( @@ -47,7 +55,7 @@ internal class MetadataParser( refines = refines, href = Href(href, baseHref = filePath).string, rels = rel.toSet(), - mediaType = mediaType, + mediaType = mediaTypeRetriever.retrieve(mediaType), properties = properties ) } @@ -73,7 +81,12 @@ internal class MetadataParser( ?: return null val resolvedProp = resolveProperty(propName, prefixMap, DEFAULT_VOCAB.META) val resolvedScheme = - element.getAttr("scheme")?.trim()?.ifEmpty { null }?.let { resolveProperty(it, prefixMap) } + element.getAttr("scheme")?.trim()?.ifEmpty { null }?.let { + resolveProperty( + it, + prefixMap + ) + } val refines = element.getAttr("refines")?.removePrefix("#") MetadataItem.Meta( id = element.id, @@ -90,7 +103,11 @@ internal class MetadataParser( val propValue = element.text?.trim()?.ifEmpty { null } ?: return null val propName = Vocabularies.DCTERMS + element.name return when (element.name) { - "creator", "contributor", "publisher" -> contributorWithLegacyAttr(element, propName, propValue) + "creator", "contributor", "publisher" -> contributorWithLegacyAttr( + element, + propName, + propValue + ) "date" -> dateWithLegacyAttr(element, propName, propValue) else -> MetadataItem.Meta( id = element.id, @@ -141,6 +158,7 @@ internal class MetadataParser( private fun resolveItemsHierarchy(items: List): List { val metadataIds = items.mapNotNull { it.id } val rootExpr = items.filter { it.refines == null || it.refines !in metadataIds } + @Suppress("Unchecked_cast") val exprByRefines = items.groupBy(MetadataItem::refines) as Map> return rootExpr.map { computeMetadataItem(it, exprByRefines, emptySet()) } @@ -175,8 +193,8 @@ internal sealed class MetadataItem { override val children: List = emptyList(), val href: String, val rels: Set, - val mediaType: String?, - val properties: List = emptyList(), + val mediaType: MediaType?, + val properties: List = emptyList() ) : MetadataItem() data class Meta( @@ -186,6 +204,6 @@ internal sealed class MetadataItem { val property: String, val value: String, val lang: String, - val scheme: String? = null, + val scheme: String? = null ) : MetadataItem() } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParser.kt index 53fc3f5b10..f06cc1af56 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParser.kt @@ -18,7 +18,13 @@ internal object NavigationDocumentParser { val prefixMap = CONTENT_RESERVED_PREFIXES + docPrefixes // prefix element overrides reserved prefixes val body = document.getFirst("body", Namespaces.XHTML) ?: return emptyMap() - val navs = body.collect("nav", Namespaces.XHTML).mapNotNull { parseNavElement(it, filePath, prefixMap) } + val navs = body.collect("nav", Namespaces.XHTML).mapNotNull { + parseNavElement( + it, + filePath, + prefixMap + ) + } val navMap = navs.flatMap { nav -> nav.first.map { type -> Pair(type, nav.second) } }.toMap() @@ -34,7 +40,13 @@ internal object NavigationDocumentParser { prefixMap: Map ): Pair, List>? { val typeAttr = nav.getAttrNs("type", Namespaces.OPS) ?: return null - val types = parseProperties(typeAttr).mapNotNull { resolveProperty(it, prefixMap, DEFAULT_VOCAB.TYPE) } + val types = parseProperties(typeAttr).mapNotNull { + resolveProperty( + it, + prefixMap, + DEFAULT_VOCAB.TYPE + ) + } val links = nav.getFirst("ol", Namespaces.XHTML)?.let { parseOlElement(it, filePath) } return if (types.isNotEmpty() && !links.isNullOrEmpty()) Pair(types, links) else null } @@ -44,9 +56,23 @@ internal object NavigationDocumentParser { private fun parseLiElement(element: ElementNode, filePath: String): Link? { val first = element.getAll().firstOrNull() ?: return null // should be , , or

    - val title = if (first.name == "ol") "" else first.collectText().replace("\\s+".toRegex(), " ").trim() + val title = if (first.name == "ol") { + "" + } else { + first.collectText().replace( + "\\s+".toRegex(), + " " + ).trim() + } val rawHref = first.getAttr("href") - val href = if (first.name == "a" && !rawHref.isNullOrBlank()) Href(rawHref, baseHref = filePath).string else "#" + val href = if (first.name == "a" && !rawHref.isNullOrBlank()) { + Href( + rawHref, + baseHref = filePath + ).string + } else { + "#" + } val children = element.getFirst("ol", Namespaces.XHTML)?.let { parseOlElement(it, filePath) }.orEmpty() return if (children.isEmpty() && (href == "#" || title == "")) { diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NcxParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NcxParser.kt index 5e76b46381..dee9cfb4e4 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NcxParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/NcxParser.kt @@ -27,19 +27,27 @@ internal object NcxParser { element.get("pageTarget", Namespaces.NCX).mapNotNull { val href = extractHref(it, filePath) val title = extractTitle(it) - if (href.isNullOrBlank() || title.isNullOrBlank()) + if (href.isNullOrBlank() || title.isNullOrBlank()) { null - else Link(title = title, href = href) + } else { + Link(title = title, href = href) + } } private fun parseNavPointElement(element: ElementNode, filePath: String): Link? { val title = extractTitle(element) val href = extractHref(element, filePath) - val children = element.get("navPoint", Namespaces.NCX).mapNotNull { parseNavPointElement(it, filePath) } - return if (children.isEmpty() && (href == null || title == null)) + val children = element.get("navPoint", Namespaces.NCX).mapNotNull { + parseNavPointElement( + it, + filePath + ) + } + return if (children.isEmpty() && (href == null || title == null)) { null - else + } else { Link(title = title, href = href ?: "#", children = children) + } } private fun extractTitle(element: ElementNode) = diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt index 6b1baad4c4..cdffc51431 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PackageDocument.kt @@ -9,6 +9,7 @@ package org.readium.r2.streamer.parser.epub import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.publication.ReadingProgression import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever internal data class PackageDocument( val path: String, @@ -20,11 +21,11 @@ internal data class PackageDocument( ) { companion object { - fun parse(document: ElementNode, filePath: String): PackageDocument? { + fun parse(document: ElementNode, filePath: String, mediaTypeRetriever: MediaTypeRetriever): PackageDocument? { val packagePrefixes = document.getAttr("prefix")?.let { parsePrefixes(it) }.orEmpty() val prefixMap = PACKAGE_RESERVED_PREFIXES + packagePrefixes // prefix element overrides reserved prefixes val epubVersion = document.getAttr("version")?.toDoubleOrNull() ?: 1.2 - val metadata = MetadataParser(epubVersion, prefixMap).parse(document, filePath) + val metadata = MetadataParser(prefixMap, mediaTypeRetriever).parse(document, filePath) ?: return null val manifestElement = document.getFirst("manifest", Namespaces.OPF) ?: return null @@ -57,7 +58,13 @@ internal data class Item( val href = element.getAttr("href")?.let { Href(it, baseHref = filePath).string } ?: return null val propAttr = element.getAttr("properties").orEmpty() - val properties = parseProperties(propAttr).map { resolveProperty(it, prefixMap, DEFAULT_VOCAB.ITEM) } + val properties = parseProperties(propAttr).map { + resolveProperty( + it, + prefixMap, + DEFAULT_VOCAB.ITEM + ) + } return Item( href = href, id = element.id, @@ -77,7 +84,12 @@ internal data class Spine( ) { companion object { fun parse(element: ElementNode, prefixMap: Map, epubVersion: Double): Spine { - val itemrefs = element.get("itemref", Namespaces.OPF).mapNotNull { Itemref.parse(it, prefixMap) } + val itemrefs = element.get("itemref", Namespaces.OPF).mapNotNull { + Itemref.parse( + it, + prefixMap + ) + } val pageProgressionDirection = when (element.getAttr("page-progression-direction")) { "rtl" -> ReadingProgression.RTL "ltr" -> ReadingProgression.LTR diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PresentationAdapter.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PresentationAdapter.kt index ba43a4f7ce..accdb8a286 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PresentationAdapter.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PresentationAdapter.kt @@ -31,13 +31,16 @@ internal class PresentationAdapter( val layoutProp = if (epubVersion < 3.0) { - if (displayOptions["fixed-layout"] == "true") + if (displayOptions["fixed-layout"] == "true") { "pre-paginated" - else + } else { "reflowable" - } else itemsHolder - .adapt { it.takeFirstWithProperty(Vocabularies.RENDITION + "layout") } - ?.value + } + } else { + itemsHolder + .adapt { it.takeFirstWithProperty(Vocabularies.RENDITION + "layout") } + ?.value + } val (overflow, continuous) = when (flowProp) { "paginated" -> Pair(Presentation.Overflow.PAGINATED, false) @@ -65,8 +68,11 @@ internal class PresentationAdapter( } val presentation = Presentation( - overflow = overflow, continuous = continuous, - layout = layout, orientation = orientation, spread = spread + overflow = overflow, + continuous = continuous, + layout = layout, + orientation = orientation, + spread = spread ) return presentation to itemsHolder.remainingItems diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PropertyDataType.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PropertyDataType.kt index 20ec765144..1fcf8ca4d2 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PropertyDataType.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/PropertyDataType.kt @@ -40,8 +40,9 @@ internal fun resolveProperty( defaultVocab.iri + splitted[0] } else if (splitted.size == 2 && prefixMap[splitted[0]] != null) { prefixMap[splitted[0]] + splitted[1] - } else + } else { property + } } internal fun parsePrefixes(prefixes: String): Map = diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ResourceAdapter.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ResourceAdapter.kt index 85dda67f48..27c991d1f2 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ResourceAdapter.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/ResourceAdapter.kt @@ -10,14 +10,15 @@ import org.readium.r2.shared.extensions.toMap import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Properties import org.readium.r2.shared.publication.encryption.Encryption +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever internal class ResourceAdapter( - private val epubVersion: Double, private val spine: Spine, private val manifest: List, private val encryptionData: Map, private val coverId: String?, - private val durationById: Map + private val durationById: Map, + private val mediaTypeRetriever: MediaTypeRetriever ) { data class Links( val readingOrder: List, @@ -34,7 +35,13 @@ internal class ResourceAdapter( fun adapt(): Links { val readingOrderIds = spine.itemrefs.filter { it.linear }.map { it.idref } - val readingOrder = readingOrderIds.mapNotNull { id -> itemById[id]?.let { item -> computeLink(item) } } + val readingOrder = readingOrderIds.mapNotNull { id -> + itemById[id]?.let { item -> + computeLink( + item + ) + } + } val readingOrderAllIds = computeIdsWithFallbacks(readingOrderIds) val resourceItems = manifest.filterNot { it.id in readingOrderAllIds } val resources = resourceItems.map { computeLink(it) } @@ -64,7 +71,7 @@ internal class ResourceAdapter( return Link( href = item.href, - type = item.mediaType, + mediaType = mediaTypeRetriever.retrieve(item.mediaType), duration = durationById[item.id], rels = rels, properties = properties, @@ -98,13 +105,15 @@ internal class ResourceAdapter( /** Compute alternate links for [item], checking for an infinite recursion */ private fun computeAlternates(item: Item, fallbackChain: Set): List { - val fallback = item.fallback?.let { id -> - if (id in fallbackChain) null else + if (id in fallbackChain) { + null + } else { itemById[id]?.let { val updatedChain = if (item.id != null) fallbackChain + item.id else fallbackChain computeLink(it, updatedChain) } + } } val mediaOverlays = item.mediaOverlay?.let { id -> itemById[id]?.let { diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/SmilParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/SmilParser.kt index bbd1a4e5ce..69d747a2c1 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/SmilParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/SmilParser.kt @@ -27,10 +27,11 @@ internal object SmilParser { private fun parseSeq(node: ElementNode, filePath: String): List? { val children: MutableList = mutableListOf() for (child in node.getAll()) { - if (child.name == "par" && child.namespace == Namespaces.SMIL) + if (child.name == "par" && child.namespace == Namespaces.SMIL) { parsePar(child, filePath)?.let { children.add(it) } - else if (child.name == "seq" && child.namespace == Namespaces.SMIL) + } else if (child.name == "seq" && child.namespace == Namespaces.SMIL) { parseSeq(child, filePath)?.let { children.addAll(it) } + } } /* No wrapping media overlay can be created unless: @@ -42,7 +43,9 @@ internal object SmilParser { return if (textref != null && audioFiles.distinct().size == 1) { // hierarchy val normalizedTextref = Href(textref, baseHref = filePath).string listOf(mediaOverlayFromChildren(normalizedTextref, children)) - } else children + } else { + children + } } private fun parsePar(node: ElementNode, filePath: String): MediaOverlayNode? { @@ -53,7 +56,10 @@ internal object SmilParser { val end = audioNode.getAttr("clipEnd")?.let { ClockValueParser.parse(it) } ?: "" "$src#t=$begin,$end" } - return MediaOverlayNode(Href(text, baseHref = filePath).string, Href(audio ?: "", baseHref = filePath).string) + return MediaOverlayNode( + Href(text, baseHref = filePath).string, + Href(audio ?: "", baseHref = filePath).string + ) } private fun mediaOverlayFromChildren(text: String, children: List): MediaOverlayNode { diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt index ab0bd2f56f..64538fb889 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt @@ -14,6 +14,7 @@ import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.streamer.extensions.guessTitle import org.readium.r2.streamer.extensions.isHiddenOrThumbs +import org.readium.r2.streamer.extensions.toLink import org.readium.r2.streamer.parser.PublicationParser /** @@ -28,21 +29,20 @@ public class ImageParser : PublicationParser { asset: PublicationParser.Asset, warnings: WarningLogger? ): Try { - - if (!asset.mediaType.matches(MediaType.CBZ) && !asset.mediaType.isBitmap) + if (!asset.mediaType.matches(MediaType.CBZ) && !asset.mediaType.isBitmap) { return Try.failure(PublicationParser.Error.FormatNotSupported()) + } val readingOrder = if (asset.mediaType.matches(MediaType.CBZ)) { - asset.fetcher.links() - .filter { !File(it.href).isHiddenOrThumbs && it.mediaType.isBitmap } - .sortedBy(Link::href) - .toMutableList() + (asset.container.entries() ?: emptySet()) + .filter { !File(it.path).isHiddenOrThumbs && it.mediaType().getOrNull()?.isBitmap == true } + .sortedBy { it.path } } else { - listOfNotNull( - asset.fetcher.links().firstOrNull() - ).toMutableList() + listOfNotNull(asset.container.entries()?.firstOrNull()) } + .map { it.toLink() } + .toMutableList() if (readingOrder.isEmpty()) { return Try.failure( @@ -50,22 +50,20 @@ public class ImageParser : PublicationParser { ) } - val title = asset.fetcher.guessTitle() ?: asset.name - // First valid resource is the cover. readingOrder[0] = readingOrder[0].copy(rels = setOf("cover")) val manifest = Manifest( metadata = Metadata( conformsTo = setOf(Publication.Profile.DIVINA), - localizedTitle = LocalizedString(title) + localizedTitle = asset.container.guessTitle()?.let { LocalizedString(it) } ), readingOrder = readingOrder ) val publicationBuilder = Publication.Builder( manifest = manifest, - fetcher = asset.fetcher, + container = asset.container, servicesBuilder = Publication.ServicesBuilder( positions = PerResourcePositionsService.createFactory(fallbackMediaType = "image/*") ) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt index a5c9af3fcc..ca0d074cf6 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt @@ -17,6 +17,7 @@ import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.pdf.PdfDocumentFactory import org.readium.r2.shared.util.pdf.toLinks +import org.readium.r2.streamer.extensions.toLink import org.readium.r2.streamer.parser.PublicationParser /** @@ -35,26 +36,27 @@ public class PdfParser( asset: PublicationParser.Asset, warnings: WarningLogger? ): Try { - if (asset.mediaType != MediaType.PDF) + if (asset.mediaType != MediaType.PDF) { return Try.failure(PublicationParser.Error.FormatNotSupported()) + } - val fileHref = asset.fetcher.links().firstOrNull()?.href + val resource = asset.container.entries()?.firstOrNull() ?: return Try.failure( PublicationParser.Error.ParsingFailed("No PDF found in the publication.") ) - val document = pdfFactory.open(asset.fetcher.get(fileHref), password = null) - val tableOfContents = document.outline.toLinks(fileHref) + val document = pdfFactory.open(resource, password = null) + val tableOfContents = document.outline.toLinks(resource.path) val manifest = Manifest( metadata = Metadata( identifier = document.identifier, conformsTo = setOf(Publication.Profile.PDF), - localizedTitle = LocalizedString(document.title?.ifBlank { null } ?: asset.name), + localizedTitle = document.title?.ifBlank { null }?.let { LocalizedString(it) }, authors = listOfNotNull(document.author).map { Contributor(name = it) }, readingProgression = document.readingProgression, - numberOfPages = document.pageCount, + numberOfPages = document.pageCount ), - readingOrder = listOf(Link(href = fileHref, type = MediaType.PDF.toString())), + readingOrder = listOf(resource.toLink(MediaType.PDF)), tableOfContents = tableOfContents ) @@ -64,7 +66,7 @@ public class PdfParser( cover = document.cover(context)?.let { InMemoryCoverService.createFactory(it) } ) - val publicationBuilder = Publication.Builder(manifest, asset.fetcher, servicesBuilder) + val publicationBuilder = Publication.Builder(manifest, asset.container, servicesBuilder) return Try.success(publicationBuilder) } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfPositionsService.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfPositionsService.kt index e9d028ce99..4c9c15e076 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfPositionsService.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfPositionsService.kt @@ -43,7 +43,7 @@ internal class PdfPositionsService( val progression = (position - 1) / pageCount.toDouble() Locator( href = link.href, - type = link.type ?: MediaType.PDF.toString(), + type = (link.mediaType ?: MediaType.PDF).toString(), locations = Locator.Locations( fragments = listOf("page=$position"), progression = progression, diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/LcpdfPositionsService.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/LcpdfPositionsService.kt index 602c832e78..bf95a1ff3a 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/LcpdfPositionsService.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/LcpdfPositionsService.kt @@ -10,7 +10,6 @@ package org.readium.r2.streamer.parser.readium import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.PdfSupport import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication @@ -22,18 +21,19 @@ import org.readium.r2.shared.util.pdf.cachedIn import timber.log.Timber /** - * Creates the [positions] for an LCP protected PDF [Publication] from its [readingOrder] and - * [fetcher]. + * Creates the [positions] for an LCP protected PDF [Publication] from its reading order and + * container. */ -@OptIn(PdfSupport::class, ExperimentalReadiumApi::class) +@OptIn(ExperimentalReadiumApi::class) internal class LcpdfPositionsService( private val pdfFactory: PdfDocumentFactory<*>, - private val context: Publication.Service.Context, + private val context: Publication.Service.Context ) : PositionsService { override suspend fun positionsByReadingOrder(): List> { - if (!::_positions.isInitialized) + if (!::_positions.isInitialized) { _positions = computePositions() + } return _positions } @@ -54,7 +54,12 @@ internal class LcpdfPositionsService( var lastPositionOfPreviousResource = 0 return resources.map { (pageCount, link) -> - val positions = createPositionsOf(link, pageCount = pageCount, totalPageCount = totalPageCount, startPosition = lastPositionOfPreviousResource) + val positions = createPositionsOf( + link, + pageCount = pageCount, + totalPageCount = totalPageCount, + startPosition = lastPositionOfPreviousResource + ) lastPositionOfPreviousResource += pageCount positions } @@ -76,7 +81,7 @@ internal class LcpdfPositionsService( val totalProgression = (startPosition + position - 1) / totalPageCount.toDouble() Locator( href = link.href, - type = link.type ?: MediaType.PDF.toString(), + type = (link.mediaType ?: MediaType.PDF).toString(), locations = Locator.Locations( fragments = listOf("page=$position"), progression = progression, @@ -91,7 +96,7 @@ internal class LcpdfPositionsService( try { pdfFactory .cachedIn(context.services) - .open(context.fetcher.get(link), password = null) + .open(context.container.get(link.href), password = null) } catch (e: Exception) { Timber.e(e) null diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt index fafde70595..0a2e8d9bd9 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt @@ -15,6 +15,7 @@ import org.readium.r2.shared.publication.services.* import org.readium.r2.shared.resource.readAsJson import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.shared.util.pdf.PdfDocumentFactory import org.readium.r2.streamer.parser.PublicationParser import org.readium.r2.streamer.parser.audio.AudioLocatorService @@ -25,22 +26,27 @@ import org.readium.r2.streamer.parser.audio.AudioLocatorService public class ReadiumWebPubParser( private val context: Context? = null, private val pdfFactory: PdfDocumentFactory<*>?, + private val mediaTypeRetriever: MediaTypeRetriever ) : PublicationParser { override suspend fun parse( asset: PublicationParser.Asset, warnings: WarningLogger? ): Try { - - if (!asset.mediaType.isReadiumWebPublication) + if (!asset.mediaType.isReadiumWebPublication) { return Try.failure(PublicationParser.Error.FormatNotSupported()) + } - val manifestJson = asset.fetcher + val manifestJson = asset.container .get("/manifest.json") .readAsJson() .getOrElse { return Try.failure(PublicationParser.Error.IO(it)) } - val manifest = Manifest.fromJSON(manifestJson, packaged = !asset.mediaType.isRwpm) + val manifest = Manifest.fromJSON( + manifestJson, + packaged = true, + mediaTypeRetriever = mediaTypeRetriever + ) ?: return Try.failure( PublicationParser.Error.ParsingFailed("Failed to parse the RWPM Manifest") ) @@ -49,7 +55,7 @@ public class ReadiumWebPubParser( // https://readium.org/lcp-specs/notes/lcp-for-pdf.html val readingOrder = manifest.readingOrder if (asset.mediaType == MediaType.LCP_PROTECTED_PDF && - (readingOrder.isEmpty() || !readingOrder.all { it.mediaType.matches(MediaType.PDF) }) + (readingOrder.isEmpty() || !readingOrder.all { MediaType.PDF.matches(it.mediaType) }) ) { return Try.failure(PublicationParser.Error.ParsingFailed("Invalid LCP Protected PDF.")) } @@ -69,13 +75,16 @@ public class ReadiumWebPubParser( } } - val publicationBuilder = Publication.Builder(manifest, asset.fetcher, servicesBuilder) + val publicationBuilder = Publication.Builder(manifest, asset.container, servicesBuilder) return Try.success(publicationBuilder) } } /** Returns whether this media type is of a Readium Web Publication profile. */ private val MediaType.isReadiumWebPublication: Boolean get() = matchesAny( - MediaType.READIUM_WEBPUB, MediaType.DIVINA, MediaType.LCP_PROTECTED_PDF, - MediaType.READIUM_AUDIOBOOK, MediaType.LCP_PROTECTED_AUDIOBOOK, + MediaType.READIUM_WEBPUB, + MediaType.DIVINA, + MediaType.LCP_PROTECTED_PDF, + MediaType.READIUM_AUDIOBOOK, + MediaType.LCP_PROTECTED_AUDIOBOOK ) diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/server/Resources.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/server/Resources.kt index 6eb6dd4887..545dd158f6 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/server/Resources.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/server/Resources.kt @@ -9,5 +9,8 @@ package org.readium.r2.streamer.server -@Deprecated("The HTTP server is not needed anymore (see migration guide)", level = DeprecationLevel.ERROR) +@Deprecated( + "The HTTP server is not needed anymore (see migration guide)", + level = DeprecationLevel.ERROR +) public class Resources diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/server/Server.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/server/Server.kt index 032ae2b666..2d507bd8ea 100755 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/server/Server.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/server/Server.kt @@ -13,7 +13,10 @@ import android.content.Context import org.nanohttpd.router.RouterNanoHTTPD @Suppress("Unused_parameter") -@Deprecated("The HTTP server is not needed anymore (see migration guide)", level = DeprecationLevel.ERROR) +@Deprecated( + "The HTTP server is not needed anymore (see migration guide)", + level = DeprecationLevel.ERROR +) public class Server( port: Int, context: Context, @@ -21,9 +24,12 @@ public class Server( ) @Suppress("Unused_parameter") -@Deprecated("The HTTP server is not needed anymore (see migration guide)", level = DeprecationLevel.ERROR) +@Deprecated( + "The HTTP server is not needed anymore (see migration guide)", + level = DeprecationLevel.ERROR +) public abstract class AbstractServer( port: Int, context: Context, - enableReadiumNavigatorSupport: Boolean = true, + enableReadiumNavigatorSupport: Boolean = true ) : RouterNanoHTTPD("127.0.0.1", port) diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt index 8b6aa48339..f7e1402222 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt @@ -10,11 +10,11 @@ package org.readium.r2.streamer import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.resource.Resource import org.readium.r2.streamer.parser.PublicationParser -internal fun Fetcher.Resource.readBlocking(range: LongRange? = null) = runBlocking { read(range) } +internal fun Resource.readBlocking(range: LongRange? = null) = runBlocking { read(range) } internal fun PublicationParser.parseBlocking(asset: PublicationParser.Asset): Publication.Builder? = runBlocking { parse(asset).getOrNull() } diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/extensions/ContainerEntryTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/extensions/ContainerEntryTest.kt new file mode 100644 index 0000000000..e79ec6c62a --- /dev/null +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/extensions/ContainerEntryTest.kt @@ -0,0 +1,73 @@ +/* + * Module: r2-streamer-kotlin + * Developers: Quentin Gliosca + * + * Copyright (c) 2020. Readium Foundation. All rights reserved. + * Use of this source code is governed by a BSD-style license which is detailed in the + * LICENSE file present in the project repository where this source code is maintained. + */ + +package org.readium.r2.streamer.extensions + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType + +class ContainerEntryTest { + + class Entry(override val path: String) : Container.Entry { + override val source: Url? = null + override suspend fun mediaType(): ResourceTry = + throw NotImplementedError() + override suspend fun properties(): ResourceTry = + throw NotImplementedError() + override suspend fun length(): ResourceTry = + throw NotImplementedError() + override suspend fun read(range: LongRange?): ResourceTry = + throw NotImplementedError() + override suspend fun close() { + throw NotImplementedError() + } + } + + @Test + fun `pathCommonFirstComponent is null when files are in the root`() { + assertNull( + listOf(Entry("/im1.jpg"), Entry("/im2.jpg"), Entry("/toc.xml")) + .pathCommonFirstComponent() + ) + } + + @Test + fun `pathCommonFirstComponent is null when files are in different directories`() { + assertNull( + listOf(Entry("/dir1/im1.jpg"), Entry("/dir2/im2.jpg"), Entry("/toc.xml")) + .pathCommonFirstComponent() + ) + } + + @Test + fun `pathCommonFirstComponent is correct when there is only one file in the root`() { + assertEquals( + "im1.jpg", + listOf(Entry("/im1.jpg")).pathCommonFirstComponent()?.name + ) + } + + @Test + fun `pathCommonFirstComponent is correct when all files are in the same directory`() { + assertEquals( + "root", + listOf( + Entry("/root/im1.jpg"), + Entry("/root/im2.jpg"), + Entry("/root/xml/toc.xml") + ).pathCommonFirstComponent()?.name + ) + } +} diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/extensions/LinkTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/extensions/LinkTest.kt deleted file mode 100644 index 747bb57bd8..0000000000 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/extensions/LinkTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Module: r2-streamer-kotlin - * Developers: Quentin Gliosca - * - * Copyright (c) 2020. Readium Foundation. All rights reserved. - * Use of this source code is governed by a BSD-style license which is detailed in the - * LICENSE file present in the project repository where this source code is maintained. - */ - -package org.readium.r2.streamer.extensions - -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNull -import org.junit.Test -import org.readium.r2.shared.publication.Link - -class LinkTest { - - @Test - fun `hrefCommonFirstComponent is null when files are in the root`() { - assertNull( - listOf(Link("/im1.jpg"), Link("/im2.jpg"), Link("/toc.xml")) - .hrefCommonFirstComponent() - ) - } - - @Test - fun `hrefCommonFirstComponent is null when files are in different directories`() { - assertNull( - listOf(Link("/dir1/im1.jpg"), Link("/dir2/im2.jpg"), Link("/toc.xml")) - .hrefCommonFirstComponent() - ) - } - - @Test - fun `hrefCommonFirstComponent is correct when there is only one file in the root`() { - assertEquals( - "im1.jpg", - listOf(Link("/im1.jpg")).hrefCommonFirstComponent()?.name - ) - } - - @Test - fun `hrefCommonFirstComponent is correct when all files are in the same directory`() { - assertEquals( - "root", - listOf( - Link("/root/im1.jpg"), - Link("/root/im2.jpg"), - Link("/root/xml/toc.xml") - ).hrefCommonFirstComponent()?.name - ) - } -} diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/audio/AudioLocatorServiceTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/audio/AudioLocatorServiceTest.kt index cc085ab295..7ee8959eb3 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/audio/AudioLocatorServiceTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/audio/AudioLocatorServiceTest.kt @@ -12,6 +12,7 @@ import org.junit.Assert.assertNull import org.junit.Test import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.util.mediatype.MediaType class AudioLocatorServiceTest { @@ -24,7 +25,11 @@ class AudioLocatorServiceTest { ) ) - val locator = Locator("l1", type = "audio/mpeg", locations = Locator.Locations(totalProgression = 0.53)) + val locator = Locator( + "l1", + type = "audio/mpeg", + locations = Locator.Locations(totalProgression = 0.53) + ) assertEquals(locator, service.locate(locator)) } @@ -37,7 +42,11 @@ class AudioLocatorServiceTest { ) ) - val locator = Locator("l3", type = "audio/mpeg", locations = Locator.Locations(totalProgression = 0.53)) + val locator = Locator( + "l3", + type = "audio/mpeg", + locations = Locator.Locations(totalProgression = 0.53) + ) assertNull(service.locate(locator)) } @@ -45,45 +54,66 @@ class AudioLocatorServiceTest { fun `locate(Locator) uses totalProgression`() = runBlocking { val service = AudioLocatorService( listOf( - Link("l1", type = "audio/mpeg", duration = 100.0), - Link("l2", type = "audio/mpeg", duration = 100.0) + Link("l1", mediaType = MediaType.MP3, duration = 100.0), + Link("l2", mediaType = MediaType.MP3, duration = 100.0) ) ) assertEquals( Locator( - "l1", type = "audio/mpeg", + "l1", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=98"), progression = 98 / 100.0, totalProgression = 0.49 ) ), - service.locate(Locator("wrong", type = "audio/mpeg", locations = Locator.Locations(totalProgression = 0.49))) + service.locate( + Locator( + "wrong", + type = "audio/mpeg", + locations = Locator.Locations(totalProgression = 0.49) + ) + ) ) assertEquals( Locator( - "l2", type = "audio/mpeg", + "l2", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=0"), progression = 0.0, totalProgression = 0.5 ) ), - service.locate(Locator("wrong", type = "audio/mpeg", locations = Locator.Locations(totalProgression = 0.5))) + service.locate( + Locator( + "wrong", + type = "audio/mpeg", + locations = Locator.Locations(totalProgression = 0.5) + ) + ) ) assertEquals( Locator( - "l2", type = "audio/mpeg", + "l2", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=2"), progression = 0.02, totalProgression = 0.51 ) ), - service.locate(Locator("wrong", type = "audio/mpeg", locations = Locator.Locations(totalProgression = 0.51))) + service.locate( + Locator( + "wrong", + type = "audio/mpeg", + locations = Locator.Locations(totalProgression = 0.51) + ) + ) ) } @@ -91,8 +121,8 @@ class AudioLocatorServiceTest { fun `locate(Locator) using totalProgression keeps title and text`() = runBlocking { val service = AudioLocatorService( listOf( - Link("l1", type = "audio/mpeg", duration = 100.0), - Link("l2", type = "audio/mpeg", duration = 100.0) + Link("l1", mediaType = MediaType.MP3, duration = 100.0), + Link("l2", mediaType = MediaType.MP3, duration = 100.0) ) ) @@ -130,14 +160,15 @@ class AudioLocatorServiceTest { fun `locate progression`() = runBlocking { val service = AudioLocatorService( listOf( - Link("l1", type = "audio/mpeg", duration = 100.0), - Link("l2", type = "audio/mpeg", duration = 100.0) + Link("l1", mediaType = MediaType.MP3, duration = 100.0), + Link("l2", mediaType = MediaType.MP3, duration = 100.0) ) ) assertEquals( Locator( - "l1", type = "audio/mpeg", + "l1", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=0"), progression = 0.0, @@ -149,7 +180,8 @@ class AudioLocatorServiceTest { assertEquals( Locator( - "l1", type = "audio/mpeg", + "l1", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=98"), progression = 98 / 100.0, @@ -161,7 +193,8 @@ class AudioLocatorServiceTest { assertEquals( Locator( - "l2", type = "audio/mpeg", + "l2", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=0"), progression = 0.0, @@ -173,7 +206,8 @@ class AudioLocatorServiceTest { assertEquals( Locator( - "l2", type = "audio/mpeg", + "l2", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=2"), progression = 0.02, @@ -185,7 +219,8 @@ class AudioLocatorServiceTest { assertEquals( Locator( - "l2", type = "audio/mpeg", + "l2", + type = "audio/mpeg", locations = Locator.Locations( fragments = listOf("t=100"), progression = 1.0, @@ -200,8 +235,8 @@ class AudioLocatorServiceTest { fun `locate invalid progression`() = runBlocking { val service = AudioLocatorService( listOf( - Link("l1", type = "audio/mpeg", duration = 100.0), - Link("l2", type = "audio/mpeg", duration = 100.0) + Link("l1", mediaType = MediaType.MP3, duration = 100.0), + Link("l2", mediaType = MediaType.MP3, duration = 100.0) ) ) diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EncryptionParserTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EncryptionParserTest.kt index 4d75a0059a..9838c14515 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EncryptionParserTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EncryptionParserTest.kt @@ -50,12 +50,18 @@ class EncryptionParserTest { @Test fun `Check EncryptionParser with namespace prefixes`() { - assertThat(parseEncryption("encryption/encryption-lcp-prefixes.xml")).contains(lcpChap1, lcpChap2) + assertThat(parseEncryption("encryption/encryption-lcp-prefixes.xml")).contains( + lcpChap1, + lcpChap2 + ) } @Test fun `Check EncryptionParser with default namespaces`() { - assertThat(parseEncryption("encryption/encryption-lcp-xmlns.xml")).contains(lcpChap1, lcpChap2) + assertThat(parseEncryption("encryption/encryption-lcp-xmlns.xml")).contains( + lcpChap1, + lcpChap2 + ) } @Test diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt index 6416c24887..21e01ef65b 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt @@ -9,19 +9,16 @@ package org.readium.r2.streamer.parser.epub -import java.io.File import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat -import org.junit.Assert.assertNotNull import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.error.getOrThrow -import org.readium.r2.shared.extensions.toMap -import org.readium.r2.shared.fetcher.Fetcher -import org.readium.r2.shared.fetcher.FileFetcher -import org.readium.r2.shared.publication.Link -import org.readium.r2.shared.publication.Properties import org.readium.r2.shared.publication.encryption.Encryption +import org.readium.r2.shared.resource.DirectoryContainerFactory +import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.resource.flatMap +import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.streamer.readBlocking import org.robolectric.RobolectricTestRunner @@ -30,46 +27,43 @@ import org.robolectric.RobolectricTestRunner class EpubDeobfuscatorTest { private val identifier = "urn:uuid:36d5078e-ff7d-468e-a5f3-f47c14b91f2f" - private val transformer = EpubDeobfuscator(identifier) - private val fetcher: Fetcher - private val font: ByteArray - init { - val deobfuscationDir = EpubDeobfuscatorTest::class.java - .getResource("deobfuscation/cut-cut.woff") - ?.path - ?.let { File(it).parentFile } - assertNotNull(deobfuscationDir) - fetcher = FileFetcher("/deobfuscation", deobfuscationDir!!, MediaTypeRetriever()) + private val deobfuscationDir = requireNotNull( + EpubDeobfuscatorTest::class.java + .getResource("deobfuscation") + ?.let { Url(it) } + ) - val fontResult = fetcher.get(Link(href = "/deobfuscation/cut-cut.woff")).readBlocking() - assert(fontResult.isSuccess) - font = fontResult.getOrThrow() + private val container = runBlocking { + requireNotNull( + DirectoryContainerFactory(MediaTypeRetriever()).create(deobfuscationDir).getOrNull() + ) } - private fun deobfuscate(href: String, algorithm: String?): Fetcher.Resource { - val encryption = algorithm?.let { - Encryption( - algorithm = algorithm - ).toJSON().toMap() + private val font = requireNotNull( + container.get("/cut-cut.woff").readBlocking().getOrNull() + ) + + private fun deobfuscate(path: String, algorithm: String?): Resource { + val resource = container.get(path) + + val deobfuscator = EpubDeobfuscator(identifier) { + if (resource.source == it) { + algorithm?.let { + Encryption(algorithm = algorithm) + } + } else { + null + } } - val properties = encryption?.let { - mapOf("encrypted" to it) - }.orEmpty() - val obfuscatedRes = fetcher.get( - Link( - href = href, - properties = Properties(properties) - ) - ) - return transformer.transform(obfuscatedRes) + return resource.flatMap(deobfuscator::transform) } @Test fun testIdpfDeobfuscation() { val deobfuscatedRes = deobfuscate( - "/deobfuscation/cut-cut.obf.woff", + "/cut-cut.obf.woff", "http://www.idpf.org/2008/embedding" ).readBlocking().getOrNull() assertThat(deobfuscatedRes).isEqualTo(font) @@ -79,7 +73,7 @@ class EpubDeobfuscatorTest { fun testIdpfDeobfuscationWithRange() { runBlocking { val deobfuscatedRes = deobfuscate( - "/deobfuscation/cut-cut.obf.woff", + "/cut-cut.obf.woff", "http://www.idpf.org/2008/embedding" ).read(20L until 40L).getOrThrow() assertThat(deobfuscatedRes).isEqualTo(font.copyOfRange(20, 40)) @@ -89,7 +83,7 @@ class EpubDeobfuscatorTest { @Test fun testAdobeDeobfuscation() { val deobfuscatedRes = deobfuscate( - "/deobfuscation/cut-cut.adb.woff", + "/cut-cut.adb.woff", "http://ns.adobe.com/pdf/enc#RC" ).readBlocking().getOrNull() assertThat(deobfuscatedRes).isEqualTo(font) @@ -98,7 +92,7 @@ class EpubDeobfuscatorTest { @Test fun `a resource is passed through when the link doesn't contain encryption data`() { val deobfuscatedRes = deobfuscate( - "/deobfuscation/cut-cut.woff", + "/cut-cut.woff", null ).readBlocking().getOrNull() assertThat(deobfuscatedRes).isEqualTo(font) @@ -107,7 +101,7 @@ class EpubDeobfuscatorTest { @Test fun `a resource is passed through when the algorithm is unknown`() { val deobfuscatedRes = deobfuscate( - "/deobfuscation/cut-cut.woff", + "/cut-cut.woff", "unknown algorithm" ).readBlocking().getOrNull() assertThat(deobfuscatedRes).isEqualTo(font) diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt index d928e62ac9..4aeace0d2c 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt @@ -14,14 +14,18 @@ import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith import org.readium.r2.shared.error.Try -import org.readium.r2.shared.fetcher.Fetcher import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Properties import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.publication.presentation.Presentation +import org.readium.r2.shared.resource.ArchiveProperties +import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.resource.archive +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -38,7 +42,7 @@ class EpubPositionsServiceTest { fun `Positions from a {readingOrder} with one resource`() { val service = createService( readingOrder = listOf( - Pair(1L, Link(href = "res", type = "application/xml")) + ReadingOrderItem(href = "res", length = 1, type = MediaType.XML) ) ) @@ -62,9 +66,9 @@ class EpubPositionsServiceTest { fun `Positions from a {readingOrder} with a few resources`() { val service = createService( readingOrder = listOf( - Pair(1L, Link(href = "res")), - Pair(2L, Link(href = "chap1", type = "application/xml")), - Pair(2L, Link(href = "chap2", type = "text/html", title = "Chapter 2")) + ReadingOrderItem("res", length = 1), + ReadingOrderItem("chap1", length = 2, MediaType.XML), + ReadingOrderItem("chap2", length = 2, MediaType.HTML, title = "Chapter 2") ) ) @@ -107,8 +111,8 @@ class EpubPositionsServiceTest { fun `{type} fallbacks on text-html`() { val service = createService( readingOrder = listOf( - Pair(1L, Link(href = "chap1", properties = createProperties(layout = EpubLayout.REFLOWABLE))), - Pair(1L, Link(href = "chap2", properties = createProperties(layout = EpubLayout.FIXED))) + ReadingOrderItem("chap1", length = 1, layout = EpubLayout.REFLOWABLE), + ReadingOrderItem("chap2", length = 1, layout = EpubLayout.FIXED) ) ) @@ -142,9 +146,9 @@ class EpubPositionsServiceTest { val service = createService( layout = EpubLayout.FIXED, readingOrder = listOf( - Pair(10000L, Link(href = "res")), - Pair(20000L, Link(href = "chap1", type = "application/xml")), - Pair(40000L, Link(href = "chap2", type = "text/html", title = "Chapter 2")) + ReadingOrderItem("res", length = 10000), + ReadingOrderItem("chap1", length = 20000, MediaType.XML), + ReadingOrderItem("chap2", length = 40000, MediaType.HTML, title = "Chapter 2") ) ) @@ -188,13 +192,15 @@ class EpubPositionsServiceTest { val service = createService( layout = EpubLayout.REFLOWABLE, readingOrder = listOf( - Pair(0L, Link(href = "chap1")), - Pair(49L, Link(href = "chap2", type = "application/xml")), - Pair(50L, Link(href = "chap3", type = "text/html", title = "Chapter 3")), - Pair(51L, Link(href = "chap4")), - Pair(120L, Link(href = "chap5")) + ReadingOrderItem("chap1", length = 0), + ReadingOrderItem("chap2", length = 49, MediaType.XML), + ReadingOrderItem("chap3", length = 50, MediaType.HTML, title = "Chapter 3"), + ReadingOrderItem("chap4", length = 51), + ReadingOrderItem("chap5", length = 120) ), - reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength(pageLength = 50) + reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength( + pageLength = 50 + ) ) assertEquals( @@ -283,9 +289,11 @@ class EpubPositionsServiceTest { val service = createService( layout = null, readingOrder = listOf( - Pair(60L, Link(href = "chap1")) + ReadingOrderItem("chap1", length = 60) ), - reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength(pageLength = 50) + reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength( + pageLength = 50 + ) ) assertEquals( @@ -318,11 +326,13 @@ class EpubPositionsServiceTest { val service = createService( layout = EpubLayout.FIXED, readingOrder = listOf( - Pair(20000L, Link(href = "chap1")), - Pair(60L, Link(href = "chap2", properties = createProperties(layout = EpubLayout.REFLOWABLE))), - Pair(20000L, Link(href = "chap3", properties = createProperties(layout = EpubLayout.FIXED))) + ReadingOrderItem("chap1", length = 20000), + ReadingOrderItem("chap2", length = 60, layout = EpubLayout.REFLOWABLE), + ReadingOrderItem("chap3", length = 20000, layout = EpubLayout.FIXED) ), - reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength(pageLength = 50) + reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength( + pageLength = 50 + ) ) assertEquals( @@ -373,10 +383,12 @@ class EpubPositionsServiceTest { val service = createService( layout = EpubLayout.REFLOWABLE, readingOrder = listOf( - Pair(60L, Link(href = "chap1", properties = createProperties(archiveEntryLength = 20L))), - Pair(60L, Link(href = "chap2")) + ReadingOrderItem("chap1", length = 60, archiveEntryLength = 20L), + ReadingOrderItem("chap2", length = 60) ), - reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength(pageLength = 50) + reflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength( + pageLength = 50 + ) ) assertEquals( @@ -390,7 +402,7 @@ class EpubPositionsServiceTest { position = 1, totalProgression = 0.0 ) - ), + ) ), listOf( Locator( @@ -422,10 +434,12 @@ class EpubPositionsServiceTest { val service = createService( layout = EpubLayout.REFLOWABLE, readingOrder = listOf( - Pair(60L, Link(href = "chap1", properties = createProperties(originalLength = 20L))), - Pair(60L, Link(href = "chap2")) + ReadingOrderItem("chap1", length = 60, originalLength = 20L), + ReadingOrderItem("chap2", length = 60) ), - reflowableStrategy = EpubPositionsService.ReflowableStrategy.OriginalLength(pageLength = 50) + reflowableStrategy = EpubPositionsService.ReflowableStrategy.OriginalLength( + pageLength = 50 + ) ) assertEquals( @@ -464,27 +478,40 @@ class EpubPositionsServiceTest { private fun createService( layout: EpubLayout? = null, - readingOrder: List>, - reflowableStrategy: EpubPositionsService.ReflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength(pageLength = 50) + readingOrder: List, + reflowableStrategy: EpubPositionsService.ReflowableStrategy = EpubPositionsService.ReflowableStrategy.ArchiveEntryLength( + pageLength = 50 + ) ) = EpubPositionsService( - readingOrder = readingOrder.map { it.second }, - fetcher = object : Fetcher { + readingOrder = readingOrder.map { it.link }, + container = object : Container { + + private fun find(relativePath: String): ReadingOrderItem? = + readingOrder.find { it.link.href == relativePath } + + override suspend fun entries(): Set? = null + + override fun get(path: String): Container.Entry { + val item = requireNotNull(find(path)) - private fun findResource(relativePath: String): Pair? = - readingOrder.find { it.second.href == relativePath } + return object : Container.Entry { + override val path: String = path - override suspend fun links(): List = emptyList() + override val source: Url? = null - override fun get(link: Link): Fetcher.Resource = object : Fetcher.Resource { - override suspend fun link(): Link = link + override suspend fun mediaType(): ResourceTry = + Try.success(item.link.mediaType ?: MediaType.BINARY) - override suspend fun length() = findResource(link.href) - ?.let { Try.success(it.first) } - ?: Try.failure(Resource.Exception.NotFound()) + override suspend fun properties(): ResourceTry = + Try.success(item.resourceProperties) - override suspend fun read(range: LongRange?): ResourceTry = Try.success(ByteArray(0)) + override suspend fun length() = Try.success(item.length) - override suspend fun close() {} + override suspend fun read(range: LongRange?): ResourceTry = + Try.success(ByteArray(0)) + + override suspend fun close() {} + } } override suspend fun close() {} @@ -493,27 +520,44 @@ class EpubPositionsServiceTest { reflowableStrategy = reflowableStrategy ) - private fun createProperties( - layout: EpubLayout? = null, - archiveEntryLength: Long? = null, - originalLength: Long? = null - ): Properties { - val properties = mutableMapOf() - if (layout != null) { - properties["layout"] = layout.value - } - if (originalLength != null) { - properties["encrypted"] = mapOf( - "algorithm" to "algo", - "originalLength" to originalLength - ) - } - if (archiveEntryLength != null) { - properties["archive"] = mapOf( - "entryLength" to archiveEntryLength, - "isEntryCompressed" to true + class ReadingOrderItem( + val href: String, + val length: Long, + val type: MediaType? = null, + val title: String? = null, + val archiveEntryLength: Long? = null, + val originalLength: Long? = null, + val layout: EpubLayout? = null + ) { + val link: Link = Link( + href = href, + mediaType = type, + title = title, + properties = Properties( + buildMap { + if (layout != null) { + put("layout", layout.value) + } + if (originalLength != null) { + put( + "encrypted", + mapOf( + "algorithm" to "algo", + "originalLength" to originalLength + ) + ) + } + } ) + ) + + val resourceProperties: Resource.Properties = Resource.Properties { + if (archiveEntryLength != null) { + archive = ArchiveProperties( + entryLength = archiveEntryLength, + isEntryCompressed = true + ) + } } - return Properties(otherProperties = properties) } } diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/MetadataTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/MetadataTest.kt index 2f18533cf5..280af498dd 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/MetadataTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/MetadataTest.kt @@ -20,6 +20,7 @@ import org.readium.r2.shared.publication.Link as SharedLink import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.publication.presentation.Presentation import org.readium.r2.shared.publication.presentation.presentation +import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -50,7 +51,10 @@ class ContributorParsingTest { @Test fun `Unknown roles are ignored`() { - val contributor = Contributor(localizedName = LocalizedString("Contributor 2"), roles = setOf("unknown")) + val contributor = Contributor( + localizedName = LocalizedString("Contributor 2"), + roles = setOf("unknown") + ) assertThat(epub2Metadata.contributors).contains(contributor) assertThat(epub3Metadata.contributors).contains(contributor) } @@ -224,7 +228,9 @@ class TitleTest { @Test fun `The selected subtitle has the lowest display-seq property (epub3 only)`() { val metadata = parsePackageDocument("package/title-multiple-subtitles.opf").metadata - assertThat(metadata.localizedSubtitle).isEqualTo(LocalizedString.fromStrings(mapOf(null to "Subtitle 2"))) + assertThat(metadata.localizedSubtitle).isEqualTo( + LocalizedString.fromStrings(mapOf(null to "Subtitle 2")) + ) } } @@ -333,7 +339,7 @@ class MetadataMiscTest { fun `Cover link is rightly identified`() { val expected = SharedLink( href = "/OEBPS/cover.jpg", - type = "image/jpeg", + mediaType = MediaType.JPEG, rels = setOf("cover") ) assertThat(parsePackageDocument("package/cover-epub2.opf").resources.firstWithRel("cover")) @@ -416,7 +422,10 @@ class CollectionTest { @Test fun `Series with position are rightly computed`() { val expected = - Collection(localizedName = LocalizedString.fromStrings(mapOf("en" to "Series B")), position = 1.5) + Collection( + localizedName = LocalizedString.fromStrings(mapOf("en" to "Series B")), + position = 1.5 + ) assertThat(epub2Metadata.belongsToSeries).contains(expected) assertThat(epub3Metadata.belongsToSeries).contains(expected) } @@ -434,8 +443,12 @@ class AccessibilityTest { } @Test fun `conformsTo contains WCAG profiles and only them`() { - assertThat(epub2Metadata.accessibility?.conformsTo).containsExactlyInAnyOrder(Accessibility.Profile.EPUB_A11Y_10_WCAG_20_A) - assertThat(epub3Metadata.accessibility?.conformsTo).containsExactlyInAnyOrder(Accessibility.Profile.EPUB_A11Y_10_WCAG_20_A) + assertThat(epub2Metadata.accessibility?.conformsTo).containsExactlyInAnyOrder( + Accessibility.Profile.EPUB_A11Y_10_WCAG_20_A + ) + assertThat(epub3Metadata.accessibility?.conformsTo).containsExactlyInAnyOrder( + Accessibility.Profile.EPUB_A11Y_10_WCAG_20_A + ) } @Test fun `certification is rightly parsed`() { @@ -450,32 +463,53 @@ class AccessibilityTest { @Test fun `features are rightly parsed`() { assertThat(epub2Metadata.accessibility?.features) - .containsExactlyInAnyOrder(Accessibility.Feature.ALTERNATIVE_TEXT, Accessibility.Feature.STRUCTURAL_NAVIGATION) + .containsExactlyInAnyOrder( + Accessibility.Feature.ALTERNATIVE_TEXT, + Accessibility.Feature.STRUCTURAL_NAVIGATION + ) } @Test fun `hazards are rightly parsed`() { assertThat(epub2Metadata.accessibility?.hazards) - .containsExactlyInAnyOrder(Accessibility.Hazard.MOTION_SIMULATION, Accessibility.Hazard.NO_SOUND_HAZARD) + .containsExactlyInAnyOrder( + Accessibility.Hazard.MOTION_SIMULATION, + Accessibility.Hazard.NO_SOUND_HAZARD + ) assertThat(epub3Metadata.accessibility?.hazards) - .containsExactlyInAnyOrder(Accessibility.Hazard.MOTION_SIMULATION, Accessibility.Hazard.NO_SOUND_HAZARD) + .containsExactlyInAnyOrder( + Accessibility.Hazard.MOTION_SIMULATION, + Accessibility.Hazard.NO_SOUND_HAZARD + ) } @Test fun `accessModes are rightly parsed`() { assertThat(epub2Metadata.accessibility?.accessModes) - .containsExactlyInAnyOrder(Accessibility.AccessMode.VISUAL, Accessibility.AccessMode.TEXTUAL) + .containsExactlyInAnyOrder( + Accessibility.AccessMode.VISUAL, + Accessibility.AccessMode.TEXTUAL + ) assertThat(epub3Metadata.accessibility?.accessModes) - .containsExactlyInAnyOrder(Accessibility.AccessMode.VISUAL, Accessibility.AccessMode.TEXTUAL) + .containsExactlyInAnyOrder( + Accessibility.AccessMode.VISUAL, + Accessibility.AccessMode.TEXTUAL + ) } @Test fun `accessModesSufficient are rightly parsed`() { assertThat(epub2Metadata.accessibility?.accessModesSufficient) .containsExactlyInAnyOrder( - setOf(Accessibility.PrimaryAccessMode.VISUAL, Accessibility.PrimaryAccessMode.TEXTUAL), + setOf( + Accessibility.PrimaryAccessMode.VISUAL, + Accessibility.PrimaryAccessMode.TEXTUAL + ), setOf(Accessibility.PrimaryAccessMode.TEXTUAL) ) assertThat(epub3Metadata.accessibility?.accessModesSufficient) .containsExactlyInAnyOrder( - setOf(Accessibility.PrimaryAccessMode.VISUAL, Accessibility.PrimaryAccessMode.TEXTUAL), + setOf( + Accessibility.PrimaryAccessMode.VISUAL, + Accessibility.PrimaryAccessMode.TEXTUAL + ), setOf(Accessibility.PrimaryAccessMode.TEXTUAL) ) } diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParserTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParserTest.kt index 78abbc2bd5..05e5acfdbd 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParserTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NavigationDocumentParserTest.kt @@ -44,7 +44,10 @@ class NavigationDocumentParserTest { @Test fun `Newlines are trimmed from title`() { assertThat(navTitles["toc"]).contains( - Link(title = "A link with new lines splitting the text", href = "/OEBPS/xhtml/chapter1.xhtml") + Link( + title = "A link with new lines splitting the text", + href = "/OEBPS/xhtml/chapter1.xhtml" + ) ) } @@ -81,14 +84,16 @@ class NavigationDocumentParserTest { assertThat(navChildren["toc"]).containsExactly( Link(title = "Introduction", href = "/OEBPS/xhtml/introduction.xhtml"), Link( - title = "Part I", href = "#", + title = "Part I", + href = "#", children = listOf( Link(title = "Chapter 1", href = "/OEBPS/xhtml/part1/chapter1.xhtml"), Link(title = "Chapter 2", href = "/OEBPS/xhtml/part1/chapter2.xhtml") ) ), Link( - title = "Part II", href = "/OEBPS/xhtml/part2/chapter1.xhtml", + title = "Part II", + href = "/OEBPS/xhtml/part2/chapter1.xhtml", children = listOf( Link(title = "Chapter 1", href = "/OEBPS/xhtml/part2/chapter1.xhtml"), Link(title = "Chapter 2", href = "/OEBPS/xhtml/part2/chapter2.xhtml") diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NcxParserTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NcxParserTest.kt index 25ae8c8fef..d9b5043490 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NcxParserTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/NcxParserTest.kt @@ -36,7 +36,10 @@ class NcxParserTest { @Test fun `Newlines are trimmed from title`() { Assertions.assertThat(ncxTitles["toc"]).contains( - Link(title = "A link with new lines splitting the text", href = "/OEBPS/xhtml/chapter1.xhtml") + Link( + title = "A link with new lines splitting the text", + href = "/OEBPS/xhtml/chapter1.xhtml" + ) ) } @@ -66,14 +69,16 @@ class NcxParserTest { Assertions.assertThat(ncxChildren["toc"]).containsExactly( Link(title = "Introduction", href = "/OEBPS/xhtml/introduction.xhtml"), Link( - title = "Part I", href = "#", + title = "Part I", + href = "#", children = listOf( Link(title = "Chapter 1", href = "/OEBPS/xhtml/part1/chapter1.xhtml"), Link(title = "Chapter 2", href = "/OEBPS/xhtml/part1/chapter2.xhtml") ) ), Link( - title = "Part II", href = "/OEBPS/xhtml/part2/chapter1.xhtml", + title = "Part II", + href = "/OEBPS/xhtml/part2/chapter1.xhtml", children = listOf( Link(title = "Chapter 1", href = "/OEBPS/xhtml/part2/chapter1.xhtml"), Link(title = "Chapter 2", href = "/OEBPS/xhtml/part2/chapter2.xhtml") diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt index 15d36b1fb0..fab0bd2b85 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PackageDocumentTest.kt @@ -20,13 +20,15 @@ import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.publication.epub.contains import org.readium.r2.shared.publication.epub.layout import org.readium.r2.shared.publication.presentation.* +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.robolectric.RobolectricTestRunner fun parsePackageDocument(path: String): Manifest { val pub = PackageDocument::class.java.getResourceAsStream(path) ?.let { XmlParser().parse(it) } - ?.let { PackageDocument.parse(it, "OEBPS/content.opf") } - ?.let { ManifestAdapter("fallback title", it) } + ?.let { PackageDocument.parse(it, "OEBPS/content.opf", MediaTypeRetriever()) } + ?.let { ManifestAdapter(it, mediaTypeRetriever = MediaTypeRetriever()) } ?.adapt() checkNotNull(pub) return pub @@ -44,7 +46,9 @@ class ReadingProgressionTest { @Test fun `Default page progression direction is rightly parsed`() { - assertThat(parsePackageDocument("package/progression-default.opf").metadata.readingProgression) + assertThat( + parsePackageDocument("package/progression-default.opf").metadata.readingProgression + ) .isEqualTo(null) } @@ -69,7 +73,9 @@ class LinkPropertyTest { fun `contains is rightly filled`() { with(propertiesPub) { assertThat(readingOrder[0].properties.contains).containsExactlyInAnyOrder("mathml") - assertThat(readingOrder[1].properties.contains).containsExactlyInAnyOrder("remote-resources") + assertThat(readingOrder[1].properties.contains).containsExactlyInAnyOrder( + "remote-resources" + ) assertThat(readingOrder[2].properties.contains).containsExactlyInAnyOrder("js", "svg") assertThat(readingOrder[3].properties.contains).isEmpty() assertThat(readingOrder[4].properties.contains).isEmpty() @@ -93,24 +99,36 @@ class LinkPropertyTest { with(propertiesPub) { assertThat(readingOrder[0].properties.layout).isEqualTo(EpubLayout.FIXED) assertThat(readingOrder[0].properties.overflow).isEqualTo(Presentation.Overflow.AUTO) - assertThat(readingOrder[0].properties.orientation).isEqualTo(Presentation.Orientation.AUTO) + assertThat(readingOrder[0].properties.orientation).isEqualTo( + Presentation.Orientation.AUTO + ) assertThat(readingOrder[0].properties.page).isEqualTo(Presentation.Page.RIGHT) assertThat(readingOrder[0].properties.spread).isNull() assertThat(readingOrder[1].properties.layout).isEqualTo(EpubLayout.REFLOWABLE) - assertThat(readingOrder[1].properties.overflow).isEqualTo(Presentation.Overflow.PAGINATED) - assertThat(readingOrder[1].properties.orientation).isEqualTo(Presentation.Orientation.LANDSCAPE) + assertThat(readingOrder[1].properties.overflow).isEqualTo( + Presentation.Overflow.PAGINATED + ) + assertThat(readingOrder[1].properties.orientation).isEqualTo( + Presentation.Orientation.LANDSCAPE + ) assertThat(readingOrder[1].properties.page).isEqualTo(Presentation.Page.LEFT) assertThat(readingOrder[0].properties.spread).isNull() assertThat(readingOrder[2].properties.layout).isNull() - assertThat(readingOrder[2].properties.overflow).isEqualTo(Presentation.Overflow.SCROLLED) - assertThat(readingOrder[2].properties.orientation).isEqualTo(Presentation.Orientation.PORTRAIT) + assertThat(readingOrder[2].properties.overflow).isEqualTo( + Presentation.Overflow.SCROLLED + ) + assertThat(readingOrder[2].properties.orientation).isEqualTo( + Presentation.Orientation.PORTRAIT + ) assertThat(readingOrder[2].properties.page).isEqualTo(Presentation.Page.CENTER) assertThat(readingOrder[2].properties.spread).isNull() assertThat(readingOrder[3].properties.layout).isNull() - assertThat(readingOrder[3].properties.overflow).isEqualTo(Presentation.Overflow.SCROLLED) + assertThat(readingOrder[3].properties.overflow).isEqualTo( + Presentation.Overflow.SCROLLED + ) assertThat(readingOrder[3].properties.orientation).isNull() assertThat(readingOrder[3].properties.page).isNull() assertThat(readingOrder[3].properties.spread).isEqualTo(Presentation.Spread.AUTO) @@ -127,11 +145,11 @@ class LinkTest { assertThat(resourcesPub.readingOrder).containsExactly( Link( href = "/titlepage.xhtml", - type = "application/xhtml+xml" + mediaType = MediaType.XHTML ), Link( href = "/OEBPS/chapter01.xhtml", - type = "application/xhtml+xml" + mediaType = MediaType.XHTML ) ) } @@ -141,38 +159,38 @@ class LinkTest { assertThat(resourcesPub.resources).containsExactlyInAnyOrder( Link( href = "/OEBPS/fonts/MinionPro.otf", - type = "application/vnd.ms-opentype" + mediaType = MediaType("application/vnd.ms-opentype")!! ), Link( href = "/OEBPS/nav.xhtml", - type = "application/xhtml+xml", + mediaType = MediaType.XHTML, rels = setOf("contents") ), Link( href = "/style.css", - type = "text/css" + mediaType = MediaType.CSS ), Link( href = "/OEBPS/chapter01.smil", - type = "application/smil+xml" + mediaType = MediaType.SMIL ), Link( href = "/OEBPS/chapter02.smil", - type = "application/smil+xml", + mediaType = MediaType.SMIL, duration = 1949.0 ), Link( href = "/OEBPS/images/alice01a.png", - type = "image/png", + mediaType = MediaType.PNG, rels = setOf("cover") ), Link( href = "/OEBPS/images/alice02a.gif", - type = "image/gif" + mediaType = MediaType.GIF ), Link( href = "/OEBPS/chapter02.xhtml", - type = "application/xhtml+xml" + mediaType = MediaType.XHTML ), Link( href = "/OEBPS/nomediatype.txt" @@ -187,15 +205,15 @@ class LinkMiscTest { assertThat(parsePackageDocument("package/fallbacks.opf")).isEqualTo( Link( href = "/OEBPS/chap1_docbook.xml", - type = "application/docbook+xml", + mediaType = MediaType("application/docbook+xml")!!, alternates = listOf( Link( href = "/OEBPS/chap1.xml", - type = "application/z3998-auth+xml", + mediaType = MediaType("application/z3998-auth+xml")!!, alternates = listOf( Link( href = "/OEBPS/chap1.xhtml", - type = "application/xhtml+xml" + mediaType = MediaType.XHTML ) ) ) diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PropertyDataTypeTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PropertyDataTypeTest.kt index 8adcb94072..86f90ce72d 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PropertyDataTypeTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/PropertyDataTypeTest.kt @@ -25,7 +25,9 @@ class ParsePrefixesTest { @Test fun `Space between prefixes and iris can be ommited`() { - val prefixes = parsePrefixes("foaf: http://xmlns.com/foaf/spec/ dbp:http://dbpedia.org/ontology/") + val prefixes = parsePrefixes( + "foaf: http://xmlns.com/foaf/spec/ dbp:http://dbpedia.org/ontology/" + ) assertThat(prefixes).contains( entry("foaf", "http://xmlns.com/foaf/spec/"), entry("dbp", "http://dbpedia.org/ontology/") @@ -35,7 +37,9 @@ class ParsePrefixesTest { @Test fun `Multiple prefixes are rightly parsed`() { - val prefixes = parsePrefixes("foaf: http://xmlns.com/foaf/spec/ dbp: http://dbpedia.org/ontology/") + val prefixes = parsePrefixes( + "foaf: http://xmlns.com/foaf/spec/ dbp: http://dbpedia.org/ontology/" + ) assertThat(prefixes).contains( entry("foaf", "http://xmlns.com/foaf/spec/"), entry("dbp", "http://dbpedia.org/ontology/") diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt index b857f37b85..3e200d4544 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/image/ImageParserTest.kt @@ -15,18 +15,19 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Test -import org.readium.r2.shared.fetcher.ContainerFetcher -import org.readium.r2.shared.fetcher.ResourceFetcher -import org.readium.r2.shared.publication.Link +import org.junit.runner.RunWith import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.firstWithRel import org.readium.r2.shared.resource.DefaultArchiveFactory import org.readium.r2.shared.resource.FileResource +import org.readium.r2.shared.resource.ResourceContainer import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.streamer.parseBlocking import org.readium.r2.streamer.parser.PublicationParser +import org.robolectric.RobolectricTestRunner +@RunWith(RobolectricTestRunner::class) class ImageParserTest { private val parser = ImageParser() @@ -34,19 +35,21 @@ class ImageParserTest { private val cbzAsset = runBlocking { val path = pathForResource("futuristic_tales.cbz") val file = File(path) - val resource = FileResource(file) - val archive = DefaultArchiveFactory().create(resource, password = null).getOrNull()!! - val fetcher = ContainerFetcher(archive, MediaTypeRetriever()) - PublicationParser.Asset(file.name, MediaType.CBZ, fetcher) + val resource = FileResource(file, mediaType = MediaType.CBZ) + val archive = DefaultArchiveFactory(MediaTypeRetriever()).create( + resource, + password = null + ).getOrNull()!! + PublicationParser.Asset(mediaType = MediaType.CBZ, archive) } private val jpgAsset = runBlocking { val path = pathForResource("futuristic_tales.jpg") - val file = File(path) - val resource = FileResource(file) - val link = Link(href = "/image.jpg", type = "image/jpeg") - val fetcher = ResourceFetcher(link, resource) - PublicationParser.Asset(file.name, MediaType.JPEG, fetcher) + val resource = FileResource(File(path), mediaType = MediaType.JPEG) + PublicationParser.Asset( + mediaType = MediaType.JPEG, + ResourceContainer(path, resource) + ) } private fun pathForResource(resource: String): String { val path = ImageParserTest::class.java.getResource(resource)?.path @@ -96,6 +99,9 @@ class ImageParserTest { fun `title is based on archive's root directory when any`() { val builder = parser.parseBlocking(cbzAsset) assertNotNull(builder) - assertEquals("Cory Doctorow's Futuristic Tales of the Here and Now", builder!!.manifest.metadata.title) + assertEquals( + "Cory Doctorow's Futuristic Tales of the Here and Now", + builder!!.manifest.metadata.title + ) } } diff --git a/settings.gradle.kts b/settings.gradle.kts index f670f64fb9..9b6225b8f7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ pluginManagement { id("org.jetbrains.dokka") version ("1.8.20") id("org.jetbrains.kotlin.android") version ("1.9.0") id("org.jetbrains.kotlin.plugin.serialization") version ("1.9.0") - id("org.jlleitschuh.gradle.ktlint") version ("11.0.0") + id("org.jlleitschuh.gradle.ktlint") version ("11.5.1") // Make sure to align with the Kotlin version. // See https://github.com/google/ksp/releases id("com.google.devtools.ksp") version ("1.9.0-1.0.12") diff --git a/test-app/src/main/java/org/readium/r2/testapp/Application.kt b/test-app/src/main/java/org/readium/r2/testapp/Application.kt index 1be7df37e2..9b2f24ac04 100755 --- a/test-app/src/main/java/org/readium/r2/testapp/Application.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/Application.kt @@ -62,6 +62,7 @@ class Application : android.app.Application() { readium.publicationFactory, readium.assetRetriever, readium.protectionRetriever, + readium.formatRegistry ) } @@ -71,7 +72,7 @@ class Application : android.app.Application() { this@Application, readium, bookRepository, - navigatorPreferences, + navigatorPreferences ) } } @@ -84,8 +85,11 @@ class Application : android.app.Application() { properties.getProperty("useExternalFileDir", "false")!!.toBoolean() return File( - if (useExternalFileDir) getExternalFilesDir(null)?.path + "/" - else filesDir?.path + "/" + if (useExternalFileDir) { + getExternalFilesDir(null)?.path + "/" + } else { + filesDir?.path + "/" + } ) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt b/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt index 1ff23abb7d..219afb408d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt @@ -37,7 +37,9 @@ class MainActivity : AppCompatActivity() { val appBarConfiguration = AppBarConfiguration( setOf( - R.id.navigation_bookshelf, R.id.navigation_catalog_list, R.id.navigation_about + R.id.navigation_bookshelf, + R.id.navigation_catalog_list, + R.id.navigation_about ) ) setupActionBarWithNavController(navController, appBarConfiguration) diff --git a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt b/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt index 1599e23ed6..8360155d86 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt @@ -20,15 +20,25 @@ sealed class PublicationError(@StringRes userMessageId: Int) : UserException(use class OutOfMemory(val error: Error) : PublicationError(R.string.publication_error_out_of_memory) - class SchemeNotSupported(val error: Error) : PublicationError(R.string.publication_error_scheme_not_supported) + class SchemeNotSupported(val error: Error) : PublicationError( + R.string.publication_error_scheme_not_supported + ) - class UnsupportedPublication(val error: Error? = null) : PublicationError(R.string.publication_error_unsupported_asset) + class UnsupportedPublication(val error: Error? = null) : PublicationError( + R.string.publication_error_unsupported_asset + ) - class InvalidPublication(val error: Error) : PublicationError(R.string.publication_error_invalid_publication) + class InvalidPublication(val error: Error) : PublicationError( + R.string.publication_error_invalid_publication + ) - class IncorrectCredentials(val error: Error) : PublicationError(R.string.publication_error_incorrect_credentials) + class IncorrectCredentials(val error: Error) : PublicationError( + R.string.publication_error_incorrect_credentials + ) - class Forbidden(val error: Error? = null) : PublicationError(R.string.publication_error_forbidden) + class Forbidden(val error: Error? = null) : PublicationError( + R.string.publication_error_forbidden + ) class Unexpected(val error: Error) : PublicationError(R.string.publication_error_unexpected) diff --git a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt index 816fae6a7a..d3d87c9077 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt @@ -24,7 +24,7 @@ import org.readium.r2.shared.resource.FileResourceFactory import org.readium.r2.shared.util.archive.channel.ChannelZipArchiveFactory import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpResourceFactory -import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.FormatRegistry import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.streamer.PublicationFactory @@ -33,42 +33,44 @@ import org.readium.r2.streamer.PublicationFactory */ class Readium(context: Context) { - private val httpClient = DefaultHttpClient() + private val mediaTypeRetriever = MediaTypeRetriever() + + val formatRegistry = FormatRegistry() + + val httpClient = DefaultHttpClient( + mediaTypeRetriever = mediaTypeRetriever + ) private val archiveFactory = CompositeArchiveFactory( - DefaultArchiveFactory(), - ChannelZipArchiveFactory() + DefaultArchiveFactory(mediaTypeRetriever), + ChannelZipArchiveFactory(mediaTypeRetriever) ) private val resourceFactory = CompositeResourceFactory( - FileResourceFactory(), + FileResourceFactory(mediaTypeRetriever), CompositeResourceFactory( ContentResourceFactory(context.contentResolver), HttpResourceFactory(httpClient) ) ) - private val containerFactory = DirectoryContainerFactory() - - private val mediaTypeRetriever = MediaTypeRetriever( - resourceFactory, - containerFactory, - archiveFactory + private val containerFactory = DirectoryContainerFactory( + mediaTypeRetriever ) val assetRetriever = AssetRetriever( + mediaTypeRetriever, resourceFactory, containerFactory, archiveFactory, - context.contentResolver, - MediaType.sniffers + context.contentResolver ) /** * The LCP service decrypts LCP-protected publication and acquire publications from a * license file. */ - val lcpService = LcpService(context, mediaTypeRetriever, resourceFactory, archiveFactory) + val lcpService = LcpService(context, assetRetriever, mediaTypeRetriever) ?.let { Try.success(it) } ?: Try.failure(UserException("liblcp is missing on the classpath")) @@ -87,8 +89,10 @@ class Readium(context: Context) { val publicationFactory = PublicationFactory( context, contentProtections = contentProtections, + mediaTypeRetriever = mediaTypeRetriever, + httpClient = httpClient, // Only required if you want to support PDF files using the PDFium adapter. - pdfFactory = PdfiumDocumentFactory(context), + pdfFactory = PdfiumDocumentFactory(context) ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt index a57260ebed..6675f61d86 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt @@ -38,6 +38,7 @@ import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.publication.protection.ContentProtectionSchemeRetriever import org.readium.r2.shared.publication.services.cover import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.mediatype.FormatRegistry import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.toUrl import org.readium.r2.streamer.PublicationFactory @@ -62,6 +63,7 @@ class BookRepository( private val publicationFactory: PublicationFactory, private val assetRetriever: AssetRetriever, private val protectionRetriever: ContentProtectionSchemeRetriever, + private val formatRegistry: FormatRegistry ) { private val coverDir: File = File(storageDir, "covers/") @@ -79,7 +81,6 @@ class BookRepository( val bookmark = Bookmark( creation = DateTime().toDate().time, bookId = bookId, - publicationId = publication.metadata.identifier ?: publication.metadata.title, resourceIndex = resource.toLong(), resourceHref = locator.href, resourceType = locator.type, @@ -196,10 +197,12 @@ class BookRepository( suspend fun addRemoteBook( url: Url ): Try { - val asset = assetRetriever.retrieve(url, fileExtension = url.extension) + val asset = assetRetriever.retrieve(url) ?: return Try.failure( ImportError.PublicationError( - PublicationError.UnsupportedPublication(Publication.OpeningException.UnsupportedAsset()) + PublicationError.UnsupportedPublication( + Publication.OpeningException.UnsupportedAsset() + ) ) ) return addBook(url, asset) @@ -207,7 +210,7 @@ class BookRepository( suspend fun addSharedStorageBook( url: Url, - coverUrl: String? = null, + coverUrl: String? = null ): Try { val asset = assetRetriever.retrieve(url) ?: return Try.failure( @@ -223,12 +226,14 @@ class BookRepository( suspend fun addLocalBook( tempFile: File, - coverUrl: String? = null, + coverUrl: String? = null ): Try { val sourceAsset = assetRetriever.retrieve(tempFile) ?: return Try.failure( ImportError.PublicationError( - PublicationError.UnsupportedPublication(Publication.OpeningException.UnsupportedAsset()) + PublicationError.UnsupportedPublication( + Publication.OpeningException.UnsupportedAsset() + ) ) ) @@ -260,7 +265,8 @@ class BookRepository( ) } - val fileName = "${UUID.randomUUID()}.${publicationTempAsset.mediaType.fileExtension}" + val fileExtension = formatRegistry.fileExtension(publicationTempAsset.mediaType) ?: "epub" + val fileName = "${UUID.randomUUID()}.$fileExtension" val libraryFile = File(storageDir, fileName) val libraryUrl = libraryFile.toUrl() @@ -279,7 +285,9 @@ class BookRepository( ).getOrElse { return Try.failure(ImportError.PublicationError(it)) } return addBook( - libraryUrl, libraryAsset, coverUrl + libraryUrl, + libraryAsset, + coverUrl ).onFailure { tryOrNull { libraryFile.delete() } } @@ -288,7 +296,7 @@ class BookRepository( private suspend fun addBook( url: Url, asset: Asset, - coverUrl: String? = null, + coverUrl: String? = null ): Try { val drmScheme = protectionRetriever.retrieve(asset) diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt index d57c6cdc9e..47d3af18d8 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt @@ -29,13 +29,14 @@ class BookshelfAdapter( ): ViewHolder { return ViewHolder( ItemRecycleBookBinding.inflate( - LayoutInflater.from(parent.context), parent, false + LayoutInflater.from(parent.context), + parent, + false ) ) } override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { - val book = getItem(position) viewHolder.bind(book) diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt index 143c2a4fa6..e6b3bc1f3f 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt @@ -54,7 +54,14 @@ class BookshelfFragment : Fragment() { bookshelfViewModel.channel.receive(viewLifecycleOwner) { handleEvent(it) } bookshelfAdapter = BookshelfAdapter( - onBookClick = { book -> book.id?.let { bookshelfViewModel.openPublication(it, requireActivity()) } }, + onBookClick = { book -> + book.id?.let { + bookshelfViewModel.openPublication( + it, + requireActivity() + ) + } + }, onBookLongClick = { book -> confirmDeleteBook(book) } ) @@ -151,7 +158,10 @@ class BookshelfFragment : Fragment() { } is BookshelfViewModel.Event.LaunchReader -> { - val intent = ReaderActivityContract().createIntent(requireContext(), event.arguments) + val intent = ReaderActivityContract().createIntent( + requireContext(), + event.arguments + ) startActivity(intent) null } diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt index ebf3ef591b..30896da39d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt @@ -49,10 +49,11 @@ class BookshelfViewModel(application: Application) : AndroidViewModel(applicatio for (element in samples) { val file = app.assets.open("Samples/$element").copyToTempFile(app.storageDir) - if (file != null) + if (file != null) { app.bookRepository.addLocalBook(file) - else if (BuildConfig.DEBUG) + } else if (BuildConfig.DEBUG) { error("Unable to load sample into the library") + } } preferences.edit().putBoolean("samples", true).apply() } diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt index f35ec8cc82..954bd194c2 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt @@ -30,7 +30,6 @@ class CatalogFeedListAdapter(private val onLongClick: (Catalog) -> Unit) : } override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { - val catalog = getItem(position) viewHolder.bind(catalog) diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt index 9dbfeebffd..f812c7d320 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt @@ -70,7 +70,6 @@ class CatalogFeedListFragment : Fragment() { val VERSION_KEY = "OPDS_CATALOG_VERSION" if (preferences.getInt(VERSION_KEY, 0) < version) { - preferences.edit().putInt(VERSION_KEY, version).apply() val oPDS2Catalog = Catalog( @@ -120,7 +119,9 @@ class CatalogFeedListFragment : Fragment() { private fun handleEvent(event: CatalogFeedListViewModel.Event) { val message = when (event) { - is CatalogFeedListViewModel.Event.FeedListEvent.CatalogParseFailed -> getString(R.string.catalog_parse_error) + is CatalogFeedListViewModel.Event.FeedListEvent.CatalogParseFailed -> getString( + R.string.catalog_parse_error + ) } Snackbar.make( requireView(), diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt index 81dc0c94ae..01484ae992 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt @@ -17,7 +17,6 @@ import org.readium.r2.opds.OPDS1Parser import org.readium.r2.opds.OPDS2Parser import org.readium.r2.shared.error.Try import org.readium.r2.shared.opds.ParseData -import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpRequest import org.readium.r2.shared.util.http.fetchWithDecoder import org.readium.r2.testapp.db.BookDatabase @@ -26,6 +25,7 @@ import org.readium.r2.testapp.utils.EventChannel class CatalogFeedListViewModel(application: Application) : AndroidViewModel(application) { + private val httpClient = getApplication().readium.httpClient private val catalogDao = BookDatabase.getDatabase(application).catalogDao() private val repository = CatalogRepository(catalogDao) val eventChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) @@ -56,7 +56,7 @@ class CatalogFeedListViewModel(application: Application) : AndroidViewModel(appl } private suspend fun parseURL(url: URL): Try { - return DefaultHttpClient().fetchWithDecoder(HttpRequest(url.toString())) { + return httpClient.fetchWithDecoder(HttpRequest(url.toString())) { val result = it.body if (isJson(result)) { OPDS2Parser.parse(result, url) diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt index 6fdabfaab3..e22619b4ca 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt @@ -49,7 +49,6 @@ class CatalogFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - catalogViewModel.eventChannel.receive(this) { handleEvent(it) } catalog = arguments?.let { BundleCompat.getParcelable(it, CATALOGFEED, Catalog::class.java) }!! diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt index 7aa15b19fb..e7367f1690 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt @@ -31,12 +31,10 @@ import timber.log.Timber class CatalogViewModel(application: Application) : AndroidViewModel(application) { - private val app get() = - getApplication() - val detailChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) val eventChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) lateinit var publication: Publication + private val app = getApplication() fun parseCatalog(catalog: Catalog) = viewModelScope.launch { var parseRequest: Try? = null @@ -44,9 +42,9 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) val request = HttpRequest(it) try { parseRequest = if (catalog.type == 1) { - OPDS1Parser.parseRequest(request) + OPDS1Parser.parseRequest(request, app.readium.httpClient) } else { - OPDS2Parser.parseRequest(request) + OPDS2Parser.parseRequest(request, app.readium.httpClient) } } catch (e: MalformedURLException) { eventChannel.send(Event.FeedEvent.CatalogParseFailed) @@ -67,7 +65,11 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) getDownloadURL(publication) .flatMap { url -> - url.downloadTo(dest) + url.downloadTo( + dest, + httpClient = app.readium.httpClient, + assetRetriever = app.readium.assetRetriever + ) }.flatMap { val opdsCover = publication.images.firstOrNull()?.href app.bookRepository.addLocalBook(dest, opdsCover) @@ -80,7 +82,7 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) private fun getDownloadURL(publication: Publication): Try = publication.links - .firstOrNull { it.mediaType.isPublication || it.mediaType == MediaType.LCP_LICENSE_DOCUMENT } + .firstOrNull { it.mediaType?.isPublication == true || it.mediaType == MediaType.LCP_LICENSE_DOCUMENT } ?.let { try { Try.success(URL(it.href)) diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt index c26c92594a..dbf0764271 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt @@ -33,7 +33,9 @@ class GroupAdapter( ): ViewHolder { return ViewHolder( ItemGroupViewBinding.inflate( - LayoutInflater.from(parent.context), parent, false + LayoutInflater.from(parent.context), + parent, + false ) ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt index 1b84181d6d..70f6b763fd 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt @@ -27,7 +27,9 @@ class NavigationAdapter(val type: Int) : ): ViewHolder { return ViewHolder( ItemRecycleButtonBinding.inflate( - LayoutInflater.from(parent.context), parent, false + LayoutInflater.from(parent.context), + parent, + false ) ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt index f4ae4e6bb0..3114869a3e 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationAdapter.kt @@ -33,7 +33,6 @@ class PublicationAdapter( } override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { - val publication = getItem(position) viewHolder.bind(publication) diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt index 9aba970547..a5ca3f2a7e 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt @@ -34,7 +34,9 @@ class PublicationDetailFragment : Fragment() { savedInstanceState: Bundle? ): View { _binding = FragmentPublicationDetailBinding.inflate( - inflater, container, false + inflater, + container, + false ) catalogViewModel.detailChannel.receive(this) { handleEvent(it) } publication = catalogViewModel.publication @@ -65,8 +67,12 @@ class PublicationDetailFragment : Fragment() { private fun handleEvent(event: CatalogViewModel.Event.DetailEvent) { val message = when (event) { - is CatalogViewModel.Event.DetailEvent.ImportPublicationSuccess -> getString(R.string.import_publication_success) - is CatalogViewModel.Event.DetailEvent.ImportPublicationFailed -> getString(R.string.import_publication_unable_add_pub_database) + is CatalogViewModel.Event.DetailEvent.ImportPublicationSuccess -> getString( + R.string.import_publication_success + ) + is CatalogViewModel.Event.DetailEvent.ImportPublicationFailed -> getString( + R.string.import_publication_unable_add_pub_database + ) } binding.catalogDetailProgressBar.visibility = View.GONE Snackbar.make( diff --git a/test-app/src/main/java/org/readium/r2/testapp/db/BooksDao.kt b/test-app/src/main/java/org/readium/r2/testapp/db/BooksDao.kt index c9ed6da5aa..ec53bc5328 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/db/BooksDao.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/db/BooksDao.kt @@ -59,7 +59,9 @@ interface BooksDao { /** * Retrieve all highlights for a specific book */ - @Query("SELECT * FROM ${Highlight.TABLE_NAME} WHERE ${Highlight.BOOK_ID} = :bookId ORDER BY ${Highlight.TOTAL_PROGRESSION} ASC") + @Query( + "SELECT * FROM ${Highlight.TABLE_NAME} WHERE ${Highlight.BOOK_ID} = :bookId ORDER BY ${Highlight.TOTAL_PROGRESSION} ASC" + ) fun getHighlightsForBook(bookId: Long): Flow> /** @@ -87,13 +89,17 @@ interface BooksDao { /** * Updates a highlight's annotation. */ - @Query("UPDATE ${Highlight.TABLE_NAME} SET ${Highlight.ANNOTATION} = :annotation WHERE ${Highlight.ID} = :id") + @Query( + "UPDATE ${Highlight.TABLE_NAME} SET ${Highlight.ANNOTATION} = :annotation WHERE ${Highlight.ID} = :id" + ) suspend fun updateHighlightAnnotation(id: Long, annotation: String) /** * Updates a highlight's tint and style. */ - @Query("UPDATE ${Highlight.TABLE_NAME} SET ${Highlight.TINT} = :tint, ${Highlight.STYLE} = :style WHERE ${Highlight.ID} = :id") + @Query( + "UPDATE ${Highlight.TABLE_NAME} SET ${Highlight.TINT} = :tint, ${Highlight.STYLE} = :style WHERE ${Highlight.ID} = :id" + ) suspend fun updateHighlightStyle(id: Long, style: Highlight.Style, @ColorInt tint: Int) /** @@ -113,6 +119,8 @@ interface BooksDao { * @param locator Location of the book * @param id The book to update */ - @Query("UPDATE " + Book.TABLE_NAME + " SET " + Book.PROGRESSION + " = :locator WHERE " + Book.ID + "= :id") + @Query( + "UPDATE " + Book.TABLE_NAME + " SET " + Book.PROGRESSION + " = :locator WHERE " + Book.ID + "= :id" + ) suspend fun saveProgression(locator: String, id: Long) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/db/CatalogDao.kt b/test-app/src/main/java/org/readium/r2/testapp/db/CatalogDao.kt index e27a705848..1298298c83 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/db/CatalogDao.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/db/CatalogDao.kt @@ -28,7 +28,9 @@ interface CatalogDao { * Retrieve list of Catalog models based on Catalog model * @return List of Catalog models as LiveData */ - @Query("SELECT * FROM " + Catalog.TABLE_NAME + " WHERE " + Catalog.TITLE + " = :title AND " + Catalog.HREF + " = :href AND " + Catalog.TYPE + " = :type") + @Query( + "SELECT * FROM " + Catalog.TABLE_NAME + " WHERE " + Catalog.TITLE + " = :title AND " + Catalog.HREF + " = :href AND " + Catalog.TYPE + " = :type" + ) fun getCatalogModels(title: String, href: String, type: Int): LiveData> /** diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt index 75ed666f90..42206cb07d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt @@ -23,7 +23,7 @@ data class Book( @ColumnInfo(name = HREF) val href: String, @ColumnInfo(name = TITLE) - val title: String, + val title: String?, @ColumnInfo(name = AUTHOR) val author: String? = null, @ColumnInfo(name = IDENTIFIER) @@ -37,21 +37,21 @@ data class Book( @ColumnInfo(name = DRM) val drm: String? = null, @ColumnInfo(name = COVER) - val cover: String, + val cover: String ) { constructor( id: Long? = null, creation: Long? = null, href: String, - title: String, + title: String?, author: String? = null, identifier: String, progression: String? = null, mediaType: MediaType, assetType: AssetType, drm: ContentProtection.Scheme?, - cover: String, + cover: String ) : this( id = id, creation = creation, @@ -63,11 +63,11 @@ data class Book( rawMediaType = mediaType.toString(), rawAssetType = assetType.value, drm = drm?.uri, - cover = cover, + cover = cover ) val mediaType: MediaType get() = - MediaType(rawMediaType) + MediaType(rawMediaType) ?: MediaType.BINARY val drmScheme: ContentProtection.Scheme? get() = drm?.let { ContentProtection.Scheme(it) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Bookmark.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Bookmark.kt index e9cd2ae496..b2dd2cbb1a 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Bookmark.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Bookmark.kt @@ -17,7 +17,7 @@ import org.readium.r2.shared.publication.Locator tableName = Bookmark.TABLE_NAME, indices = [ Index( - value = ["BOOK_ID", "LOCATION"], + value = [Bookmark.BOOK_ID, Bookmark.LOCATION], unique = true ) ] @@ -30,8 +30,6 @@ data class Bookmark( var creation: Long? = null, @ColumnInfo(name = BOOK_ID) val bookId: Long, - @ColumnInfo(name = PUBLICATION_ID) - val publicationId: String, @ColumnInfo(name = RESOURCE_INDEX) val resourceIndex: Long, @ColumnInfo(name = RESOURCE_HREF) @@ -57,16 +55,15 @@ data class Bookmark( companion object { - const val TABLE_NAME = "BOOKMARKS" - const val ID = "ID" - const val CREATION_DATE = "CREATION_DATE" - const val BOOK_ID = "BOOK_ID" - const val PUBLICATION_ID = "PUBLICATION_ID" - const val RESOURCE_INDEX = "RESOURCE_INDEX" - const val RESOURCE_HREF = "RESOURCE_HREF" - const val RESOURCE_TYPE = "RESOURCE_TYPE" - const val RESOURCE_TITLE = "RESOURCE_TITLE" - const val LOCATION = "LOCATION" - const val LOCATOR_TEXT = "LOCATOR_TEXT" + const val TABLE_NAME = "bookmarks" + const val ID = "id" + const val CREATION_DATE = "creation_date" + const val BOOK_ID = "book_id" + const val RESOURCE_INDEX = "resource_index" + const val RESOURCE_HREF = "resource_href" + const val RESOURCE_TYPE = "resource_type" + const val RESOURCE_TITLE = "resource_title" + const val LOCATION = "location" + const val LOCATOR_TEXT = "locator_text" } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Catalog.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Catalog.kt index 2eb3073a0a..f04c61fe18 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Catalog.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Catalog.kt @@ -27,10 +27,10 @@ data class Catalog( ) : Parcelable { companion object { - const val TABLE_NAME = "CATALOG" - const val ID = "ID" - const val TITLE = "TITLE" - const val HREF = "HREF" - const val TYPE = "TYPE" + const val TABLE_NAME = "catalogs" + const val ID = "id" + const val TITLE = "title" + const val HREF = "href" + const val TYPE = "type" } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Highlight.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Highlight.kt index 6df45b7d9c..58d770c2e0 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Highlight.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/model/Highlight.kt @@ -27,7 +27,12 @@ import org.readium.r2.shared.publication.Locator @Entity( tableName = "highlights", foreignKeys = [ - ForeignKey(entity = Book::class, parentColumns = [Book.ID], childColumns = [Highlight.BOOK_ID], onDelete = ForeignKey.CASCADE) + ForeignKey( + entity = Book::class, + parentColumns = [Book.ID], + childColumns = [Highlight.BOOK_ID], + onDelete = ForeignKey.CASCADE + ) ], indices = [Index(value = [Highlight.BOOK_ID])] ) @@ -42,7 +47,8 @@ data class Highlight( @ColumnInfo(name = STYLE) var style: Style, @ColumnInfo(name = TINT, defaultValue = "0") - @ColorInt var tint: Int, + @ColorInt + var tint: Int, @ColumnInfo(name = HREF) var href: String, @ColumnInfo(name = TYPE) @@ -56,7 +62,7 @@ data class Highlight( @ColumnInfo(name = TEXT, defaultValue = "{}") var text: Locator.Text = Locator.Text(), @ColumnInfo(name = ANNOTATION, defaultValue = "") - var annotation: String = "", + var annotation: String = "" ) { constructor( @@ -84,7 +90,7 @@ data class Highlight( type = type, title = title, locations = locations, - text = text, + text = text ) enum class Style(val value: String) { @@ -121,16 +127,23 @@ data class Highlight( class HighlightConverters { @TypeConverter fun styleFromString(value: String?): Highlight.Style = Highlight.Style.getOrDefault(value) + @TypeConverter fun styleToString(style: Highlight.Style): String = style.value @TypeConverter - fun textFromString(value: String?): Locator.Text = Locator.Text.fromJSON(value?.let { JSONObject(it) }) + fun textFromString(value: String?): Locator.Text = Locator.Text.fromJSON( + value?.let { JSONObject(it) } + ) + @TypeConverter fun textToString(text: Locator.Text): String = text.toJSON().toString() @TypeConverter - fun locationsFromString(value: String?): Locator.Locations = Locator.Locations.fromJSON(value?.let { JSONObject(it) }) + fun locationsFromString(value: String?): Locator.Locations = Locator.Locations.fromJSON( + value?.let { JSONObject(it) } + ) + @TypeConverter fun locationsToString(text: Locator.Locations): String = text.toJSON().toString() } diff --git a/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementFragment.kt index 883dda0ae2..e6351acaba 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementFragment.kt @@ -73,10 +73,11 @@ class DrmManagementFragment : Fragment() { binding.drmValueCopiesLeft.text = model.copiesLeft val datesVisibility = - if (model.start != null && model.end != null && model.start != model.end) + if (model.start != null && model.end != null && model.start != model.end) { View.VISIBLE - else + } else { View.GONE + } binding.drmStart.visibility = datesVisibility binding.drmValueStart.text = model.start.toFormattedString() @@ -135,8 +136,9 @@ private fun Date?.toFormattedString() = // FIXME: the toast is drawn behind the navigation bar private fun Exception.toastUserMessage(view: View) { - if (this is UserException) + if (this is UserException) { Snackbar.make(view, getUserMessage(view.context), Snackbar.LENGTH_LONG).show() + } Timber.d(this) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt index f0bd7295e4..f65ea38f83 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt @@ -15,16 +15,19 @@ import org.readium.r2.shared.error.Try class LcpManagementViewModel( private val lcpLicense: LcpLicense, - private val renewListener: LcpLicense.RenewListener, + private val renewListener: LcpLicense.RenewListener ) : DrmManagementViewModel() { class Factory( private val lcpLicense: LcpLicense, - private val renewListener: LcpLicense.RenewListener, + private val renewListener: LcpLicense.RenewListener ) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T = - modelClass.getDeclaredConstructor(LcpLicense::class.java, LcpLicense.RenewListener::class.java) + modelClass.getDeclaredConstructor( + LcpLicense::class.java, + LcpLicense.RenewListener::class.java + ) .newInstance(lcpLicense, renewListener) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/opds/GridAutoFitLayoutManager.kt b/test-app/src/main/java/org/readium/r2/testapp/opds/GridAutoFitLayoutManager.kt index 20f512453b..d437f0742d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/opds/GridAutoFitLayoutManager.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/opds/GridAutoFitLayoutManager.kt @@ -27,7 +27,12 @@ class GridAutoFitLayoutManager : GridLayoutManager { setColumnWidth(checkedColumnWidth(context, columnWidth)) } /* Initially set spanCount to 1, will be changed automatically later. */ - constructor(context: Context, columnWidth: Int, orientation: Int, reverseLayout: Boolean) : super(context, 1, orientation, reverseLayout) { + constructor(context: Context, columnWidth: Int, orientation: Int, reverseLayout: Boolean) : super( + context, + 1, + orientation, + reverseLayout + ) { setColumnWidth(checkedColumnWidth(context, columnWidth)) } /* Initially set spanCount to 1, will be changed automatically later. */ @@ -35,12 +40,14 @@ class GridAutoFitLayoutManager : GridLayoutManager { var width = columnWidth width = if (width <= 0) { TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, sColumnWidth.toFloat(), + TypedValue.COMPLEX_UNIT_DIP, + sColumnWidth.toFloat(), context.resources.displayMetrics ).toInt() } else { TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, width.toFloat(), + TypedValue.COMPLEX_UNIT_DIP, + width.toFloat(), context.resources.displayMetrics ).toInt() } diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt index 5dd4bc6cf8..8a23edfb71 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt @@ -58,13 +58,20 @@ class BookmarksFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bookmarkAdapter = BookmarkAdapter(publication, onBookmarkDeleteRequested = { bookmark -> viewModel.deleteBookmark(bookmark.id!!) }, onBookmarkSelectedRequested = { bookmark -> onBookmarkSelected(bookmark) }) + bookmarkAdapter = BookmarkAdapter( + publication, + onBookmarkDeleteRequested = { bookmark -> viewModel.deleteBookmark(bookmark.id!!) }, + onBookmarkSelectedRequested = { bookmark -> onBookmarkSelected(bookmark) } + ) binding.listView.apply { layoutManager = LinearLayoutManager(requireContext()) adapter = bookmarkAdapter } - val comparator: Comparator = compareBy({ it.resourceIndex }, { it.locator.locations.progression }) + val comparator: Comparator = compareBy( + { it.resourceIndex }, + { it.locator.locations.progression } + ) viewModel.getBookmarks().observe(viewLifecycleOwner) { val bookmarks = it.sortedWith(comparator) bookmarkAdapter.submitList(bookmarks) @@ -92,7 +99,9 @@ class BookmarkAdapter( ): ViewHolder { return ViewHolder( ItemRecycleBookmarkBinding.inflate( - LayoutInflater.from(parent.context), parent, false + LayoutInflater.from(parent.context), + parent, + false ) ) } @@ -104,7 +113,9 @@ class BookmarkAdapter( holder.bind(item) } - inner class ViewHolder(val binding: ItemRecycleBookmarkBinding) : RecyclerView.ViewHolder(binding.root) { + inner class ViewHolder(val binding: ItemRecycleBookmarkBinding) : RecyclerView.ViewHolder( + binding.root + ) { fun bind(bookmark: Bookmark) { val title = getBookSpineItem(bookmark.resourceHref) @@ -120,7 +131,6 @@ class BookmarkAdapter( binding.bookmarkTimestamp.text = formattedDate binding.overflow.setOnClickListener { - val popupMenu = PopupMenu(binding.overflow.context, binding.overflow) popupMenu.menuInflater.inflate(R.menu.menu_bookmark, popupMenu.menu) popupMenu.show() diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt index 1137d0eb16..d34db2cb2c 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt @@ -59,7 +59,11 @@ class HighlightsFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - highlightAdapter = HighlightAdapter(publication, onDeleteHighlightRequested = { highlight -> viewModel.deleteHighlight(highlight.id) }, onHighlightSelectedRequested = { highlight -> onHighlightSelected(highlight) }) + highlightAdapter = HighlightAdapter( + publication, + onDeleteHighlightRequested = { highlight -> viewModel.deleteHighlight(highlight.id) }, + onHighlightSelectedRequested = { highlight -> onHighlightSelected(highlight) } + ) binding.listView.apply { layoutManager = LinearLayoutManager(requireContext()) adapter = highlightAdapter @@ -91,7 +95,9 @@ class HighlightAdapter( ): ViewHolder { return ViewHolder( ItemRecycleHighlightBinding.inflate( - LayoutInflater.from(parent.context), parent, false + LayoutInflater.from(parent.context), + parent, + false ) ) } @@ -103,19 +109,25 @@ class HighlightAdapter( holder.bind(item) } - inner class ViewHolder(val binding: ItemRecycleHighlightBinding) : RecyclerView.ViewHolder(binding.root) { + inner class ViewHolder(val binding: ItemRecycleHighlightBinding) : RecyclerView.ViewHolder( + binding.root + ) { fun bind(highlight: Highlight) { binding.highlightChapter.text = highlight.title binding.highlightText.text = highlight.locator.text.highlight binding.annotation.text = highlight.annotation - val formattedDate = DateTime(highlight.creation).toString(DateTimeFormat.shortDateTime()) + val formattedDate = DateTime(highlight.creation).toString( + DateTimeFormat.shortDateTime() + ) binding.highlightTimeStamp.text = formattedDate binding.highlightOverflow.setOnClickListener { - - val popupMenu = PopupMenu(binding.highlightOverflow.context, binding.highlightOverflow) + val popupMenu = PopupMenu( + binding.highlightOverflow.context, + binding.highlightOverflow + ) popupMenu.menuInflater.inflate(R.menu.menu_bookmark, popupMenu.menu) popupMenu.show() diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt index 1c50a406aa..f5232732bc 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/NavigationFragment.kt @@ -42,7 +42,9 @@ class NavigationFragment : Fragment() { publication = it.publication } - links = requireNotNull(BundleCompat.getParcelableArrayList(requireArguments(), LINKS_ARG, Link::class.java)) + links = requireNotNull( + BundleCompat.getParcelableArrayList(requireArguments(), LINKS_ARG, Link::class.java) + ) } override fun onCreateView( @@ -97,7 +99,10 @@ class NavigationFragment : Fragment() { fun newInstance(links: List) = NavigationFragment().apply { arguments = Bundle().apply { - putParcelableArrayList(LINKS_ARG, if (links is ArrayList) links else ArrayList(links)) + putParcelableArrayList( + LINKS_ARG, + if (links is ArrayList) links else ArrayList(links) + ) } } } @@ -112,7 +117,9 @@ class NavigationAdapter(private val onLinkSelected: (Link) -> Unit) : ): ViewHolder { return ViewHolder( ItemRecycleNavigationBinding.inflate( - LayoutInflater.from(parent.context), parent, false + LayoutInflater.from(parent.context), + parent, + false ) ) } @@ -124,11 +131,16 @@ class NavigationAdapter(private val onLinkSelected: (Link) -> Unit) : holder.bind(item) } - inner class ViewHolder(val binding: ItemRecycleNavigationBinding) : RecyclerView.ViewHolder(binding.root) { + inner class ViewHolder(val binding: ItemRecycleNavigationBinding) : RecyclerView.ViewHolder( + binding.root + ) { fun bind(item: Pair) { binding.navigationTextView.text = item.second.outlineTitle - binding.indentation.layoutParams = LinearLayout.LayoutParams(item.first * 50, ViewGroup.LayoutParams.MATCH_PARENT) + binding.indentation.layoutParams = LinearLayout.LayoutParams( + item.first * 50, + ViewGroup.LayoutParams.MATCH_PARENT + ) binding.root.setOnClickListener { onLinkSelected(item.second) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt index 434b314442..fb46d2d5e1 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineContract.kt @@ -22,7 +22,9 @@ object OutlineContract { Bundle().apply { putParcelable(DESTINATION_KEY, locator) } fun parseResult(result: Bundle): Result { - val destination = requireNotNull(BundleCompat.getParcelable(result, DESTINATION_KEY, Locator::class.java)) + val destination = requireNotNull( + BundleCompat.getParcelable(result, DESTINATION_KEY, Locator::class.java) + ) return Result(destination) } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineFragment.kt index 3de2c3d22d..aa5e1f8bc5 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/OutlineFragment.kt @@ -60,12 +60,22 @@ class OutlineFragment : Fragment() { super.onViewCreated(view, savedInstanceState) val outlines: List = when { - publication.conformsTo(Publication.Profile.EPUB) -> listOf(Outline.Contents, Outline.Bookmarks, Outline.Highlights, Outline.PageList, Outline.Landmarks) + publication.conformsTo(Publication.Profile.EPUB) -> listOf( + Outline.Contents, + Outline.Bookmarks, + Outline.Highlights, + Outline.PageList, + Outline.Landmarks + ) else -> listOf(Outline.Contents, Outline.Bookmarks) } binding.outlinePager.adapter = OutlineFragmentStateAdapter(this, publication, outlines) - TabLayoutMediator(binding.outlineTabLayout, binding.outlinePager) { tab, idx -> tab.setText(outlines[idx].label) }.attach() + TabLayoutMediator(binding.outlineTabLayout, binding.outlinePager) { tab, idx -> + tab.setText( + outlines[idx].label + ) + }.attach() } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt index a7322e9288..9940f98d83 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/AudioReaderFragment.kt @@ -100,10 +100,11 @@ class AudioReaderFragment : BaseReaderFragment(), SeekBar.OnSeekBarChangeListene binding.timelineDuration.isEnabled = true binding.timelinePosition.isEnabled = true binding.playPause.setImageResource( - if (playback.playWhenReady) + if (playback.playWhenReady) { R.drawable.ic_baseline_pause_24 - else + } else { R.drawable.ic_baseline_play_arrow_24 + } ) if (seekingItem == null) { diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt index f433230041..89b7299f69 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt @@ -50,7 +50,9 @@ abstract class BaseReaderFragment : Fragment() { when (event) { is ReaderViewModel.FeedbackEvent.BookmarkFailed -> toast(R.string.bookmark_exists) - is ReaderViewModel.FeedbackEvent.BookmarkSuccessfullyAdded -> toast(R.string.bookmark_added) + is ReaderViewModel.FeedbackEvent.BookmarkSuccessfullyAdded -> toast( + R.string.bookmark_added + ) } } } @@ -86,7 +88,9 @@ abstract class BaseReaderFragment : Fragment() { .show(childFragmentManager, "Settings") } R.id.drm -> { - model.activityChannel.send(ReaderViewModel.Event.OpenDrmManagementRequested) + model.activityChannel.send( + ReaderViewModel.Event.OpenDrmManagementRequested + ) } } return true diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt index d39c496aa7..f49028777d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt @@ -102,7 +102,11 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene this, FragmentResultListener { _, result -> menuSearch.collapseActionView() - BundleCompat.getParcelable(result, SearchFragment::class.java.name, Locator::class.java)?.let { + BundleCompat.getParcelable( + result, + SearchFragment::class.java.name, + Locator::class.java + )?.let { navigator.go(it) } } @@ -120,7 +124,12 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene if (savedInstanceState == null) { childFragmentManager.commitNow { - add(R.id.fragment_reader_container, EpubNavigatorFragment::class.java, Bundle(), NAVIGATOR_FRAGMENT_TAG) + add( + R.id.fragment_reader_container, + EpubNavigatorFragment::class.java, + Bundle(), + NAVIGATOR_FRAGMENT_TAG + ) } } navigator = childFragmentManager.findFragmentByTag(NAVIGATOR_FRAGMENT_TAG) as EpubNavigatorFragment @@ -189,7 +198,7 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene Decoration( id = "page-$index", locator = locator, - style = DecorationStylePageNumber(label = label), + style = DecorationStylePageNumber(label = label) ) } @@ -242,7 +251,8 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene menuSearchView.setQuery("", false) (activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.showSoftInput( - this.view, 0 + this.view, + 0 ) } } @@ -250,7 +260,12 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene private fun showSearchFragment() { childFragmentManager.commit { childFragmentManager.findFragmentByTag(SEARCH_FRAGMENT_TAG)?.let { remove(it) } - add(R.id.fragment_reader_container, SearchFragment::class.java, Bundle(), SEARCH_FRAGMENT_TAG) + add( + R.id.fragment_reader_container, + SearchFragment::class.java, + Bundle(), + SEARCH_FRAGMENT_TAG + ) hide(navigator) addToBackStack(SEARCH_FRAGMENT_TAG) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/FullscreenReaderActivityDelegate.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/FullscreenReaderActivityDelegate.kt index b8c1bc8d5c..62d648b1d3 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/FullscreenReaderActivityDelegate.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/FullscreenReaderActivityDelegate.kt @@ -22,11 +22,10 @@ import org.readium.r2.testapp.utils.showSystemUi class FullscreenReaderActivityDelegate( private val activity: AppCompatActivity, private val readerFragment: VisualReaderFragment, - private val binding: ActivityReaderBinding, + private val binding: ActivityReaderBinding ) : DefaultLifecycleObserver { override fun onCreate(owner: LifecycleOwner) { - // Without this, activity_reader_container receives the insets only once, // although we need a call every time the reader is hidden activity.window.decorView.setOnApplyWindowInsetsListener { view, insets -> @@ -49,19 +48,21 @@ class FullscreenReaderActivityDelegate( } private fun updateSystemUiVisibility() { - if (readerFragment.isHidden) + if (readerFragment.isHidden) { activity.showSystemUi() - else + } else { readerFragment.updateSystemUiVisibility() + } // Seems to be required to adjust padding when transitioning from the outlines to the screen reader binding.activityContainer.requestApplyInsets() } private fun updateSystemUiPadding(container: View, insets: WindowInsets) { - if (readerFragment.isHidden) + if (readerFragment.isHidden) { container.padSystemUi(insets, activity) - else + } else { container.clearPadding() + } } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ImageReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ImageReaderFragment.kt index 6854ca3ff4..295a00de1e 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ImageReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ImageReaderFragment.kt @@ -36,7 +36,12 @@ class ImageReaderFragment : VisualReaderFragment(), ImageNavigatorFragment.Liste val view = super.onCreateView(inflater, container, savedInstanceState) if (savedInstanceState == null) { childFragmentManager.commitNow { - add(R.id.fragment_reader_container, ImageNavigatorFragment::class.java, Bundle(), NAVIGATOR_FRAGMENT_TAG) + add( + R.id.fragment_reader_container, + ImageNavigatorFragment::class.java, + Bundle(), + NAVIGATOR_FRAGMENT_TAG + ) } } navigator = childFragmentManager.findFragmentByTag(NAVIGATOR_FRAGMENT_TAG)!! as Navigator diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt index 9f384735c5..d9d81dc1be 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt @@ -34,7 +34,7 @@ class MediaService : MediaSessionService() { class Session( val bookId: Long, val navigator: AnyMediaNavigator, - val mediaSession: MediaSession, + val mediaSession: MediaSession ) { val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) } @@ -101,7 +101,9 @@ class MediaService : MediaSessionService() { flags = flags or PendingIntent.FLAG_IMMUTABLE } - val intent = application.packageManager.getLaunchIntentForPackage(application.packageName) + val intent = application.packageManager.getLaunchIntentForPackage( + application.packageName + ) return PendingIntent.getActivity(applicationContext, 0, intent, flags) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/PdfReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/PdfReaderFragment.kt index a1b76a4b37..d1a78e696e 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/PdfReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/PdfReaderFragment.kt @@ -33,7 +33,7 @@ class PdfReaderFragment : VisualReaderFragment(), PdfNavigatorFragment.Listener readerData.navigatorFactory.createFragmentFactory( initialLocator = readerData.initialLocation, initialPreferences = readerData.preferencesManager.preferences.value, - listener = this, + listener = this ) super.onCreate(savedInstanceState) @@ -47,7 +47,12 @@ class PdfReaderFragment : VisualReaderFragment(), PdfNavigatorFragment.Listener val view = super.onCreateView(inflater, container, savedInstanceState) if (savedInstanceState == null) { childFragmentManager.commitNow { - replace(R.id.fragment_reader_container, PdfNavigatorFragment::class.java, Bundle(), NAVIGATOR_FRAGMENT_TAG) + replace( + R.id.fragment_reader_container, + PdfNavigatorFragment::class.java, + Bundle(), + NAVIGATOR_FRAGMENT_TAG + ) } } @Suppress("Unchecked_cast") diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt index 5b5e0b326e..58269a9bf4 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivity.kt @@ -39,7 +39,10 @@ open class ReaderActivity : AppCompatActivity() { private val model: ReaderViewModel by viewModels() override val defaultViewModelProviderFactory: ViewModelProvider.Factory - get() = ReaderViewModel.createFactory(application as Application, ReaderActivityContract.parseIntent(this)) + get() = ReaderViewModel.createFactory( + application as Application, + ReaderActivityContract.parseIntent(this) + ) private lateinit var binding: ActivityReaderBinding private lateinit var readerFragment: BaseReaderFragment @@ -89,8 +92,9 @@ open class ReaderActivity : AppCompatActivity() { DrmManagementContract.REQUEST_KEY, this, FragmentResultListener { _, result -> - if (DrmManagementContract.parseResult(result).hasReturned) + if (DrmManagementContract.parseResult(result).hasReturned) { finish() + } } ) @@ -165,7 +169,12 @@ open class ReaderActivity : AppCompatActivity() { private fun showOutlineFragment() { supportFragmentManager.commit { - add(R.id.activity_container, OutlineFragment::class.java, Bundle(), OUTLINE_FRAGMENT_TAG) + add( + R.id.activity_container, + OutlineFragment::class.java, + Bundle(), + OUTLINE_FRAGMENT_TAG + ) hide(readerFragment) addToBackStack(null) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivityContract.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivityContract.kt index 8a0a4d16f9..c0862ef8c7 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivityContract.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderActivityContract.kt @@ -30,8 +30,9 @@ class ReaderActivityContract : } override fun parseResult(resultCode: Int, intent: Intent?): Arguments? { - if (intent == null) + if (intent == null) { return null + } val extras = requireNotNull(intent.extras) return parseExtras(extras) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt index 45c35dcc95..c45c8ab13c 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderInitData.kt @@ -32,14 +32,14 @@ sealed class VisualReaderInitData( override val bookId: Long, override val publication: Publication, val initialLocation: Locator?, - val ttsInitData: TtsInitData?, + val ttsInitData: TtsInitData? ) : ReaderInitData() class ImageReaderInitData( bookId: Long, publication: Publication, initialLocation: Locator?, - ttsInitData: TtsInitData?, + ttsInitData: TtsInitData? ) : VisualReaderInitData(bookId, publication, initialLocation, ttsInitData) class EpubReaderInitData( @@ -48,7 +48,7 @@ class EpubReaderInitData( initialLocation: Locator?, val preferencesManager: PreferencesManager, val navigatorFactory: EpubNavigatorFactory, - ttsInitData: TtsInitData?, + ttsInitData: TtsInitData? ) : VisualReaderInitData(bookId, publication, initialLocation, ttsInitData) class PdfReaderInitData( @@ -57,13 +57,13 @@ class PdfReaderInitData( initialLocation: Locator?, val preferencesManager: PreferencesManager, val navigatorFactory: PdfNavigatorFactory, - ttsInitData: TtsInitData?, + ttsInitData: TtsInitData? ) : VisualReaderInitData(bookId, publication, initialLocation, ttsInitData) class TtsInitData( val mediaServiceFacade: MediaServiceFacade, val navigatorFactory: AndroidTtsNavigatorFactory, - val preferencesManager: PreferencesManager, + val preferencesManager: PreferencesManager ) class MediaReaderInitData( @@ -75,11 +75,11 @@ class MediaReaderInitData( ) : ReaderInitData() class DummyReaderInitData( - override val bookId: Long, + override val bookId: Long ) : ReaderInitData() { override val publication: Publication = Publication( Manifest( - metadata = Metadata(identifier = "dummy", localizedTitle = LocalizedString("")) + metadata = Metadata(identifier = "dummy") ) ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt index 4e3295baec..ff8ac63e83 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt @@ -25,6 +25,7 @@ import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.allAreHtml import org.readium.r2.shared.publication.services.isRestricted import org.readium.r2.shared.util.Url import org.readium.r2.testapp.PublicationError @@ -48,7 +49,7 @@ class ReaderRepository( private val application: Application, private val readium: Readium, private val bookRepository: BookRepository, - private val preferencesDataStore: DataStore, + private val preferencesDataStore: DataStore ) { sealed class OpeningError( content: Content, @@ -95,7 +96,9 @@ class ReaderRepository( val book = checkNotNull(bookRepository.get(bookId)) { "Cannot find book in database." } val asset = readium.assetRetriever.retrieve( - Url(book.href)!!, book.mediaType, book.assetType + Url(book.href)!!, + book.mediaType, + book.assetType ).getOrElse { return Try.failure(OpeningError.PublicationError(it)) } val publication = readium.publicationFactory.open( @@ -116,7 +119,7 @@ class ReaderRepository( val readerInitData = when { publication.conformsTo(Publication.Profile.AUDIOBOOK) -> openAudio(bookId, publication, initialLocator) - publication.conformsTo(Publication.Profile.EPUB) -> + publication.conformsTo(Publication.Profile.EPUB) || publication.readingOrder.allAreHtml -> openEpub(bookId, publication, initialLocator) publication.conformsTo(Publication.Profile.PDF) -> openPdf(bookId, publication, initialLocator) @@ -136,20 +139,23 @@ class ReaderRepository( publication: Publication, initialLocator: Locator? ): Try { - val preferencesManager = ExoPlayerPreferencesManagerFactory(preferencesDataStore) .createPreferenceManager(bookId) val initialPreferences = preferencesManager.preferences.value val navigatorFactory = AudioNavigatorFactory( publication, - ExoPlayerEngineProvider(application), - ) ?: return Try.failure(OpeningError.PublicationError(PublicationError.UnsupportedPublication())) + ExoPlayerEngineProvider(application) + ) ?: return Try.failure( + OpeningError.PublicationError(PublicationError.UnsupportedPublication()) + ) val navigator = navigatorFactory.createNavigator( initialLocator, initialPreferences - ) ?: return Try.failure(OpeningError.PublicationError(PublicationError.UnsupportedPublication())) + ) ?: return Try.failure( + OpeningError.PublicationError(PublicationError.UnsupportedPublication()) + ) mediaServiceFacade.openSession(bookId, navigator) val initData = MediaReaderInitData( @@ -167,15 +173,18 @@ class ReaderRepository( publication: Publication, initialLocator: Locator? ): Try { - val preferencesManager = EpubPreferencesManagerFactory(preferencesDataStore) .createPreferenceManager(bookId) val navigatorFactory = EpubNavigatorFactory(publication) val ttsInitData = getTtsInitData(bookId, publication) val initData = EpubReaderInitData( - bookId, publication, initialLocator, - preferencesManager, navigatorFactory, ttsInitData + bookId, + publication, + initialLocator, + preferencesManager, + navigatorFactory, + ttsInitData ) return Try.success(initData) } @@ -185,7 +194,6 @@ class ReaderRepository( publication: Publication, initialLocator: Locator? ): Try { - val preferencesManager = PdfiumPreferencesManagerFactory(preferencesDataStore) .createPreferenceManager(bookId) val pdfEngine = PdfiumEngineProvider() @@ -193,8 +201,11 @@ class ReaderRepository( val ttsInitData = getTtsInitData(bookId, publication) val initData = PdfReaderInitData( - bookId, publication, initialLocator, - preferencesManager, navigatorFactory, + bookId, + publication, + initialLocator, + preferencesManager, + navigatorFactory, ttsInitData ) return Try.success(initData) @@ -216,7 +227,7 @@ class ReaderRepository( private suspend fun getTtsInitData( bookId: Long, - publication: Publication, + publication: Publication ): TtsInitData? { val preferencesManager = AndroidTtsPreferencesManagerFactory(preferencesDataStore) .createPreferenceManager(bookId) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt index 30c0f9149f..e5fd45f596 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt @@ -43,7 +43,7 @@ import timber.log.Timber class ReaderViewModel( private val bookId: Long, private val readerRepository: ReaderRepository, - private val bookRepository: BookRepository, + private val bookRepository: BookRepository ) : ViewModel() { val readerInitData = @@ -145,15 +145,21 @@ class ReaderViewModel( createDecoration( idSuffix = "highlight", style = when (style) { - Highlight.Style.HIGHLIGHT -> Decoration.Style.Highlight(tint = tint, isActive = isActive) - Highlight.Style.UNDERLINE -> Decoration.Style.Underline(tint = tint, isActive = isActive) + Highlight.Style.HIGHLIGHT -> Decoration.Style.Highlight( + tint = tint, + isActive = isActive + ) + Highlight.Style.UNDERLINE -> Decoration.Style.Underline( + tint = tint, + isActive = isActive + ) } ), // Additional page margin icon decoration, if the highlight has an associated note. annotation.takeIf { it.isNotEmpty() }?.let { createDecoration( idSuffix = "annotation", - style = DecorationStyleAnnotationMark(tint = tint), + style = DecorationStyleAnnotationMark(tint = tint) ) } ) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt index c9dafa121f..4a8caa8d75 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt @@ -315,8 +315,11 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List val isUnderline = (decoration.style is Decoration.Style.Underline) showHighlightPopup( rect, - style = if (isUnderline) Highlight.Style.UNDERLINE - else Highlight.Style.HIGHLIGHT, + style = if (isUnderline) { + Highlight.Style.UNDERLINE + } else { + Highlight.Style.HIGHLIGHT + }, highlightId = id ) } @@ -337,7 +340,7 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List R.id.green to Color.rgb(173, 247, 123), R.id.blue to Color.rgb(124, 198, 247), R.id.yellow to Color.rgb(249, 239, 125), - R.id.purple to Color.rgb(182, 153, 255), + R.id.purple to Color.rgb(182, 153, 255) ) val customSelectionActionModeCallback: ActionMode.Callback by lazy { SelectionActionModeCallback() } @@ -537,10 +540,11 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List } fun updateSystemUiVisibility() { - if (navigatorFragment.isHidden) + if (navigatorFragment.isHidden) { requireActivity().showSystemUi() - else + } else { requireActivity().hideSystemUi() + } requireView().requestApplyInsets() } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt index 2ef0c025e9..d21e0919d2 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/PreferencesManagers.kt @@ -44,7 +44,7 @@ class PreferencesManager

    > internal constructor( val preferences: StateFlow

    , @Suppress("Unused") // Keep the scope alive until the PreferencesManager is garbage collected private val coroutineScope: CoroutineScope, - private val editPreferences: suspend (P) -> Unit, + private val editPreferences: suspend (P) -> Unit ) { suspend fun setPreferences(preferences: P) { @@ -116,7 +116,7 @@ sealed class PreferencesManagerFactory

    >( } class EpubPreferencesManagerFactory( - dataStore: DataStore, + dataStore: DataStore ) : PreferencesManagerFactory( dataStore = dataStore, klass = EpubPreferences::class, @@ -127,7 +127,7 @@ class EpubPreferencesManagerFactory( ) class PdfiumPreferencesManagerFactory( - dataStore: DataStore, + dataStore: DataStore ) : PreferencesManagerFactory( dataStore = dataStore, klass = PdfiumPreferences::class, diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt index 89f8ffcf35..79e1c2c1bd 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferences.kt @@ -123,7 +123,7 @@ private fun

    , E : PreferencesEditor

    > UserPref theme = editor.theme, typeScale = editor.typeScale, verticalText = editor.verticalText, - wordSpacing = editor.wordSpacing, + wordSpacing = editor.wordSpacing ) EpubLayout.FIXED -> FixedLayoutUserPreferences( @@ -131,7 +131,7 @@ private fun

    , E : PreferencesEditor

    > UserPref backgroundColor = editor.backgroundColor, language = editor.language, readingProgression = editor.readingProgression, - spread = editor.spread, + spread = editor.spread ) } is TtsPreferencesEditor -> @@ -265,7 +265,7 @@ private fun FixedLayoutUserPreferences( ButtonGroupItem( title = "Spread", preference = spread, - commit = commit, + commit = commit ) { value -> when (value) { Spread.AUTO -> "Auto" @@ -337,7 +337,7 @@ private fun ReflowableUserPreferences( theme: EnumPreference? = null, typeScale: RangePreference? = null, verticalText: Preference? = null, - wordSpacing: RangePreference? = null, + wordSpacing: RangePreference? = null ) { if (language != null || readingProgression != null || verticalText != null) { if (language != null) { @@ -368,7 +368,6 @@ private fun ReflowableUserPreferences( } if (scroll != null || columnCount != null || pageMargins != null) { - if (scroll != null) { SwitchItem( title = "Scroll", @@ -381,7 +380,7 @@ private fun ReflowableUserPreferences( ButtonGroupItem( title = "Columns", preference = columnCount, - commit = commit, + commit = commit ) { value -> when (value) { ColumnCount.AUTO -> "Auto" @@ -403,7 +402,6 @@ private fun ReflowableUserPreferences( } if (theme != null || textColor != null || imageFilter != null) { - if (theme != null) { ButtonGroupItem( title = "Theme", @@ -505,7 +503,7 @@ private fun ReflowableUserPreferences( SwitchItem( title = "Publisher styles", preference = publisherStyles, - commit = commit, + commit = commit ) if (!(publisherStyles.value ?: publisherStyles.effectiveValue)) { @@ -603,7 +601,7 @@ private fun Divider() { private fun PresetsMenuButton( presets: List, clear: () -> Unit, - commit: () -> Unit, + commit: () -> Unit ) { if (presets.isEmpty()) return diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt index 0659661d54..76afae1c26 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/preferences/UserPreferencesViewModel.kt @@ -67,19 +67,25 @@ class UserPreferencesViewModel with(readerInitData) { UserPreferencesViewModel( - viewModelScope, bookId, preferencesManager, + viewModelScope, + bookId, + preferencesManager, createPreferencesEditor = navigatorFactory::createPreferencesEditor ) } is PdfReaderInitData -> with(readerInitData) { UserPreferencesViewModel( - viewModelScope, bookId, preferencesManager, + viewModelScope, + bookId, + preferencesManager, createPreferencesEditor = navigatorFactory::createPreferencesEditor ) } is MediaReaderInitData -> with(readerInitData) { UserPreferencesViewModel( - viewModelScope, bookId, preferencesManager, + viewModelScope, + bookId, + preferencesManager, createPreferencesEditor = navigatorFactory::createAudioPreferencesEditor ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt index 445080b1a6..141360df69 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsControls.kt @@ -57,39 +57,45 @@ fun TtsControls( onPrevious: () -> Unit, onNext: () -> Unit, onPreferences: () -> Unit, - modifier: Modifier = Modifier, + modifier: Modifier = Modifier ) { Card( modifier = modifier ) { Row( horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { val largeButtonModifier = Modifier.size(40.dp) IconButton(onClick = onPrevious) { Icon( imageVector = Icons.Default.SkipPrevious, - contentDescription = stringResource(R.string.tts_previous), + contentDescription = stringResource(R.string.tts_previous) ) } IconButton( - onClick = onPlayPause, + onClick = onPlayPause ) { Icon( - imageVector = if (playing) Icons.Default.Pause - else Icons.Default.PlayArrow, + imageVector = if (playing) { + Icons.Default.Pause + } else { + Icons.Default.PlayArrow + }, contentDescription = stringResource( - if (playing) R.string.tts_pause - else R.string.tts_play + if (playing) { + R.string.tts_pause + } else { + R.string.tts_play + } ), modifier = Modifier.then(largeButtonModifier) ) } IconButton( - onClick = onStop, + onClick = onStop ) { Icon( imageVector = Icons.Default.Stop, diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt index 52e246fac0..d7de208352 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/tts/TtsViewModel.kt @@ -47,7 +47,7 @@ class TtsViewModel private constructor( private val publication: Publication, private val ttsNavigatorFactory: AndroidTtsNavigatorFactory, private val mediaServiceFacade: MediaServiceFacade, - private val preferencesManager: PreferencesManager, + private val preferencesManager: PreferencesManager ) : TtsNavigator.Listener { companion object { @@ -57,7 +57,7 @@ class TtsViewModel private constructor( */ operator fun invoke( viewModelScope: CoroutineScope, - readerInitData: ReaderInitData, + readerInitData: ReaderInitData ): TtsViewModel? { if (readerInitData !is VisualReaderInitData || readerInitData.ttsInitData == null) { return null @@ -161,8 +161,9 @@ class TtsViewModel private constructor( */ fun start(navigator: Navigator) { viewModelScope.launch { - if (mediaServiceFacade.session.value != null) + if (mediaServiceFacade.session.value != null) { return@launch + } openSession(navigator) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/search/SearchResultAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/search/SearchResultAdapter.kt index 8e51753244..84adb7c232 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/search/SearchResultAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/search/SearchResultAdapter.kt @@ -27,7 +27,9 @@ class SearchResultAdapter(private var listener: Listener) : override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return ViewHolder( ItemRecycleSearchBinding.inflate( - LayoutInflater.from(parent.context), parent, false + LayoutInflater.from(parent.context), + parent, + false ) ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt b/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt index f4ad6a7c98..115618a28f 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/shared/views/Preferences.kt @@ -79,7 +79,7 @@ private fun ButtonGroupItem( selectedOption: T?, formatValue: (T) -> String, onClear: (() -> Unit)?, - onSelectedOptionChanged: (T) -> Unit, + onSelectedOptionChanged: (T) -> Unit ) { Item(title, isActive = isActive, onClear = onClear) { ToggleButtonGroup( @@ -174,7 +174,7 @@ fun > StepperItem( onDecrement = { preference.decrement(); commit() }, onIncrement = { preference.increment(); commit() }, onClear = { preference.clear(); commit() } - .takeIf { preference.value != null }, + .takeIf { preference.value != null } ) } @@ -235,7 +235,7 @@ fun SwitchItem( onCheckedChange = { preference.set(it); commit() }, onToggle = { preference.toggle(); commit() }, onClear = { preference.clear(); commit() } - .takeIf { preference.value != null }, + .takeIf { preference.value != null } ) } @@ -378,8 +378,11 @@ private fun Item( ) { ListItem( modifier = - if (onClick != null) Modifier.clickable(onClick = onClick) - else Modifier, + if (onClick != null) { + Modifier.clickable(onClick = onClick) + } else { + Modifier + }, text = { val alpha = if (isActive) 1.0f else ContentAlpha.disabled CompositionLocalProvider(LocalContentAlpha provides alpha) { @@ -432,7 +435,7 @@ private fun SelectorListItem( selection: T, formatValue: (T) -> String, onSelected: (T) -> Unit, - enabled: Boolean = values.isNotEmpty(), + enabled: Boolean = values.isNotEmpty() ) { var isExpanded by remember { mutableStateOf(false) } fun dismiss() { isExpanded = false } diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/ContentResolverUtil.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/ContentResolverUtil.kt index 635512a58b..035d8080a0 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/ContentResolverUtil.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/ContentResolverUtil.kt @@ -74,7 +74,8 @@ object ContentResolverUtil { } return try { val contentUri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id) + Uri.parse("content://downloads/public_downloads"), + java.lang.Long.valueOf(id) ) getDataColumn(context, contentUri, null, null) } catch (e: NumberFormatException) { @@ -99,7 +100,6 @@ object ContentResolverUtil { return getDataColumn(context, contentUri, selection, selectionArgs) } } else if ("content".equals(uri.scheme!!, ignoreCase = true)) { - // Return the remote address return getDataColumn(context, uri, null, null) } else if ("file".equals(uri.scheme!!, ignoreCase = true)) { @@ -125,7 +125,6 @@ object ContentResolverUtil { selection: String?, selectionArgs: Array? ): String? { - val column = "_data" val projection = arrayOf(column) context.contentResolver.query(uri!!, projection, selection, selectionArgs, null).use { cursor -> diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/SectionDecoration.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/SectionDecoration.kt index bcf41ab96b..d3feb40aa4 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/SectionDecoration.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/SectionDecoration.kt @@ -78,9 +78,20 @@ class SectionDecoration( private fun fixLayoutSize(v: View, parent: ViewGroup) { val widthSpec = View.MeasureSpec.makeMeasureSpec(parent.width, View.MeasureSpec.EXACTLY) - val heightSpec = View.MeasureSpec.makeMeasureSpec(parent.height, View.MeasureSpec.UNSPECIFIED) - val childWidth = ViewGroup.getChildMeasureSpec(widthSpec, parent.paddingStart + parent.paddingEnd, v.layoutParams.width) - val childHeight = ViewGroup.getChildMeasureSpec(heightSpec, parent.paddingTop + parent.paddingBottom, v.layoutParams.height) + val heightSpec = View.MeasureSpec.makeMeasureSpec( + parent.height, + View.MeasureSpec.UNSPECIFIED + ) + val childWidth = ViewGroup.getChildMeasureSpec( + widthSpec, + parent.paddingStart + parent.paddingEnd, + v.layoutParams.width + ) + val childHeight = ViewGroup.getChildMeasureSpec( + heightSpec, + parent.paddingTop + parent.paddingBottom, + v.layoutParams.height + ) v.measure(childWidth, childHeight) v.layout(0, 0, v.measuredWidth, v.measuredHeight) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/SystemUiManagement.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/SystemUiManagement.kt index 52cd7eb77f..9a1e1129ab 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/SystemUiManagement.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/SystemUiManagement.kt @@ -20,8 +20,8 @@ private fun Activity.isSystemUiVisible(): Boolean { } // Using ViewCompat and WindowInsetsCompat does not work properly in all versions of Android -@Suppress("DEPRECATION") /** Enable fullscreen or immersive mode. */ +@Suppress("DEPRECATION") fun Activity.hideSystemUi() { this.window.decorView.systemUiVisibility = ( View.SYSTEM_UI_FLAG_IMMERSIVE @@ -34,8 +34,8 @@ fun Activity.hideSystemUi() { } // Using ViewCompat and WindowInsetsCompat does not work properly in all versions of Android -@Suppress("DEPRECATION") /** Disable fullscreen or immersive mode. */ +@Suppress("DEPRECATION") fun Activity.showSystemUi() { this.window.decorView.systemUiVisibility = ( View.SYSTEM_UI_FLAG_LAYOUT_STABLE diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ColorPicker.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ColorPicker.kt index 5f0ab20c5a..7c3ed2aaff 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ColorPicker.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ColorPicker.kt @@ -36,7 +36,7 @@ fun ColorPicker(onPick: (Int) -> Unit) { // Yellow listOf("#fff9c4", "#fff176", "#ffeb3b", "#fbc02d", "#f57f17"), // Orange - listOf("#ffe0b2", "#ffb74d", "#ff9800", "#f57c00", "#e65100"), + listOf("#ffe0b2", "#ffb74d", "#ff9800", "#f57c00", "#e65100") ) Column { diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ComposeBottomSheetDialogFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ComposeBottomSheetDialogFragment.kt index 79980ac278..5be07bbc52 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ComposeBottomSheetDialogFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ComposeBottomSheetDialogFragment.kt @@ -43,11 +43,13 @@ abstract class ComposeBottomSheetDialogFragment( composeView, FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT ) ) } - } else composeView + } else { + composeView + } } @Composable diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/DropdownMenuButton.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/DropdownMenuButton.kt index 53756cf02b..a71ee3a612 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/DropdownMenuButton.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/DropdownMenuButton.kt @@ -21,7 +21,7 @@ fun DropdownMenuButton( fun dismiss() { isExpanded = false } OutlinedButton( - onClick = { isExpanded = true }, + onClick = { isExpanded = true } ) { text() DropdownMenu( diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ToggleButton.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ToggleButton.kt index 06aecf18e7..5d658515ca 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ToggleButton.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/compose/ToggleButton.kt @@ -69,8 +69,11 @@ fun ToggleButton( } ), elevation = - if (selected) ButtonDefaults.elevation(defaultElevation = 2.dp) - else null + if (selected) { + ButtonDefaults.elevation(defaultElevation = 2.dp) + } else { + null + } ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt index 4ea3218703..5de0346cee 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt @@ -17,17 +17,22 @@ import java.net.URL import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ensureActive import kotlinx.coroutines.withContext +import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.error.Try import org.readium.r2.shared.error.flatMap -import org.readium.r2.shared.util.http.* +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.http.HttpException +import org.readium.r2.shared.util.http.HttpRequest +import org.readium.r2.shared.util.http.HttpResponse +import org.readium.r2.shared.util.http.HttpTry import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.testapp.BuildConfig import timber.log.Timber suspend fun File.moveTo(target: File) = withContext(Dispatchers.IO) { - if (!this@moveTo.renameTo(target)) + if (!this@moveTo.renameTo(target)) { throw IOException() + } } /** @@ -41,35 +46,18 @@ fun File.listFilesSafely(filter: FileFilter? = null): List { suspend fun URL.downloadTo( dest: File, - maxRedirections: Int = 2 + httpClient: HttpClient, + assetRetriever: AssetRetriever ): Try { - if (maxRedirections == 0) { - return Try.Failure(Exception("Too many HTTP redirections.")) - } - - val urlString = toString() - - if (BuildConfig.DEBUG) Timber.i("download url $urlString") - return DefaultHttpClient().download(HttpRequest(toString()), dest, MediaTypeRetriever()) - .flatMap { - try { - if (BuildConfig.DEBUG) Timber.i("response url ${it.url}") - if (BuildConfig.DEBUG) Timber.i("download destination ${dest.path}") - if (urlString == it.url) { - Try.success(Unit) - } else { - URL(it.url).downloadTo(dest, maxRedirections - 1) - } - } catch (e: Exception) { - Try.failure(e) - } - } + if (BuildConfig.DEBUG) Timber.i("download url $this") + return httpClient.download(HttpRequest(toString()), dest, assetRetriever) + .map { } } private suspend fun HttpClient.download( request: HttpRequest, destination: File, - mediaTypeRetriever: MediaTypeRetriever + assetRetriever: AssetRetriever ): HttpTry = try { stream(request).flatMap { res -> @@ -88,9 +76,9 @@ private suspend fun HttpClient.download( } var response = res.response if (response.mediaType.matches(MediaType.BINARY)) { - response = response.copy( - mediaType = mediaTypeRetriever.retrieve(destination) ?: response.mediaType - ) + assetRetriever.retrieve(destination)?.mediaType?.let { + response = response.copy(mediaType = it) + } } Try.success(response) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt index e3f672035c..3b02e3da19 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt @@ -6,22 +6,46 @@ package org.readium.r2.testapp.utils.extensions +import android.content.ContentResolver import android.content.Context import android.net.Uri +import android.provider.MediaStore import java.io.File import java.util.* import org.readium.r2.shared.error.Try import org.readium.r2.testapp.utils.ContentResolverUtil +import org.readium.r2.testapp.utils.tryOrNull suspend fun Uri.copyToTempFile(context: Context, dir: File): Try = try { val filename = UUID.randomUUID().toString() - val extension = path - ?.let { File(it).extension } - ?: "tmp" - val file = File(dir, "$filename.$extension") + val file = File(dir, "$filename.${extension(context)}") ContentResolverUtil.getContentInputStream(context, this, file) Try.success(file) } catch (e: Exception) { Try.failure(e) } + +private fun Uri.extension(context: Context): String? { + if (scheme == ContentResolver.SCHEME_CONTENT) { + tryOrNull { + context.contentResolver.queryProjection(this, MediaStore.MediaColumns.DISPLAY_NAME) + ?.let { filename -> + File(filename).extension + .takeUnless { it.isBlank() } + } + }?.let { return it } + } + + return path?.let { File(it).extension } +} + +private fun ContentResolver.queryProjection(uri: Uri, projection: String): String? = + tryOrNull { + query(uri, arrayOf(projection), null, null, null)?.use { cursor -> + if (cursor.moveToFirst()) { + return cursor.getString(0) + } + return null + } + } diff --git a/test-app/src/main/res/values/arrays.xml b/test-app/src/main/res/values/arrays.xml index 500d03ecaa..8cb4f5dc9a 100644 --- a/test-app/src/main/res/values/arrays.xml +++ b/test-app/src/main/res/values/arrays.xml @@ -1,9 +1,9 @@ - Import to app storage - Add from shared storage - Add from the Web + Copy to app storage + Read from shared storage + Stream from the Web \ No newline at end of file From 372120c784a31ee2fe4b1d3258f02378734b2e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Tue, 22 Aug 2023 16:33:28 +0200 Subject: [PATCH 23/65] Move `Try` back into `util` package (#378) --- .../pdfium/document/PdfiumDocument.kt | 2 +- .../pspdfkit/document/ResourceDataProvider.kt | 2 +- .../readium/r2/lcp/LcpContentProtection.kt | 8 ++--- .../java/org/readium/r2/lcp/LcpDecryptor.kt | 6 ++-- .../org/readium/r2/lcp/LcpDecryptorTest.kt | 4 +-- .../java/org/readium/r2/lcp/LcpLicense.kt | 2 +- .../java/org/readium/r2/lcp/LcpService.kt | 2 +- .../org/readium/r2/lcp/license/License.kt | 6 ++-- .../r2/lcp/license/LicenseValidation.kt | 2 +- .../container/ContainerLicenseContainer.kt | 2 +- .../container/LcplResourceLicenseContainer.kt | 2 +- .../org/readium/r2/lcp/service/CRLService.kt | 2 +- .../readium/r2/lcp/service/LicensesService.kt | 2 +- .../readium/r2/lcp/service/NetworkService.kt | 2 +- .../navigator/media2/ExoPlayerDataSource.kt | 2 +- .../navigator/media2/MediaNavigator.kt | 4 +-- .../navigator/media2/SessionPlayerFacade.kt | 4 +-- .../navigator/media2/SessionPlayerHelpers.kt | 2 +- .../readium/r2/navigator/R2BasicWebView.kt | 2 +- .../navigator/audio/PublicationDataSource.kt | 2 +- .../readium/r2/navigator/epub/HtmlInjector.kt | 4 +-- .../r2/navigator/epub/WebViewServer.kt | 2 +- .../media3/audio/MetadataRetriever.kt | 2 +- .../media3/exoplayer/ExoPlayerDataSource.kt | 2 +- .../java/org/readium/r2/opds/OPDS1Parser.kt | 2 +- .../java/org/readium/r2/opds/OPDS2Parser.kt | 2 +- .../readium/r2/shared/asset/AssetRetriever.kt | 26 ++++++++-------- .../r2/shared/publication/Publication.kt | 6 ++-- .../AdeptFallbackContentProtection.kt | 2 +- .../protection/ContentProtection.kt | 2 +- .../LcpFallbackContentProtection.kt | 2 +- .../services/ContentProtectionService.kt | 2 +- .../publication/services/PositionsService.kt | 2 +- .../iterators/HtmlResourceContentIterator.kt | 2 +- .../services/search/SearchService.kt | 2 +- .../services/search/StringSearchService.kt | 4 +-- .../r2/shared/resource/BufferingResource.kt | 2 +- .../r2/shared/resource/BytesResource.kt | 2 +- .../r2/shared/resource/ContentResource.kt | 2 +- .../shared/resource/DefaultArchiveFactory.kt | 4 +-- .../r2/shared/resource/DirectoryContainer.kt | 2 +- .../readium/r2/shared/resource/Factories.kt | 30 +++++++++---------- .../r2/shared/resource/FileChannelResource.kt | 2 +- .../r2/shared/resource/FileResource.kt | 4 +-- .../readium/r2/shared/resource/Resource.kt | 4 +-- .../r2/shared/resource/ResourceInputStream.kt | 2 +- .../shared/resource/TransformingResource.kt | 2 +- .../r2/shared/resource/ZipContainer.kt | 4 +-- .../content/ResourceContentExtractor.kt | 2 +- .../org/readium/r2/shared/util/Deprecated.kt | 2 -- .../r2/shared/{error => util}/Error.kt | 2 +- .../readium/r2/shared/{error => util}/Try.kt | 2 +- .../archive/channel/ChannelZipContainer.kt | 4 +-- .../util/archive/channel/HttpChannel.kt | 4 +-- .../util/archive/channel/ResourceChannel.kt | 4 +-- .../r2/shared/util/http/DefaultHttpClient.kt | 6 ++-- .../readium/r2/shared/util/http/HttpClient.kt | 4 +-- .../r2/shared/util/http/HttpException.kt | 2 +- .../r2/shared/util/http/HttpResource.kt | 4 +-- .../shared/util/http/HttpResourceFactory.kt | 2 +- .../publication/protection/TestContainer.kt | 2 +- .../r2/shared/resource/ZipContainerTest.kt | 2 +- .../readium/r2/streamer/ParserAssetFactory.kt | 10 +++---- .../readium/r2/streamer/PublicationFactory.kt | 4 +-- .../r2/streamer/parser/PublicationParser.kt | 16 +++++----- .../r2/streamer/parser/audio/AudioParser.kt | 2 +- .../r2/streamer/parser/epub/EpubParser.kt | 4 +-- .../r2/streamer/parser/image/ImageParser.kt | 2 +- .../r2/streamer/parser/pdf/PdfParser.kt | 2 +- .../parser/readium/ReadiumWebPubParser.kt | 4 +-- .../parser/epub/EpubDeobfuscatorTest.kt | 2 +- .../parser/epub/EpubPositionsServiceTest.kt | 2 +- .../readium/r2/testapp/PublicationError.kt | 2 +- .../java/org/readium/r2/testapp/Readium.kt | 2 +- .../r2/testapp/bookshelf/BookRepository.kt | 6 ++-- .../catalogs/CatalogFeedListViewModel.kt | 2 +- .../r2/testapp/catalogs/CatalogViewModel.kt | 4 +-- .../r2/testapp/drm/DrmManagementViewModel.kt | 2 +- .../r2/testapp/drm/LcpManagementViewModel.kt | 2 +- .../r2/testapp/reader/ReaderRepository.kt | 4 +-- .../r2/testapp/reader/ReaderViewModel.kt | 2 +- .../r2/testapp/search/SearchPagingSource.kt | 2 +- .../r2/testapp/utils/extensions/File.kt | 4 +-- .../r2/testapp/utils/extensions/Uri.kt | 2 +- 84 files changed, 153 insertions(+), 155 deletions(-) rename readium/shared/src/main/java/org/readium/r2/shared/{error => util}/Error.kt (96%) rename readium/shared/src/main/java/org/readium/r2/shared/{error => util}/Try.kt (99%) diff --git a/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt b/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt index 9369c2d827..5cad45420f 100644 --- a/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt +++ b/readium/adapters/pdfium/pdfium-document/src/main/java/org/readium/adapters/pdfium/document/PdfiumDocument.kt @@ -16,10 +16,10 @@ import kotlin.reflect.KClass import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.InternalReadiumApi -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.md5 import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.pdf.PdfDocument import org.readium.r2.shared.util.pdf.PdfDocumentFactory import org.readium.r2.shared.util.toFile diff --git a/readium/adapters/pspdfkit/pspdfkit-document/src/main/java/org/readium/adapters/pspdfkit/document/ResourceDataProvider.kt b/readium/adapters/pspdfkit/pspdfkit-document/src/main/java/org/readium/adapters/pspdfkit/document/ResourceDataProvider.kt index d84eef4d25..679b811d7d 100644 --- a/readium/adapters/pspdfkit/pspdfkit-document/src/main/java/org/readium/adapters/pspdfkit/document/ResourceDataProvider.kt +++ b/readium/adapters/pspdfkit/pspdfkit-document/src/main/java/org/readium/adapters/pspdfkit/document/ResourceDataProvider.kt @@ -9,9 +9,9 @@ package org.readium.adapters.pspdfkit.document import com.pspdfkit.document.providers.DataProvider import java.util.* import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.synchronized +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.isLazyInitialized import timber.log.Timber diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt index 9b713ab0fe..c42d03cc05 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt @@ -11,10 +11,6 @@ import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.asset.AssetType -import org.readium.r2.shared.error.ThrowableError -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.encryption.encryption import org.readium.r2.shared.publication.flatten @@ -24,7 +20,11 @@ import org.readium.r2.shared.resource.ArchiveFactory import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceFactory import org.readium.r2.shared.resource.TransformingContainer +import org.readium.r2.shared.util.ThrowableError +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.toFile internal class LcpContentProtection( diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt index 5c91e20432..5eef7fd033 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptor.kt @@ -10,9 +10,6 @@ package org.readium.r2.lcp import java.io.IOException -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.coerceFirstNonNegative import org.readium.r2.shared.extensions.inflate import org.readium.r2.shared.extensions.requireLengthFitInt @@ -25,7 +22,10 @@ import org.readium.r2.shared.resource.TransformingResource import org.readium.r2.shared.resource.flatMap import org.readium.r2.shared.resource.flatMapCatching import org.readium.r2.shared.resource.mapCatching +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.getOrThrow /** * Decrypts a resource protected with LCP. diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt index 4f6b4b8772..667ace86fc 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDecryptorTest.kt @@ -10,12 +10,12 @@ package org.readium.r2.lcp import kotlin.math.ceil -import org.readium.r2.shared.error.getOrElse -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.coerceIn import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.mapCatching +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.use import timber.log.Timber diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt index a5afd352f7..79e58ce04f 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpLicense.kt @@ -15,8 +15,8 @@ import kotlinx.coroutines.runBlocking import org.joda.time.DateTime import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.lcp.license.model.StatusDocument -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.services.ContentProtectionService +import org.readium.r2.shared.util.Try import timber.log.Timber /** diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt index 61d9a27582..c8ca96938b 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt @@ -30,8 +30,8 @@ import org.readium.r2.lcp.service.PassphrasesRepository import org.readium.r2.lcp.service.PassphrasesService import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.asset.AssetRetriever -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt index 9975dad291..61d2a30233 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/License.kt @@ -25,11 +25,11 @@ import org.readium.r2.lcp.service.DeviceService import org.readium.r2.lcp.service.LcpClient import org.readium.r2.lcp.service.LicensesRepository import org.readium.r2.lcp.service.NetworkService -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.toIso8601String import org.readium.r2.shared.extensions.tryOrNull +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt index 32227057f7..f028835daf 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/LicenseValidation.kt @@ -23,7 +23,7 @@ import org.readium.r2.lcp.service.DeviceService import org.readium.r2.lcp.service.LcpClient import org.readium.r2.lcp.service.NetworkService import org.readium.r2.lcp.service.PassphrasesService -import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt index 70d9d5e45d..abe514bcf5 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt @@ -9,9 +9,9 @@ package org.readium.r2.lcp.license.container import kotlinx.coroutines.runBlocking import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.license.model.LicenseDocument -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.getOrThrow /** * Access to a License Document stored in a read-only container. diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt index 6277b4a003..e5ea792fee 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt @@ -12,8 +12,8 @@ package org.readium.r2.lcp.license.container import kotlinx.coroutines.runBlocking import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.license.model.LicenseDocument -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.getOrThrow /** * Access a License Document stored in an LCP License Document file (LCPL) readable through a diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt index 176331767c..c183fe4bcc 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt @@ -18,7 +18,7 @@ import org.joda.time.DateTime import org.joda.time.Days import org.readium.r2.lcp.BuildConfig.DEBUG import org.readium.r2.lcp.LcpException -import org.readium.r2.shared.error.getOrElse +import org.readium.r2.shared.util.getOrElse import timber.log.Timber @OptIn(ExperimentalTime::class) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index b0e0b6d78a..049e87f044 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -31,9 +31,9 @@ import org.readium.r2.lcp.license.container.createLicenseContainer import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.asset.AssetRetriever -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.tryOr import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt index cae98e3152..51fa440403 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/NetworkService.kt @@ -20,7 +20,7 @@ import kotlin.time.Duration import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.lcp.LcpException -import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.invoke import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeHints diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt index 24be368a33..3a1195cead 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/ExoPlayerDataSource.kt @@ -18,10 +18,10 @@ import com.google.android.exoplayer2.upstream.DataSpec import com.google.android.exoplayer2.upstream.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.buffered +import org.readium.r2.shared.util.getOrThrow public sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException( message, diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt index 8b6cc4f60f..4c5529855d 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/MediaNavigator.kt @@ -34,12 +34,12 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.readium.navigator.media2.MediaNavigator.Companion.create import org.readium.r2.navigator.Navigator -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.indexOfFirstWithHref +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.flatMap import timber.log.Timber /** diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt index 5a267e6c78..a8853c2e33 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerFacade.kt @@ -26,8 +26,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.flatMap import timber.log.Timber /** diff --git a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt index 7941b5e349..c2b76af0fe 100644 --- a/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt +++ b/readium/navigator-media2/src/main/java/org/readium/navigator/media2/SessionPlayerHelpers.kt @@ -12,7 +12,7 @@ import androidx.media2.common.SessionPlayer import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlin.time.ExperimentalTime -import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.Try internal enum class SessionPlayerState { Idle, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt index 4034ac1942..5bc29a0ad4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt @@ -41,7 +41,6 @@ import org.readium.r2.navigator.input.KeyEvent import org.readium.r2.navigator.preferences.ReadingProgression import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.InternalReadiumApi -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.optNullableString import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.extensions.tryOrNull @@ -50,6 +49,7 @@ import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.use import timber.log.Timber diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt index 2ccdf23ce4..36389997e6 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/audio/PublicationDataSource.kt @@ -18,10 +18,10 @@ import com.google.android.exoplayer2.upstream.DataSpec import com.google.android.exoplayer2.upstream.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.buffered +import org.readium.r2.shared.util.getOrThrow internal sealed class PublicationDataSourceException(message: String, cause: Throwable?) : IOException( message, diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt index 3fcb00034c..fb5b32b4c0 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/HtmlInjector.kt @@ -8,8 +8,6 @@ package org.readium.r2.navigator.epub import org.readium.r2.navigator.epub.css.ReadiumCss import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.epub.EpubLayout import org.readium.r2.shared.publication.presentation.presentation @@ -17,6 +15,8 @@ import org.readium.r2.shared.publication.services.isProtected import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.resource.TransformingResource +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.getOrElse import timber.log.Timber /** diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt index e223348c0c..06730a39eb 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/WebViewServer.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.navigator.epub.css.ReadiumCss import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource @@ -24,6 +23,7 @@ import org.readium.r2.shared.resource.ResourceInputStream import org.readium.r2.shared.resource.StringResource import org.readium.r2.shared.resource.fallback import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.HttpHeaders import org.readium.r2.shared.util.http.HttpRange import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt index 18db248abe..9d38b0711a 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/audio/MetadataRetriever.kt @@ -15,9 +15,9 @@ import java.io.IOException import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.getOrThrow @RequiresApi(Build.VERSION_CODES.M) internal class MetadataRetriever( diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt index 7d20db4ebe..ac9cfcc24c 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/exoplayer/ExoPlayerDataSource.kt @@ -15,10 +15,10 @@ import androidx.media3.datasource.DataSpec import androidx.media3.datasource.TransferListener import java.io.IOException import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.buffered +import org.readium.r2.shared.util.getOrThrow public sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException( message, diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt index 4c15ad1da9..81eaafaa45 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS1Parser.kt @@ -11,7 +11,6 @@ package org.readium.r2.opds import java.net.URL import org.joda.time.DateTime -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.toList import org.readium.r2.shared.extensions.toMap import org.readium.r2.shared.opds.* @@ -20,6 +19,7 @@ import org.readium.r2.shared.parser.xml.XmlParser import org.readium.r2.shared.publication.* import org.readium.r2.shared.toJSON import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpRequest diff --git a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt index b7c137af48..3e077af7a9 100644 --- a/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt +++ b/readium/opds/src/main/java/org/readium/r2/opds/OPDS2Parser.kt @@ -13,7 +13,6 @@ import java.net.URL import org.joda.time.DateTime import org.json.JSONArray import org.json.JSONObject -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.removeLastComponent import org.readium.r2.shared.opds.Facet import org.readium.r2.shared.opds.Feed @@ -24,6 +23,7 @@ import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpRequest diff --git a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt index 3397366111..15833d2336 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt @@ -11,10 +11,6 @@ import android.content.Context import android.net.Uri import android.provider.MediaStore import java.io.File -import org.readium.r2.shared.error.ThrowableError -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.extensions.queryProjection import org.readium.r2.shared.resource.ArchiveFactory import org.readium.r2.shared.resource.Container @@ -27,7 +23,11 @@ import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceFactory import org.readium.r2.shared.resource.ResourceMediaTypeSnifferContent import org.readium.r2.shared.util.Either +import org.readium.r2.shared.util.ThrowableError +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeHints import org.readium.r2.shared.util.mediatype.MediaTypeRetriever @@ -58,11 +58,11 @@ public class AssetRetriever( } } - public sealed class Error : org.readium.r2.shared.error.Error { + public sealed class Error : org.readium.r2.shared.util.Error { public class SchemeNotSupported( public val scheme: String, - override val cause: org.readium.r2.shared.error.Error? + override val cause: org.readium.r2.shared.util.Error? ) : Error() { public constructor(scheme: String, exception: Exception) : @@ -74,7 +74,7 @@ public class AssetRetriever( public class NotFound( public val url: Url, - override val cause: org.readium.r2.shared.error.Error? + override val cause: org.readium.r2.shared.util.Error? ) : Error() { public constructor(url: Url, exception: Exception) : @@ -85,7 +85,7 @@ public class AssetRetriever( } public class InvalidAsset( - override val cause: org.readium.r2.shared.error.Error? + override val cause: org.readium.r2.shared.util.Error? ) : Error() { public constructor(exception: Exception) : @@ -96,7 +96,7 @@ public class AssetRetriever( } public class ArchiveFormatNotSupported( - override val cause: org.readium.r2.shared.error.Error? + override val cause: org.readium.r2.shared.util.Error? ) : Error() { public constructor(exception: Exception) : @@ -108,7 +108,7 @@ public class AssetRetriever( public class Forbidden( public val url: Url, - override val cause: org.readium.r2.shared.error.Error + override val cause: org.readium.r2.shared.util.Error ) : Error() { public constructor(url: Url, exception: Exception) : @@ -119,7 +119,7 @@ public class AssetRetriever( } public class Unavailable( - override val cause: org.readium.r2.shared.error.Error + override val cause: org.readium.r2.shared.util.Error ) : Error() { public constructor(exception: Exception) : @@ -136,7 +136,7 @@ public class AssetRetriever( override val message: String = "There is not enough memory on the device to load the asset." - override val cause: org.readium.r2.shared.error.Error = + override val cause: org.readium.r2.shared.util.Error = ThrowableError(error) } @@ -147,7 +147,7 @@ public class AssetRetriever( override val message: String = exception.message ?: "Something unexpected happened." - override val cause: org.readium.r2.shared.error.Error = + override val cause: org.readium.r2.shared.util.Error = ThrowableError(exception) } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt index eba3934190..c2ef21df93 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Publication.kt @@ -16,9 +16,6 @@ import kotlinx.parcelize.Parcelize import org.json.JSONObject import org.readium.r2.shared.* import org.readium.r2.shared.BuildConfig.DEBUG -import org.readium.r2.shared.error.Error -import org.readium.r2.shared.error.MessageError -import org.readium.r2.shared.error.ThrowableError import org.readium.r2.shared.extensions.* import org.readium.r2.shared.extensions.removeLastComponent import org.readium.r2.shared.publication.epub.listOfAudioClips @@ -38,6 +35,9 @@ import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.resource.fallback import org.readium.r2.shared.util.Closeable +import org.readium.r2.shared.util.Error +import org.readium.r2.shared.util.MessageError +import org.readium.r2.shared.util.ThrowableError import org.readium.r2.shared.util.mediatype.MediaType internal typealias ServiceFactory = (Publication.Service.Context) -> Publication.Service? diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt index a3e974d8c0..bbbd2c1f4d 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/AdeptFallbackContentProtection.kt @@ -8,13 +8,13 @@ package org.readium.r2.shared.publication.protection import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.asset.Asset -import org.readium.r2.shared.error.Try import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.protection.ContentProtection.Scheme import org.readium.r2.shared.publication.services.contentProtectionServiceFactory import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsXml +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt index 86275c3a03..7af2ee8220 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/ContentProtection.kt @@ -12,11 +12,11 @@ package org.readium.r2.shared.publication.protection import androidx.annotation.StringRes import org.readium.r2.shared.R import org.readium.r2.shared.UserException -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.LocalizedString import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.ContentProtectionService import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt index f96ec028ec..63c69610fb 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/protection/LcpFallbackContentProtection.kt @@ -9,7 +9,6 @@ package org.readium.r2.shared.publication.protection import org.json.JSONObject import org.readium.r2.shared.InternalReadiumApi import org.readium.r2.shared.asset.Asset -import org.readium.r2.shared.error.Try import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication @@ -20,6 +19,7 @@ import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsJson import org.readium.r2.shared.resource.readAsXml +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt index 819f343d08..0ed282c5a5 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/ContentProtectionService.kt @@ -12,7 +12,6 @@ package org.readium.r2.shared.publication.services import java.util.Locale import org.json.JSONObject import org.readium.r2.shared.UserException -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.putIfNotEmpty import org.readium.r2.shared.extensions.queryParameters import org.readium.r2.shared.publication.Link @@ -24,6 +23,7 @@ import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.resource.FailureResource import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.StringResource +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt index 807125b714..6a171f6909 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/PositionsService.kt @@ -11,7 +11,6 @@ package org.readium.r2.shared.publication.services import kotlinx.coroutines.runBlocking import org.json.JSONObject -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.mapNotNull import org.readium.r2.shared.extensions.toJsonOrNull import org.readium.r2.shared.publication.Link @@ -25,6 +24,7 @@ import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.StringResource import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.toJSON +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index 47113bc084..c692988761 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -15,7 +15,6 @@ import org.jsoup.parser.Parser import org.jsoup.select.NodeTraversor import org.jsoup.select.NodeVisitor import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator @@ -34,6 +33,7 @@ import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Href import org.readium.r2.shared.util.Language +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.use diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt index a707f9b669..2608074bd0 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/SearchService.kt @@ -12,12 +12,12 @@ import kotlinx.parcelize.Parcelize import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.R import org.readium.r2.shared.UserException -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.LocatorCollection import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.ServiceFactory import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.SuspendingCloseable +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.HttpException @ExperimentalReadiumApi diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt index 2b24a39389..636c0c876f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/search/StringSearchService.kt @@ -17,14 +17,14 @@ import java.util.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.services.positionsByReadingOrder import org.readium.r2.shared.publication.services.search.SearchService.Options import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.content.DefaultResourceContentExtractorFactory import org.readium.r2.shared.resource.content.ResourceContentExtractor +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.getOrThrow import timber.log.Timber /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt index f09cc7083a..04366c7e82 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/BufferingResource.kt @@ -6,10 +6,10 @@ package org.readium.r2.shared.resource -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.coerceIn import org.readium.r2.shared.extensions.contains import org.readium.r2.shared.extensions.requireLengthFitInt +import org.readium.r2.shared.util.Try /** * Wraps a [Resource] and buffers its content. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt index d142922c2b..6f9e37debd 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/BytesResource.kt @@ -7,8 +7,8 @@ package org.readium.r2.shared.resource import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.read +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt index 2bdf6bf6e0..310b4c109a 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ContentResource.kt @@ -14,8 +14,8 @@ import java.io.InputStream import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.toUri diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt index e0c2f29d41..6da801d3f6 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/DefaultArchiveFactory.kt @@ -11,8 +11,8 @@ import java.util.zip.ZipException import java.util.zip.ZipFile import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.MessageError -import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.MessageError +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.shared.util.toFile diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt index d1d091c7ae..d7a09f7c33 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/DirectoryContainer.kt @@ -10,10 +10,10 @@ import android.content.ContentResolver import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.extensions.isParentOf import org.readium.r2.shared.extensions.tryOr +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaTypeRetriever diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt index f759bfdb18..d903cc5f82 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Factories.kt @@ -6,10 +6,10 @@ package org.readium.r2.shared.resource -import org.readium.r2.shared.error.ThrowableError -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.tryRecover +import org.readium.r2.shared.util.ThrowableError +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.tryRecover /** * A factory to read [Resource]s from [Url]s. @@ -19,11 +19,11 @@ import org.readium.r2.shared.util.Url */ public fun interface ResourceFactory { - public sealed class Error : org.readium.r2.shared.error.Error { + public sealed class Error : org.readium.r2.shared.util.Error { public class SchemeNotSupported( public val scheme: String, - override val cause: org.readium.r2.shared.error.Error? = null + override val cause: org.readium.r2.shared.util.Error? = null ) : Error() { public constructor(scheme: String, exception: Exception) : this( @@ -37,7 +37,7 @@ public fun interface ResourceFactory { public class NotAResource( public val url: Url, - override val cause: org.readium.r2.shared.error.Error? = null + override val cause: org.readium.r2.shared.util.Error? = null ) : Error() { public constructor(url: Url, exception: Exception) : this( @@ -50,7 +50,7 @@ public fun interface ResourceFactory { } public class Forbidden( - override val cause: org.readium.r2.shared.error.Error + override val cause: org.readium.r2.shared.util.Error ) : Error() { public constructor(exception: Exception) : this(ThrowableError(exception)) @@ -71,11 +71,11 @@ public fun interface ResourceFactory { */ public fun interface ContainerFactory { - public sealed class Error : org.readium.r2.shared.error.Error { + public sealed class Error : org.readium.r2.shared.util.Error { public class SchemeNotSupported( public val scheme: String, - override val cause: org.readium.r2.shared.error.Error? = null + override val cause: org.readium.r2.shared.util.Error? = null ) : Error() { public constructor(scheme: String, exception: Exception) : this( @@ -89,7 +89,7 @@ public fun interface ContainerFactory { public class NotAContainer( public val url: Url, - override val cause: org.readium.r2.shared.error.Error? = null + override val cause: org.readium.r2.shared.util.Error? = null ) : Error() { public constructor(url: Url, exception: Exception) : this( @@ -102,7 +102,7 @@ public fun interface ContainerFactory { } public class Forbidden( - override val cause: org.readium.r2.shared.error.Error + override val cause: org.readium.r2.shared.util.Error ) : Error() { public constructor(exception: Exception) : this(ThrowableError(exception)) @@ -122,10 +122,10 @@ public fun interface ContainerFactory { */ public fun interface ArchiveFactory { - public sealed class Error : org.readium.r2.shared.error.Error { + public sealed class Error : org.readium.r2.shared.util.Error { public class FormatNotSupported( - override val cause: org.readium.r2.shared.error.Error? = null + override val cause: org.readium.r2.shared.util.Error? = null ) : Error() { public constructor(exception: Exception) : this(ThrowableError(exception)) @@ -135,7 +135,7 @@ public fun interface ArchiveFactory { } public class PasswordsNotSupported( - override val cause: org.readium.r2.shared.error.Error? = null + override val cause: org.readium.r2.shared.util.Error? = null ) : Error() { public constructor(exception: Exception) : this(ThrowableError(exception)) @@ -145,7 +145,7 @@ public fun interface ArchiveFactory { } public class ResourceReading( - override val cause: org.readium.r2.shared.error.Error?, + override val cause: org.readium.r2.shared.util.Error?, public val resourceException: Resource.Exception ) : Error() { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt index 76e8e5f270..954c035061 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileChannelResource.kt @@ -13,8 +13,8 @@ import java.nio.channels.Channels import java.nio.channels.FileChannel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt index f9b500b4b7..fb68a4e34c 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/FileResource.kt @@ -12,10 +12,10 @@ import java.io.RandomAccessFile import java.nio.channels.Channels import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.* +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.isFile import org.readium.r2.shared.util.isLazyInitialized import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt index ea5515dccb..0a31286c80 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/Resource.kt @@ -14,12 +14,12 @@ import java.nio.charset.Charset import org.json.JSONObject import org.readium.r2.shared.R import org.readium.r2.shared.UserException -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.parser.xml.ElementNode import org.readium.r2.shared.parser.xml.XmlParser import org.readium.r2.shared.util.SuspendingCloseable +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.mediatype.MediaType public typealias ResourceTry = Try diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt index 8b2ceb014b..b23e1c5730 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ResourceInputStream.kt @@ -9,7 +9,7 @@ package org.readium.r2.shared.resource import java.io.IOException import java.io.InputStream import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.error.getOrThrow +import org.readium.r2.shared.util.getOrThrow /** * Input stream reading a [Resource]'s content. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt index a7a055aba4..2f3263367f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/TransformingResource.kt @@ -6,10 +6,10 @@ package org.readium.r2.shared.resource -import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.extensions.coerceIn import org.readium.r2.shared.extensions.requireLengthFitInt import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.flatMap /** * Transforms the bytes of [resource] on-the-fly. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt index 665f449976..266a5098e3 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/ZipContainer.kt @@ -14,15 +14,15 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.json.JSONObject import org.readium.r2.shared.JSONable -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.extensions.optNullableBoolean import org.readium.r2.shared.extensions.optNullableLong import org.readium.r2.shared.extensions.readFully import org.readium.r2.shared.extensions.toMap import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.io.CountingInputStream import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeHints diff --git a/readium/shared/src/main/java/org/readium/r2/shared/resource/content/ResourceContentExtractor.kt b/readium/shared/src/main/java/org/readium/r2/shared/resource/content/ResourceContentExtractor.kt index f6d811b057..64136dfe04 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/resource/content/ResourceContentExtractor.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/resource/content/ResourceContentExtractor.kt @@ -11,11 +11,11 @@ import kotlinx.coroutines.withContext import org.jsoup.Jsoup import org.jsoup.parser.Parser import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.error.Try import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.resource.mapCatching import org.readium.r2.shared.resource.readAsString +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt index 9f60ac91af..9019ce948b 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Deprecated.kt @@ -8,8 +8,6 @@ package org.readium.r2.shared.util -import org.readium.r2.shared.error.Try - /** * Returns the encapsulated result of the given transform function applied to the encapsulated |Throwable] exception * if this instance represents failure or the original encapsulated value if it is success. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Error.kt similarity index 96% rename from readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt rename to readium/shared/src/main/java/org/readium/r2/shared/util/Error.kt index 6855e4496a..3b9a430764 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/error/Error.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Error.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.shared.error +package org.readium.r2.shared.util /** * Describes an error. diff --git a/readium/shared/src/main/java/org/readium/r2/shared/error/Try.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt similarity index 99% rename from readium/shared/src/main/java/org/readium/r2/shared/error/Try.kt rename to readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt index 3fb8db45b9..bfa09890c1 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/error/Try.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Try.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.shared.error +package org.readium.r2.shared.util /** A [Result] type which can be used as a return type. */ public sealed class Try { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt index 6d465f46f5..bf89d89e26 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ChannelZipContainer.kt @@ -9,8 +9,6 @@ package org.readium.r2.shared.util.archive.channel import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.extensions.readFully import org.readium.r2.shared.extensions.tryOrLog @@ -22,10 +20,12 @@ import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceMediaTypeSnifferContent import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.resource.archive +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipArchiveEntry import org.readium.r2.shared.util.archive.channel.compress.archivers.zip.ZipFile import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.io.CountingInputStream import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeHints diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt index e8762de0c4..ebe6d5765f 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/HttpChannel.kt @@ -12,12 +12,12 @@ import java.nio.ByteBuffer import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.extensions.readSafe import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpException import org.readium.r2.shared.util.http.HttpRequest diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt index 6c577ae1de..2b1dbcf46e 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/archive/channel/ResourceChannel.kt @@ -9,12 +9,12 @@ package org.readium.r2.shared.util.archive.channel import java.io.IOException import java.nio.ByteBuffer import kotlinx.coroutines.* -import org.readium.r2.shared.error.getOrElse -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.archive.channel.jvm.ClosedChannelException import org.readium.r2.shared.util.archive.channel.jvm.NonWritableChannelException import org.readium.r2.shared.util.archive.channel.jvm.SeekableByteChannel +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.getOrThrow internal class ResourceChannel( private val resource: Resource diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt index 1792b07168..323b12058d 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/DefaultHttpClient.kt @@ -14,14 +14,14 @@ import java.net.URL import kotlin.time.Duration import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap -import org.readium.r2.shared.error.tryRecover +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.http.HttpRequest.Method import org.readium.r2.shared.util.mediatype.BytesResourceMediaTypeSnifferContent import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeHints import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.util.tryRecover import timber.log.Timber /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt index 7e93c8a047..b323966769 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpClient.kt @@ -11,8 +11,8 @@ import java.nio.charset.Charset import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.json.JSONObject -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.mediatype.MediaType /** diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt index 462303680e..7378bdb053 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpException.kt @@ -14,8 +14,8 @@ import java.util.concurrent.CancellationException import org.json.JSONObject import org.readium.r2.shared.R import org.readium.r2.shared.UserException -import org.readium.r2.shared.error.Try import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.mediatype.MediaType public typealias HttpTry = Try diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt index 39f42720f7..eb647b13e8 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResource.kt @@ -3,13 +3,13 @@ package org.readium.r2.shared.util.http import java.io.InputStream import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.extensions.read import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.io.CountingInputStream import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt index b89bb74546..b426ce3719 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/http/HttpResourceFactory.kt @@ -6,9 +6,9 @@ package org.readium.r2.shared.util.http -import org.readium.r2.shared.error.Try import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceFactory +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.isHttp diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt index ff815d84bd..08433cc50d 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/protection/TestContainer.kt @@ -6,11 +6,11 @@ package org.readium.r2.shared.publication.protection -import org.readium.r2.shared.error.Try import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.resource.StringResource +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/shared/src/test/java/org/readium/r2/shared/resource/ZipContainerTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/resource/ZipContainerTest.kt index 6e036c9e04..195a913846 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/resource/ZipContainerTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/resource/ZipContainerTest.kt @@ -18,8 +18,8 @@ import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.junit.runner.RunWith -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.util.archive.channel.ChannelZipArchiveFactory +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.shared.util.use diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt index cffeb14653..b477105781 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt @@ -10,17 +10,17 @@ import java.io.File import java.nio.charset.Charset import org.json.JSONObject import org.readium.r2.shared.asset.Asset -import org.readium.r2.shared.error.MessageError -import org.readium.r2.shared.error.ThrowableError -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceContainer import org.readium.r2.shared.resource.RoutingContainer import org.readium.r2.shared.resource.StringResource +import org.readium.r2.shared.util.MessageError +import org.readium.r2.shared.util.ThrowableError +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpContainer import org.readium.r2.shared.util.mediatype.MediaType diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt index 8d87d4e5d5..3118e28f06 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/PublicationFactory.kt @@ -9,13 +9,13 @@ package org.readium.r2.streamer import android.content.Context import org.readium.r2.shared.PdfSupport import org.readium.r2.shared.asset.Asset -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.protection.AdeptFallbackContentProtection import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.publication.protection.LcpFallbackContentProtection import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.logging.WarningLogger diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt index d8a86a722f..5807151a42 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/PublicationParser.kt @@ -6,12 +6,12 @@ package org.readium.r2.streamer.parser -import org.readium.r2.shared.error.MessageError -import org.readium.r2.shared.error.ThrowableError -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.MessageError +import org.readium.r2.shared.util.ThrowableError +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType @@ -46,18 +46,18 @@ public interface PublicationParser { warnings: WarningLogger? = null ): Try - public sealed class Error : org.readium.r2.shared.error.Error { + public sealed class Error : org.readium.r2.shared.util.Error { public class FormatNotSupported : Error() { override val message: String = "Asset format not supported." - override val cause: org.readium.r2.shared.error.Error? = + override val cause: org.readium.r2.shared.util.Error? = null } - public class ParsingFailed(override val cause: org.readium.r2.shared.error.Error?) : Error() { + public class ParsingFailed(override val cause: org.readium.r2.shared.util.Error?) : Error() { public constructor(message: String) : this(MessageError(message)) @@ -72,12 +72,12 @@ public interface PublicationParser { override val message: String = "An IO error occurred." - override val cause: org.readium.r2.shared.error.Error = + override val cause: org.readium.r2.shared.util.Error = ThrowableError(resourceError) } public class OutOfMemory( - override val cause: org.readium.r2.shared.error.Error? + override val cause: org.readium.r2.shared.util.Error? ) : Error() { override val message: String = diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt index de756bed98..2d8d3168f8 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/audio/AudioParser.kt @@ -7,11 +7,11 @@ package org.readium.r2.streamer.parser.audio import java.io.File -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.LocalizedString import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Metadata import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.streamer.extensions.guessTitle diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt index 2c8a7fafbd..9459aca44c 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/epub/EpubParser.kt @@ -7,8 +7,6 @@ package org.readium.r2.streamer.parser.epub import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Publication @@ -21,6 +19,8 @@ import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.TransformingContainer import org.readium.r2.shared.resource.readAsXml import org.readium.r2.shared.util.Href +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt index 64538fb889..ef18f00a0e 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/image/ImageParser.kt @@ -7,9 +7,9 @@ package org.readium.r2.streamer.parser.image import java.io.File -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.services.PerResourcePositionsService +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.streamer.extensions.guessTitle diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt index ca0d074cf6..460ecb5fda 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/pdf/PdfParser.kt @@ -9,10 +9,10 @@ package org.readium.r2.streamer.parser.pdf import android.content.Context import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.PdfSupport -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.* import org.readium.r2.shared.publication.services.InMemoryCacheService import org.readium.r2.shared.publication.services.InMemoryCoverService +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.pdf.PdfDocumentFactory diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt index 0a2e8d9bd9..9bd39a4094 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt @@ -7,12 +7,12 @@ package org.readium.r2.streamer.parser.readium import android.content.Context -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Manifest import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.* import org.readium.r2.shared.resource.readAsJson +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.logging.WarningLogger import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt index 21e01ef65b..7eda3a0fc0 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubDeobfuscatorTest.kt @@ -13,12 +13,12 @@ import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.junit.runner.RunWith -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.encryption.Encryption import org.readium.r2.shared.resource.DirectoryContainerFactory import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.flatMap import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import org.readium.r2.streamer.readBlocking import org.robolectric.RobolectricTestRunner diff --git a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt index 4aeace0d2c..3d3f96abd7 100644 --- a/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt +++ b/readium/streamer/src/test/java/org/readium/r2/streamer/parser/epub/EpubPositionsServiceTest.kt @@ -13,7 +13,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.Link import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Properties @@ -24,6 +23,7 @@ import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceTry import org.readium.r2.shared.resource.archive +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.mediatype.MediaType import org.robolectric.RobolectricTestRunner diff --git a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt b/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt index 8360155d86..c024a4ee3a 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt @@ -9,8 +9,8 @@ package org.readium.r2.testapp import androidx.annotation.StringRes import org.readium.r2.shared.UserException import org.readium.r2.shared.asset.AssetRetriever -import org.readium.r2.shared.error.Error import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.Error sealed class PublicationError(@StringRes userMessageId: Int) : UserException(userMessageId) { diff --git a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt index d3d87c9077..82b1c0a1d4 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt @@ -13,7 +13,6 @@ import org.readium.r2.navigator.preferences.FontFamily import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.UserException import org.readium.r2.shared.asset.AssetRetriever -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.protection.ContentProtectionSchemeRetriever import org.readium.r2.shared.resource.CompositeArchiveFactory import org.readium.r2.shared.resource.CompositeResourceFactory @@ -21,6 +20,7 @@ import org.readium.r2.shared.resource.ContentResourceFactory import org.readium.r2.shared.resource.DefaultArchiveFactory import org.readium.r2.shared.resource.DirectoryContainerFactory import org.readium.r2.shared.resource.FileResourceFactory +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.archive.channel.ChannelZipArchiveFactory import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpResourceFactory diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt index 6675f61d86..326aa67497 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt @@ -28,16 +28,16 @@ import org.readium.r2.shared.UserException import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.asset.AssetType -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.indexOfFirstWithHref import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.publication.protection.ContentProtectionSchemeRetriever import org.readium.r2.shared.publication.services.cover +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.mediatype.FormatRegistry import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.toUrl diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt index 01484ae992..1078dd30e0 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt @@ -15,8 +15,8 @@ import kotlinx.coroutines.launch import org.json.JSONObject import org.readium.r2.opds.OPDS1Parser import org.readium.r2.opds.OPDS2Parser -import org.readium.r2.shared.error.Try import org.readium.r2.shared.opds.ParseData +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.HttpRequest import org.readium.r2.shared.util.http.fetchWithDecoder import org.readium.r2.testapp.db.BookDatabase diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt index e7367f1690..15d86482c0 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt @@ -17,11 +17,11 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.launch import org.readium.r2.opds.OPDS1Parser import org.readium.r2.opds.OPDS2Parser -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap import org.readium.r2.shared.opds.ParseData import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.opds.images +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.http.HttpRequest import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.testapp.domain.model.Catalog diff --git a/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementViewModel.kt index f3c89bf329..bc14687812 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementViewModel.kt @@ -9,7 +9,7 @@ package org.readium.r2.testapp.drm import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModel import java.util.* -import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.Try abstract class DrmManagementViewModel : ViewModel() { diff --git a/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt index f65ea38f83..eab08ba8be 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/drm/LcpManagementViewModel.kt @@ -11,7 +11,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import java.util.* import org.readium.r2.lcp.LcpLicense -import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.Try class LcpManagementViewModel( private val lcpLicense: LcpLicense, diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt index ff8ac63e83..2581f80b68 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt @@ -21,13 +21,13 @@ import org.readium.r2.navigator.pdf.PdfNavigatorFactory import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.UserException import org.readium.r2.shared.asset.AssetRetriever -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.getOrElse import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.allAreHtml import org.readium.r2.shared.publication.services.isRestricted +import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.getOrElse import org.readium.r2.testapp.PublicationError import org.readium.r2.testapp.Readium import org.readium.r2.testapp.bookshelf.BookRepository diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt index e5fd45f596..3852b246da 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt @@ -22,13 +22,13 @@ import org.readium.r2.navigator.ExperimentalDecorator import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.Search import org.readium.r2.shared.UserException -import org.readium.r2.shared.error.Try import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.LocatorCollection import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.services.search.SearchIterator import org.readium.r2.shared.publication.services.search.SearchTry import org.readium.r2.shared.publication.services.search.search +import org.readium.r2.shared.util.Try import org.readium.r2.testapp.Application import org.readium.r2.testapp.bookshelf.BookRepository import org.readium.r2.testapp.domain.model.Highlight diff --git a/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt b/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt index 9d858e5f87..f6082263de 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/search/SearchPagingSource.kt @@ -9,10 +9,10 @@ package org.readium.r2.testapp.search import androidx.paging.PagingSource import androidx.paging.PagingState import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.error.getOrThrow import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.LocatorCollection import org.readium.r2.shared.publication.services.search.SearchTry +import org.readium.r2.shared.util.getOrThrow @OptIn(ExperimentalReadiumApi::class) class SearchPagingSource( diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt index 5de0346cee..62bbb4d56b 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt @@ -18,8 +18,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ensureActive import kotlinx.coroutines.withContext import org.readium.r2.shared.asset.AssetRetriever -import org.readium.r2.shared.error.Try -import org.readium.r2.shared.error.flatMap +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.http.HttpClient import org.readium.r2.shared.util.http.HttpException import org.readium.r2.shared.util.http.HttpRequest diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt index 3b02e3da19..b9636881cf 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Uri.kt @@ -12,7 +12,7 @@ import android.net.Uri import android.provider.MediaStore import java.io.File import java.util.* -import org.readium.r2.shared.error.Try +import org.readium.r2.shared.util.Try import org.readium.r2.testapp.utils.ContentResolverUtil import org.readium.r2.testapp.utils.tryOrNull From 8d06db3ff4b77cf040681b1d3347d9303a8c1db3 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Tue, 22 Aug 2023 17:31:14 +0200 Subject: [PATCH 24/65] Fix uses of MenuProvider (#379) --- .../readium/r2/testapp/reader/BaseReaderFragment.kt | 10 ++++++---- .../readium/r2/testapp/reader/EpubReaderFragment.kt | 5 ++--- .../readium/r2/testapp/reader/VisualReaderFragment.kt | 10 ++++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt index 89b7299f69..dec50e0984 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/BaseReaderFragment.kt @@ -16,7 +16,6 @@ import androidx.core.view.MenuHost import androidx.core.view.MenuProvider import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Lifecycle import org.readium.r2.lcp.lcpLicense import org.readium.r2.navigator.Navigator import org.readium.r2.navigator.preferences.Configurable @@ -78,26 +77,29 @@ abstract class BaseReaderFragment : Fragment() { when (menuItem.itemId) { R.id.toc -> { model.activityChannel.send(ReaderViewModel.Event.OpenOutlineRequested) + return true } R.id.bookmark -> { model.insertBookmark(navigator.currentLocator.value) + return true } R.id.settings -> { val settingsModel = checkNotNull(model.settings) UserPreferencesBottomSheetDialogFragment(settingsModel, "User Settings") .show(childFragmentManager, "Settings") + return true } R.id.drm -> { model.activityChannel.send( ReaderViewModel.Event.OpenDrmManagementRequested ) + return true } } - return true + return false } }, - viewLifecycleOwner, - Lifecycle.State.RESUMED + viewLifecycleOwner ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt index f49028777d..2f353480f4 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/EpubReaderFragment.kt @@ -175,11 +175,10 @@ class EpubReaderFragment : VisualReaderFragment(), EpubNavigatorFragment.Listene return true } } - return true + return false } }, - viewLifecycleOwner, - Lifecycle.State.RESUMED + viewLifecycleOwner ) } diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt index 4a8caa8d75..206b4eeec8 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt @@ -145,13 +145,15 @@ abstract class VisualReaderFragment : BaseReaderFragment(), VisualNavigator.List override fun onMenuItemSelected(menuItem: MenuItem): Boolean { when (menuItem.itemId) { - R.id.tts -> checkNotNull(model.tts).start(navigator) + R.id.tts -> { + checkNotNull(model.tts).start(navigator) + return true + } } - return true + return false } }, - viewLifecycleOwner, - Lifecycle.State.RESUMED + viewLifecycleOwner ) } From f5cd4b9c5bea958446e6cbda9979e4ea8a0e3596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 23 Aug 2023 18:00:07 +0200 Subject: [PATCH 25/65] Simplify RWPM parsing for packaged publications (#380) --- .../readium/r2/lcp/service/LicensesService.kt | 10 +--- .../navigator/media/MediaSessionNavigator.kt | 4 +- .../readium/r2/shared/publication/Manifest.kt | 34 +++++--------- .../r2/shared/publication/ManifestTest.kt | 47 ++----------------- .../readium/r2/streamer/ParserAssetFactory.kt | 11 ++--- .../parser/readium/ReadiumWebPubParser.kt | 1 - 6 files changed, 21 insertions(+), 86 deletions(-) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index 049e87f044..b70554299d 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -34,6 +34,7 @@ import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.extensions.tryOr import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.mediatype.FormatRegistry import org.readium.r2.shared.util.mediatype.MediaType import timber.log.Timber @@ -260,12 +261,5 @@ internal class LicensesService( } private val MediaType.fileExtension: String get() = - when { - matches(MediaType.DIVINA) -> "divina" - matches(MediaType.EPUB) -> "epub" - matches(MediaType.LCP_PROTECTED_PDF) -> "pdf" - matches(MediaType.READIUM_AUDIOBOOK) -> "audiobook" - matches(MediaType.READIUM_WEBPUB) -> "webpub" - else -> "epub" - } + FormatRegistry().fileExtension(this) ?: "epub" } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt index efc6c4f0e4..4d7d1f67d0 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media/MediaSessionNavigator.kt @@ -45,8 +45,8 @@ private val skipBackwardInterval: Duration = 30.seconds @OptIn(ExperimentalTime::class) public class MediaSessionNavigator( override val publication: Publication, - internal val publicationId: PublicationId, - private val controller: MediaControllerCompat, + public val publicationId: PublicationId, + public val controller: MediaControllerCompat, public var listener: Listener? = null ) : MediaNavigator, CoroutineScope by MainScope() { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt index ace4d4ef3c..8f64b360de 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Manifest.kt @@ -155,28 +155,23 @@ public data class Manifest( */ public fun fromJSON( json: JSONObject?, - packaged: Boolean = false, mediaTypeRetriever: MediaTypeRetriever = MediaTypeRetriever(), warnings: WarningLogger? = null ): Manifest? { json ?: return null val baseUrl = - if (packaged) { - "/" - } else { - Link.fromJSONArray( - json.optJSONArray("links"), - mediaTypeRetriever, - warnings = warnings - ) - .firstWithRel("self") - ?.href - ?.toUrlOrNull() - ?.removeLastComponent() - ?.toString() - ?: "/" - } + Link.fromJSONArray( + json.optJSONArray("links"), + mediaTypeRetriever, + warnings = warnings + ) + .firstWithRel("self") + ?.href + ?.toUrlOrNull() + ?.removeLastComponent() + ?.toString() + ?: "/" val normalizeHref = { href: String -> Href(href, baseUrl).string } @@ -199,13 +194,6 @@ public data class Manifest( normalizeHref, warnings ) - .map { - if (packaged && "self" in it.rels) { - it.copy(rels = it.rels - "self" + "alternate") - } else { - it - } - } // [readingOrder] used to be [spine], so we parse [spine] as a fallback. val readingOrderJSON = (json.remove("readingOrder") ?: json.remove("spine")) as? JSONArray diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt index 3ee6693549..ece39b346a 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/ManifestTest.kt @@ -268,53 +268,12 @@ class ManifestTest { } @Test - fun `self link is replaced when parsing a package`() { - assertEquals( - Manifest( - metadata = Metadata(localizedTitle = LocalizedString("Title")), - links = listOf(Link(href = "/manifest.json", rels = setOf("alternate"))) - ), - Manifest.fromJSON( - JSONObject( - """{ - "metadata": {"title": "Title"}, - "links": [ - {"href": "/manifest.json", "rel": ["self"], "templated": false} - ] - }""" - ), - packaged = true - ) - ) - } - - @Test - fun `self link is kept when parsing a remote manifest`() { - assertEquals( - Manifest( - metadata = Metadata(localizedTitle = LocalizedString("Title")), - links = listOf(Link(href = "/manifest.json", rels = setOf("self"))) - ), - Manifest.fromJSON( - JSONObject( - """{ - "metadata": {"title": "Title"}, - "links": [ - {"href": "/manifest.json", "rel": ["self"]} - ] - }""" - ) - ) - ) - } - - @Test - fun `href are resolved to root when parsing a package`() { + fun `href are resolved to root with a relative self link`() { val json = JSONObject( """{ "metadata": {"title": "Title"}, "links": [ - {"href": "http://example.com/manifest.json", "rel": ["self"], "templated": false} + {"href": "manifest.json", "rel": ["self"], "templated": false} ], "readingOrder": [ {"href": "chap1.html", "type": "text/html", "templated": false} @@ -324,7 +283,7 @@ class ManifestTest { assertEquals( "/chap1.html", - Manifest.fromJSON(json, packaged = true)?.readingOrder?.first()?.href + Manifest.fromJSON(json)?.readingOrder?.first()?.href ) } diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt index b477105781..8f6adfbb1b 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/ParserAssetFactory.kt @@ -15,7 +15,6 @@ import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.ResourceContainer import org.readium.r2.shared.resource.RoutingContainer -import org.readium.r2.shared.resource.StringResource import org.readium.r2.shared.util.MessageError import org.readium.r2.shared.util.ThrowableError import org.readium.r2.shared.util.Try @@ -65,7 +64,7 @@ internal class ParserAssetFactory( private suspend fun createParserAssetForManifest( asset: Asset.Resource ): Try { - val manifest = asset.resource.readAsRwpm(packaged = false) + val manifest = asset.resource.readAsRwpm() .mapFailure { Publication.OpeningException.ParsingFailed(ThrowableError(it)) } .getOrElse { return Try.failure(it) } @@ -87,10 +86,7 @@ internal class ParserAssetFactory( val container = RoutingContainer( - local = ResourceContainer( - path = "/manifest.json", - resource = StringResource(manifest.toJSON().toString(), asset.mediaType) - ), + local = ResourceContainer(path = "/manifest.json", asset.resource), remote = HttpContainer(httpClient, baseUrl) ) @@ -118,14 +114,13 @@ internal class ParserAssetFactory( ) } - private suspend fun Resource.readAsRwpm(packaged: Boolean): Try = + private suspend fun Resource.readAsRwpm(): Try = try { val bytes = read().getOrThrow() val string = String(bytes, Charset.defaultCharset()) val json = JSONObject(string) val manifest = Manifest.fromJSON( json, - packaged = packaged, mediaTypeRetriever = mediaTypeRetriever ) ?: throw Exception("Failed to parse the RWPM Manifest") diff --git a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt index 9bd39a4094..ce1cf1de56 100644 --- a/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt +++ b/readium/streamer/src/main/java/org/readium/r2/streamer/parser/readium/ReadiumWebPubParser.kt @@ -44,7 +44,6 @@ public class ReadiumWebPubParser( val manifest = Manifest.fromJSON( manifestJson, - packaged = true, mediaTypeRetriever = mediaTypeRetriever ) ?: return Try.failure( From 4df93f780ec7bcf176f2798cff7df4cba52acccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Mon, 28 Aug 2023 15:28:40 +0200 Subject: [PATCH 26/65] Highlight images during text-to-speech (#382) --- .../r2/navigator/media3/tts/TtsNavigator.kt | 22 ++++---- .../r2/navigator/media3/tts/TtsPlayer.kt | 50 +++++++++---------- ...entIterator.kt => TtsUtteranceIterator.kt} | 26 +++++----- 3 files changed, 45 insertions(+), 53 deletions(-) rename readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/{TtsContentIterator.kt => TtsUtteranceIterator.kt} (91%) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt index 7365403c34..250d5440b9 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsNavigator.kt @@ -68,7 +68,7 @@ public class TtsNavigator, ?: ttsEngineProvider.createEmptyPreferences() val contentIterator = - TtsContentIterator(publication, tokenizerFactory, initialLocator) + TtsUtteranceIterator(publication, tokenizerFactory, initialLocator) val ttsEngine = ttsEngineProvider.createEngine(publication, actualInitialPreferences) @@ -279,28 +279,24 @@ public class TtsNavigator, private fun TtsPlayer.Utterance.toPosition(): Location { val currentLink = publication.readingOrder[position.resourceIndex] - val utteranceHighlight = publication + val utteranceLocator = publication .locatorFromLink(currentLink)!! .copy( locations = position.locations, - text = Locator.Text( - highlight = text, - before = position.textBefore, - after = position.textAfter - ) + text = position.text ) - val tokenHighlight = range - ?.let { utteranceHighlight.copy(text = utteranceHighlight.text.substring(it)) } + val tokenLocator = range + ?.let { utteranceLocator.copy(text = utteranceLocator.text.substring(it)) } return Location( href = Href(currentLink.href), - textBefore = position.textBefore, - textAfter = position.textAfter, + textBefore = position.text.before, + textAfter = position.text.after, utterance = text, range = range, - utteranceLocator = utteranceHighlight, - tokenLocator = tokenHighlight + utteranceLocator = utteranceLocator, + tokenLocator = tokenLocator ) } } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt index 0d4a5097a3..08c4179f1a 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsPlayer.kt @@ -24,13 +24,13 @@ import org.readium.r2.shared.extensions.tryOrNull import org.readium.r2.shared.publication.Locator /** - * Plays the content from a [TtsContentIterator] with a [TtsEngine]. + * Plays the content from a [TtsUtteranceIterator] with a [TtsEngine]. */ @ExperimentalReadiumApi internal class TtsPlayer, E : TtsEngine.Error, V : TtsEngine.Voice> private constructor( private val engineFacade: TtsEngineFacade, - private val contentIterator: TtsContentIterator, + private val contentIterator: TtsUtteranceIterator, initialWindow: UtteranceWindow, initialPreferences: P ) : Configurable { @@ -40,7 +40,7 @@ internal class TtsPlayer, suspend operator fun , E : TtsEngine.Error, V : TtsEngine.Voice> invoke( engine: TtsEngine, - contentIterator: TtsContentIterator, + contentIterator: TtsUtteranceIterator, initialPreferences: P ): TtsPlayer? { val initialContext = tryOrNull { contentIterator.startContext() } @@ -59,23 +59,23 @@ internal class TtsPlayer, ) } - private suspend fun TtsContentIterator.startContext(): UtteranceWindow? { - val previousUtterance = previousUtterance() - val currentUtterance = nextUtterance() + private suspend fun TtsUtteranceIterator.startContext(): UtteranceWindow? { + val previousUtterance = previous() + val currentUtterance = next() val startWindow = if (currentUtterance != null) { UtteranceWindow( previousUtterance = previousUtterance, currentUtterance = currentUtterance, - nextUtterance = nextUtterance(), + nextUtterance = next(), ended = false ) } else { val actualCurrentUtterance = previousUtterance ?: return null - val actualPreviousUtterance = previousUtterance() + val actualPreviousUtterance = previous() // Go back to the end of the iterator. - nextUtterance() + next() UtteranceWindow( previousUtterance = actualPreviousUtterance, @@ -129,15 +129,14 @@ internal class TtsPlayer, data class Position( val resourceIndex: Int, val locations: Locator.Locations, - val textBefore: String?, - val textAfter: String? + val text: Locator.Text ) } private data class UtteranceWindow( - val previousUtterance: TtsContentIterator.Utterance?, - val currentUtterance: TtsContentIterator.Utterance, - val nextUtterance: TtsContentIterator.Utterance?, + val previousUtterance: TtsUtteranceIterator.Utterance?, + val currentUtterance: TtsUtteranceIterator.Utterance, + val nextUtterance: TtsUtteranceIterator.Utterance?, val ended: Boolean = false ) @@ -411,19 +410,19 @@ internal class TtsPlayer, val previousUtterance = try { // Get previously currentUtterance once more - contentIterator.previousUtterance() + contentIterator.previous() // Get previously previousUtterance once more - contentIterator.previousUtterance() + contentIterator.previous() // Get new previous utterance - val previousUtterance = contentIterator.previousUtterance() + val previousUtterance = contentIterator.previous() // Go to currentUtterance position - contentIterator.nextUtterance() + contentIterator.next() // Go to nextUtterance position - contentIterator.nextUtterance() + contentIterator.next() previousUtterance } catch (e: Exception) { @@ -448,7 +447,7 @@ internal class TtsPlayer, } val nextUtterance = try { - contentIterator.nextUtterance() + contentIterator.next() } catch (e: Exception) { onContentError(e) return @@ -498,8 +497,8 @@ internal class TtsPlayer, playContinuous() } - private suspend fun speakUtterance(utterance: TtsContentIterator.Utterance): E? = - engineFacade.speak(utterance.text, utterance.language, ::onRangeChanged) + private suspend fun speakUtterance(utterance: TtsUtteranceIterator.Utterance): E? = + engineFacade.speak(utterance.utterance, utterance.language, ::onRangeChanged) private fun onEngineError(error: E) { playbackMutable.value = playbackMutable.value.copy( @@ -535,15 +534,14 @@ internal class TtsPlayer, private fun isPlaying() = playbackMutable.value.playWhenReady && playback.value.state == State.Ready - private fun TtsContentIterator.Utterance.ttsPlayerUtterance(): Utterance = + private fun TtsUtteranceIterator.Utterance.ttsPlayerUtterance(): Utterance = Utterance( - text = text, + text = utterance, range = null, position = Utterance.Position( resourceIndex = resourceIndex, locations = locations, - textAfter = textAfter, - textBefore = textBefore + text = text ) ) } diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsContentIterator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsUtteranceIterator.kt similarity index 91% rename from readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsContentIterator.kt rename to readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsUtteranceIterator.kt index e16d7be294..6baef7866f 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsContentIterator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsUtteranceIterator.kt @@ -24,17 +24,16 @@ import org.readium.r2.shared.util.tokenizer.TextTokenizer * * Not thread-safe. */ -internal class TtsContentIterator( +internal class TtsUtteranceIterator( private val publication: Publication, private val tokenizerFactory: (language: Language?) -> TextTokenizer, initialLocator: Locator? ) { data class Utterance( + val utterance: String, val resourceIndex: Int, val locations: Locator.Locations, - val text: String, - val textBefore: String?, - val textAfter: String?, + val text: Locator.Text, val language: Language? ) @@ -109,14 +108,14 @@ internal class TtsContentIterator( /** * Advances to the previous item and returns it, or null if we reached the beginning. */ - suspend fun previousUtterance(): Utterance? = - nextUtterance(Direction.Backward) + suspend fun previous(): Utterance? = + next(Direction.Backward) /** * Advances to the next item and returns it, or null if we reached the end. */ - suspend fun nextUtterance(): Utterance? = - nextUtterance(Direction.Forward) + suspend fun next(): Utterance? = + next(Direction.Forward) private enum class Direction { Forward, Backward; @@ -126,10 +125,10 @@ internal class TtsContentIterator( * Gets the next utterance in the given [direction], or null when reaching the beginning or the * end. */ - private suspend fun nextUtterance(direction: Direction): Utterance? { + private suspend fun next(direction: Direction): Utterance? { val utterance = utterances.nextIn(direction) if (utterance == null && loadNextUtterances(direction)) { - return nextUtterance(direction) + return next(direction) } return utterance } @@ -167,7 +166,7 @@ internal class TtsContentIterator( */ private fun Content.Element.tokenize(): List { val contentTokenizer = TextContentTokenizer( - language = this@TtsContentIterator.language, + language = this@TtsUtteranceIterator.language, textTokenizerFactory = tokenizerFactory, overrideContentLanguage = overrideContentLanguage ) @@ -187,11 +186,10 @@ internal class TtsContentIterator( ?: throw IllegalStateException("Content Element cannot be found in readingOrder.") return Utterance( + utterance = text, resourceIndex = resourceIndex, locations = locator.locations, - text = text, - textBefore = locator.text.before, - textAfter = locator.text.after, + text = locator.text, language = language ) } From ef8d2218772a6f1f8b8f052bc8500946f7ec4aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Fri, 15 Sep 2023 10:12:41 +0200 Subject: [PATCH 27/65] Bugfixes for TTS (#390) --- .../navigator/media3/tts/TtsEngineFacade.kt | 40 ++---- .../readium/r2/shared/publication/Locator.kt | 19 +-- .../r2/shared/publication/LocatorTest.kt | 125 ++++++++++++++++++ 3 files changed, 150 insertions(+), 34 deletions(-) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngineFacade.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngineFacade.kt index 5f5151ca28..4caff34898 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngineFacade.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/media3/tts/TtsEngineFacade.kt @@ -26,8 +26,6 @@ internal class TtsEngineFacade? = null - val voices: Set get() = engine.voices @@ -45,54 +43,44 @@ internal class TtsEngineFacade? = null + private data class UtteranceTask( val requestId: TtsEngine.RequestId, val continuation: CancellableContinuation, val onRange: (IntRange) -> Unit ) + private fun getTask(id: TtsEngine.RequestId) = + currentTask?.takeIf { it.requestId == id } + + private fun popTask(id: TtsEngine.RequestId) = + getTask(id) + ?.also { currentTask = null } + private inner class EngineListener : TtsEngine.Listener { override fun onStart(requestId: TtsEngine.RequestId) { } override fun onRange(requestId: TtsEngine.RequestId, range: IntRange) { - currentTask - ?.takeIf { it.requestId == requestId } - ?.onRange - ?.invoke(range) + getTask(requestId)?.onRange?.invoke(range) } override fun onInterrupted(requestId: TtsEngine.RequestId) { - currentTask - ?.takeIf { it.requestId == requestId } - ?.continuation - ?.cancel() - currentTask = null + popTask(requestId)?.continuation?.cancel() } override fun onFlushed(requestId: TtsEngine.RequestId) { - currentTask - ?.takeIf { it.requestId == requestId } - ?.continuation - ?.cancel() - currentTask = null + popTask(requestId)?.continuation?.cancel() } override fun onDone(requestId: TtsEngine.RequestId) { - currentTask - ?.takeIf { it.requestId == requestId } - ?.continuation - ?.resume(null) {} - currentTask = null + popTask(requestId)?.continuation?.resume(null) {} } override fun onError(requestId: TtsEngine.RequestId, error: E) { - currentTask - ?.takeIf { it.requestId == requestId } - ?.continuation - ?.resume(error) {} - currentTask = null + popTask(requestId)?.continuation?.resume(error) {} } } } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt index 442886003d..68f39e6df1 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/Locator.kt @@ -134,14 +134,17 @@ public data class Locator( } public fun substring(range: IntRange): Text { - highlight ?: return this - return tryOr(this) { - copy( - before = (before ?: "") + highlight.substring(0, range.first), - highlight = highlight.substring(range), - after = highlight.substring(range.last) + (after ?: "") - ) - } + if (highlight.isNullOrBlank()) return this + + val fixedRange = range.first.coerceIn(0, highlight.length)..range.last.coerceIn( + 0, + highlight.length - 1 + ) + return copy( + before = (before ?: "") + highlight.substring(0, fixedRange.first), + highlight = highlight.substring(fixedRange), + after = highlight.substring((fixedRange.last + 1).coerceAtMost(highlight.length)) + (after ?: "") + ) } public companion object { diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt index 89337e2ca2..18b53bc86b 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/LocatorTest.kt @@ -337,6 +337,131 @@ class LocatorTest { ).toJSON() ) } + + @Test fun `substring from a range`() { + val text = Locator.Text( + before = "before", + highlight = "highlight", + after = "after" + ) + + assertEquals( + Locator.Text( + before = "before", + highlight = "h", + after = "ighlightafter" + ), + text.substring(0..-1) + ) + + assertEquals( + Locator.Text( + before = "before", + highlight = "h", + after = "ighlightafter" + ), + text.substring(0..0) + ) + + assertEquals( + Locator.Text( + before = "beforehigh", + highlight = "lig", + after = "htafter" + ), + text.substring(4..6) + ) + + assertEquals( + Locator.Text( + before = "before", + highlight = "highlight", + after = "after" + ), + text.substring(0..8) + ) + + assertEquals( + Locator.Text( + before = "beforehighli", + highlight = "ght", + after = "after" + ), + text.substring(6..12) + ) + + assertEquals( + Locator.Text( + before = "beforehighligh", + highlight = "t", + after = "after" + ), + text.substring(8..12) + ) + + assertEquals( + Locator.Text( + before = "beforehighlight", + highlight = "", + after = "after" + ), + text.substring(9..12) + ) + } + + @Test fun `substring from a range with null components`() { + assertEquals( + Locator.Text( + before = "high", + highlight = "lig", + after = "htafter" + ), + Locator.Text( + before = null, + highlight = "highlight", + after = "after" + ).substring(4..6) + ) + + assertEquals( + Locator.Text( + before = "beforehigh", + highlight = "lig", + after = "ht" + ), + Locator.Text( + before = "before", + highlight = "highlight", + after = null + ).substring(4..6) + ) + + assertEquals( + Locator.Text( + before = "before", + highlight = null, + after = "after" + ), + Locator.Text( + before = "before", + highlight = null, + after = "after" + ).substring(4..6) + ) + + assertEquals( + Locator.Text( + before = "before", + highlight = "", + after = "after" + ), + Locator.Text( + before = "before", + highlight = "", + after = "after" + ).substring(4..6) + ) + } } @RunWith(RobolectricTestRunner::class) From f85d408fbee5ae841014b8cf3ad4d4bd5c598be2 Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:10:21 +0200 Subject: [PATCH 28/65] Add a download manager (#381) --- .../readium/r2/lcp/LcpDownloadsRepository.kt | 99 +++++ .../readium/r2/lcp/LcpPublicationRetriever.kt | 272 ++++++++++++ .../java/org/readium/r2/lcp/LcpService.kt | 42 +- .../container/BytesLicenseContainer.kt | 2 +- .../license/container/LCPLLicenseContainer.kt | 2 +- .../license/container/ZIPLicenseContainer.kt | 2 +- .../r2/lcp/license/model/LicenseDocument.kt | 98 +++-- .../readium/r2/lcp/service/LicensesService.kt | 22 +- .../readium/r2/shared/util/CoroutineQueue.kt | 69 +++ .../readium/r2/shared/util/MapCompanion.kt | 4 + .../shared/util/downloads/DownloadManager.kt | 139 ++++++ .../android/AndroidDownloadManager.kt | 311 +++++++++++++ .../downloads/android/DownloadCursorFacade.kt | 55 +++ .../foreground/ForegroundDownloadManager.kt | 194 +++++++++ test-app/src/main/AndroidManifest.xml | 1 + .../org/readium/r2/testapp/Application.kt | 86 +++- .../org/readium/r2/testapp/MainActivity.kt | 25 +- .../org/readium/r2/testapp/MainViewModel.kt | 62 +++ .../java/org/readium/r2/testapp/Readium.kt | 19 +- .../r2/testapp/bookshelf/BookRepository.kt | 377 ---------------- .../r2/testapp/bookshelf/BookshelfAdapter.kt | 2 +- .../r2/testapp/bookshelf/BookshelfFragment.kt | 64 ++- .../testapp/bookshelf/BookshelfViewModel.kt | 106 +---- .../catalogs/CatalogFeedListAdapter.kt | 2 +- .../catalogs/CatalogFeedListFragment.kt | 2 +- .../catalogs/CatalogFeedListViewModel.kt | 7 +- .../r2/testapp/catalogs/CatalogFragment.kt | 10 +- .../r2/testapp/catalogs/CatalogViewModel.kt | 63 +-- .../r2/testapp/catalogs/GroupAdapter.kt | 2 +- .../r2/testapp/catalogs/NavigationAdapter.kt | 2 +- .../catalogs/PublicationDetailFragment.kt | 22 - .../readium/r2/testapp/data/BookRepository.kt | 106 +++++ .../{catalogs => data}/CatalogRepository.kt | 6 +- .../r2/testapp/data/DownloadRepository.kt | 37 ++ .../db/AppDatabase.kt} | 27 +- .../r2/testapp/{ => data}/db/BooksDao.kt | 8 +- .../r2/testapp/{ => data}/db/CatalogDao.kt | 4 +- .../r2/testapp/data/db/DownloadsDao.kt | 37 ++ .../r2/testapp/{domain => data}/model/Book.kt | 2 +- .../{domain => data}/model/Bookmark.kt | 2 +- .../testapp/{domain => data}/model/Catalog.kt | 2 +- .../readium/r2/testapp/data/model/Download.kt | 50 +++ .../{domain => data}/model/Highlight.kt | 2 +- .../readium/r2/testapp/domain/Bookshelf.kt | 176 ++++++++ .../readium/r2/testapp/domain/CoverStorage.kt | 61 +++ .../readium/r2/testapp/domain/ImportError.kt | 60 +++ .../testapp/{ => domain}/PublicationError.kt | 9 +- .../r2/testapp/domain/PublicationRetriever.kt | 409 ++++++++++++++++++ .../r2/testapp/outline/BookmarksFragment.kt | 2 +- .../r2/testapp/outline/HighlightsFragment.kt | 2 +- .../r2/testapp/reader/ReaderRepository.kt | 22 +- .../r2/testapp/reader/ReaderViewModel.kt | 4 +- .../r2/testapp/reader/VisualReaderFragment.kt | 2 +- .../r2/testapp/utils/extensions/File.kt | 9 +- .../r2/testapp/utils/extensions/Number.kt | 9 + test-app/src/main/res/values/arrays.xml | 2 +- test-app/src/main/res/values/strings.xml | 5 +- 57 files changed, 2507 insertions(+), 711 deletions(-) create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/LcpDownloadsRepository.kt create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/LcpPublicationRetriever.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/CoroutineQueue.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/downloads/DownloadManager.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/AndroidDownloadManager.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/DownloadCursorFacade.kt create mode 100644 readium/shared/src/main/java/org/readium/r2/shared/util/downloads/foreground/ForegroundDownloadManager.kt create mode 100644 test-app/src/main/java/org/readium/r2/testapp/MainViewModel.kt delete mode 100644 test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt create mode 100644 test-app/src/main/java/org/readium/r2/testapp/data/BookRepository.kt rename test-app/src/main/java/org/readium/r2/testapp/{catalogs => data}/CatalogRepository.kt (80%) create mode 100644 test-app/src/main/java/org/readium/r2/testapp/data/DownloadRepository.kt rename test-app/src/main/java/org/readium/r2/testapp/{db/BookDatabase.kt => data/db/AppDatabase.kt} (59%) rename test-app/src/main/java/org/readium/r2/testapp/{ => data}/db/BooksDao.kt (95%) rename test-app/src/main/java/org/readium/r2/testapp/{ => data}/db/CatalogDao.kt (94%) create mode 100644 test-app/src/main/java/org/readium/r2/testapp/data/db/DownloadsDao.kt rename test-app/src/main/java/org/readium/r2/testapp/{domain => data}/model/Book.kt (98%) rename test-app/src/main/java/org/readium/r2/testapp/{domain => data}/model/Bookmark.kt (97%) rename test-app/src/main/java/org/readium/r2/testapp/{domain => data}/model/Catalog.kt (95%) create mode 100644 test-app/src/main/java/org/readium/r2/testapp/data/model/Download.kt rename test-app/src/main/java/org/readium/r2/testapp/{domain => data}/model/Highlight.kt (99%) create mode 100644 test-app/src/main/java/org/readium/r2/testapp/domain/Bookshelf.kt create mode 100644 test-app/src/main/java/org/readium/r2/testapp/domain/CoverStorage.kt create mode 100644 test-app/src/main/java/org/readium/r2/testapp/domain/ImportError.kt rename test-app/src/main/java/org/readium/r2/testapp/{ => domain}/PublicationError.kt (93%) create mode 100644 test-app/src/main/java/org/readium/r2/testapp/domain/PublicationRetriever.kt create mode 100644 test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Number.kt diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDownloadsRepository.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDownloadsRepository.kt new file mode 100644 index 0000000000..3d32f9dd06 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpDownloadsRepository.kt @@ -0,0 +1,99 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp + +import android.content.Context +import java.io.File +import java.util.LinkedList +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.json.JSONObject +import org.readium.r2.shared.util.CoroutineQueue + +internal class LcpDownloadsRepository( + context: Context +) { + private val queue = CoroutineQueue() + + private val storageDir: Deferred = + queue.scope.async { + withContext(Dispatchers.IO) { + File(context.noBackupFilesDir, LcpDownloadsRepository::class.qualifiedName!!) + .also { if (!it.exists()) it.mkdirs() } + } + } + + private val storageFile: Deferred = + queue.scope.async { + withContext(Dispatchers.IO) { + File(storageDir.await(), "licenses.json") + .also { if (!it.exists()) { it.writeText("{}", Charsets.UTF_8) } } + } + } + + private val snapshot: Deferred> = + queue.scope.async { + readSnapshot().toMutableMap() + } + + fun addDownload(id: String, license: JSONObject) { + queue.scope.launch { + val snapshotCompleted = snapshot.await() + snapshotCompleted[id] = license + writeSnapshot(snapshotCompleted) + } + } + + fun removeDownload(id: String) { + queue.launch { + val snapshotCompleted = snapshot.await() + snapshotCompleted.remove(id) + writeSnapshot(snapshotCompleted) + } + } + + suspend fun retrieveLicense(id: String): JSONObject? = + queue.await { + snapshot.await()[id] + } + + private suspend fun readSnapshot(): Map { + return withContext(Dispatchers.IO) { + storageFile.await().readText(Charsets.UTF_8).toData().toMutableMap() + } + } + + private suspend fun writeSnapshot(snapshot: Map) { + val storageFileCompleted = storageFile.await() + withContext(Dispatchers.IO) { + storageFileCompleted.writeText(snapshot.toJson(), Charsets.UTF_8) + } + } + + private fun Map.toJson(): String { + val jsonObject = JSONObject() + for ((id, license) in this.entries) { + jsonObject.put(id, license) + } + return jsonObject.toString() + } + + private fun String.toData(): Map { + val jsonObject = JSONObject(this) + val names = jsonObject.keys().iterator().toList() + return names.associateWith { jsonObject.getJSONObject(it) } + } + + private fun Iterator.toList(): List = + LinkedList().apply { + while (hasNext()) + this += next() + }.toMutableList() +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpPublicationRetriever.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpPublicationRetriever.kt new file mode 100644 index 0000000000..eebbe697f2 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpPublicationRetriever.kt @@ -0,0 +1,272 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp + +import android.content.Context +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import org.readium.r2.lcp.license.container.createLicenseContainer +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.downloads.DownloadManager +import org.readium.r2.shared.util.mediatype.FormatRegistry +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever + +/** + * Utility to acquire a protected publication from an LCP License Document. + */ +public class LcpPublicationRetriever( + context: Context, + private val downloadManager: DownloadManager, + private val mediaTypeRetriever: MediaTypeRetriever +) { + + @JvmInline + public value class RequestId(public val value: String) + + public interface Listener { + + /** + * Called when the publication has been successfully acquired. + */ + public fun onAcquisitionCompleted( + requestId: RequestId, + acquiredPublication: LcpService.AcquiredPublication + ) + + /** + * The acquisition with ID [requestId] has downloaded [downloaded] out of [expected] bytes. + */ + public fun onAcquisitionProgressed( + requestId: RequestId, + downloaded: Long, + expected: Long? + ) + + /** + * The acquisition with ID [requestId] has failed with the given [error]. + */ + public fun onAcquisitionFailed( + requestId: RequestId, + error: LcpException + ) + + /** + * The acquisition with ID [requestId] has been cancelled. + */ + public fun onAcquisitionCancelled( + requestId: RequestId + ) + } + + /** + * Submits a new request to acquire the publication protected with the given [license]. + * + * The given [listener] will automatically be registered. + * + * Returns the ID of the acquisition request, which can be used to cancel it. + */ + public fun retrieve( + license: LicenseDocument, + listener: Listener + ): RequestId { + val requestId = fetchPublication(license) + addListener(requestId, listener) + return requestId + } + + /** + * Registers a listener for the acquisition with the given [requestId]. + * + * If the [downloadManager] provided during construction supports background downloading, this + * should typically be used when you create a new instance after the app restarted. + */ + public fun register( + requestId: RequestId, + listener: Listener + ) { + addListener( + requestId, + listener, + onFirstListenerAdded = { + downloadManager.register( + DownloadManager.RequestId(requestId.value), + downloadListener + ) + } + ) + } + + /** + * Cancels the acquisition with the given [requestId]. + */ + public fun cancel(requestId: RequestId) { + downloadManager.cancel(DownloadManager.RequestId(requestId.value)) + downloadsRepository.removeDownload(requestId.value) + } + + /** + * Releases any in-memory resource associated with this [LcpPublicationRetriever]. + * + * If the pending acquisitions cannot continue in the background, they will be cancelled. + */ + public fun close() { + downloadManager.close() + } + + private val coroutineScope: CoroutineScope = + MainScope() + + private val formatRegistry: FormatRegistry = + FormatRegistry() + + private val downloadsRepository: LcpDownloadsRepository = + LcpDownloadsRepository(context) + + private val downloadListener: DownloadManager.Listener = + DownloadListener() + + private val listeners: MutableMap> = + mutableMapOf() + + private fun addListener( + requestId: RequestId, + listener: Listener, + onFirstListenerAdded: () -> Unit = {} + ) { + listeners + .getOrPut(requestId) { + onFirstListenerAdded() + mutableListOf() + } + .add(listener) + } + + private fun fetchPublication( + license: LicenseDocument + ): RequestId { + val url = Url(license.publicationLink.url) + + val requestId = downloadManager.submit( + request = DownloadManager.Request( + url = url, + headers = emptyMap() + ), + listener = downloadListener + ) + + downloadsRepository.addDownload(requestId.value, license.json) + return RequestId(requestId.value) + } + + private inner class DownloadListener : DownloadManager.Listener { + + override fun onDownloadCompleted( + requestId: DownloadManager.RequestId, + download: DownloadManager.Download + ) { + coroutineScope.launch { + val lcpRequestId = RequestId(requestId.value) + val listenersForId = checkNotNull(listeners[lcpRequestId]) + + val license = downloadsRepository.retrieveLicense(requestId.value) + ?.let { LicenseDocument(it) } + ?: run { + listenersForId.forEach { + it.onAcquisitionFailed( + lcpRequestId, + LcpException.wrap( + Exception("Couldn't retrieve license from local storage.") + ) + ) + } + return@launch + } + downloadsRepository.removeDownload(requestId.value) + + val mt = mediaTypeRetriever.retrieve( + mediaTypes = listOfNotNull( + license.publicationLink.type, + download.mediaType.toString() + ) + ) ?: MediaType.EPUB + + try { + // Saves the License Document into the downloaded publication + val container = createLicenseContainer(download.file, mt) + container.write(license) + } catch (e: Exception) { + tryOrLog { download.file.delete() } + listenersForId.forEach { + it.onAcquisitionFailed(lcpRequestId, LcpException.wrap(e)) + } + return@launch + } + + val acquiredPublication = LcpService.AcquiredPublication( + localFile = download.file, + suggestedFilename = "${license.id}.${formatRegistry.fileExtension(mt) ?: "epub"}", + mediaType = mt, + licenseDocument = license + ) + + listenersForId.forEach { + it.onAcquisitionCompleted(lcpRequestId, acquiredPublication) + } + listeners.remove(lcpRequestId) + } + } + + override fun onDownloadProgressed( + requestId: DownloadManager.RequestId, + downloaded: Long, + expected: Long? + ) { + val lcpRequestId = RequestId(requestId.value) + val listenersForId = checkNotNull(listeners[lcpRequestId]) + + listenersForId.forEach { + it.onAcquisitionProgressed( + lcpRequestId, + downloaded, + expected + ) + } + } + + override fun onDownloadFailed( + requestId: DownloadManager.RequestId, + error: DownloadManager.Error + ) { + val lcpRequestId = RequestId(requestId.value) + val listenersForId = checkNotNull(listeners[lcpRequestId]) + + downloadsRepository.removeDownload(requestId.value) + + listenersForId.forEach { + it.onAcquisitionFailed( + lcpRequestId, + LcpException.Network(Exception(error.message)) + ) + } + + listeners.remove(lcpRequestId) + } + + override fun onDownloadCancelled(requestId: DownloadManager.RequestId) { + val lcpRequestId = RequestId(requestId.value) + val listenersForId = checkNotNull(listeners[lcpRequestId]) + listenersForId.forEach { + it.onAcquisitionCancelled(lcpRequestId) + } + listeners.remove(lcpRequestId) + } + } +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt index c8ca96938b..4669a239d2 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt @@ -13,8 +13,6 @@ import android.content.Context import java.io.File import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.readium.r2.lcp.auth.LcpDialogAuthentication import org.readium.r2.lcp.license.model.LicenseDocument @@ -32,6 +30,7 @@ import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.downloads.DownloadManager import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.mediatype.MediaTypeRetriever @@ -57,6 +56,11 @@ public interface LcpService { * * @param onProgress Callback to follow the acquisition progress from 0.0 to 1.0. */ + @Deprecated( + "Use a LcpPublicationRetriever instead.", + ReplaceWith("publicationRetriever()"), + level = DeprecationLevel.ERROR + ) public suspend fun acquirePublication(lcpl: ByteArray, onProgress: (Double) -> Unit = {}): Try /** @@ -66,14 +70,15 @@ public interface LcpService { * * @param onProgress Callback to follow the acquisition progress from 0.0 to 1.0. */ + @Deprecated( + "Use a LcpPublicationRetriever instead.", + ReplaceWith("publicationRetriever()"), + level = DeprecationLevel.ERROR + ) public suspend fun acquirePublication(lcpl: File, onProgress: (Double) -> Unit = {}): Try = withContext( Dispatchers.IO ) { - try { - acquirePublication(lcpl.readBytes(), onProgress) - } catch (e: Exception) { - Try.failure(LcpException.wrap(e)) - } + throw NotImplementedError() } /** @@ -115,6 +120,12 @@ public interface LcpService { sender: Any? ): Try + /** + * Creates an [LcpPublicationRetriever] instance which can be used to acquire a protected + * publication from an LCP License Document. + */ + public fun publicationRetriever(): LcpPublicationRetriever + /** * Creates a [ContentProtection] instance which can be used with a Streamer to unlock * LCP protected publications. @@ -157,7 +168,8 @@ public interface LcpService { public operator fun invoke( context: Context, assetRetriever: AssetRetriever, - mediaTypeRetriever: MediaTypeRetriever + mediaTypeRetriever: MediaTypeRetriever, + downloadManager: DownloadManager ): LcpService? { if (!LcpClient.isAvailable()) { return null @@ -182,7 +194,9 @@ public interface LcpService { network = network, passphrases = passphrases, context = context, - assetRetriever = assetRetriever + assetRetriever = assetRetriever, + mediaTypeRetriever = mediaTypeRetriever, + downloadManager = downloadManager ) } @@ -196,8 +210,8 @@ public interface LcpService { } @Deprecated( - "Use `acquirePublication()` with coroutines instead", - ReplaceWith("acquirePublication(lcpl)"), + "Use a LcpPublicationRetriever instead.", + ReplaceWith("publicationRetriever()"), level = DeprecationLevel.ERROR ) @DelicateCoroutinesApi @@ -206,11 +220,7 @@ public interface LcpService { authentication: LcpAuthenticating?, completion: (AcquiredPublication?, LcpException?) -> Unit ) { - GlobalScope.launch { - acquirePublication(lcpl) - .onSuccess { completion(it, null) } - .onFailure { completion(null, it) } - } + throw NotImplementedError() } @Deprecated( diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt index 0692e18c46..13af2b2bfe 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt @@ -19,6 +19,6 @@ internal class BytesLicenseContainer(private var bytes: ByteArray) : LicenseCont override fun read(): ByteArray = bytes override fun write(license: LicenseDocument) { - bytes = license.data + bytes = license.toByteArray() } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt index 0c36e9cb0e..a5c81de802 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt @@ -27,7 +27,7 @@ internal class LCPLLicenseContainer(private val lcpl: String) : LicenseContainer override fun write(license: LicenseDocument) { try { - File(lcpl).writeBytes(license.data) + File(lcpl).writeBytes(license.toByteArray()) } catch (e: Exception) { throw LcpException.Container.WriteFailed(lcpl) } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt index 85f9ee42be..3ad2096548 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt @@ -52,7 +52,7 @@ internal class ZIPLicenseContainer( if (ZipUtil.containsEntry(tmpZip, pathInZIP)) { ZipUtil.removeEntry(tmpZip, pathInZIP) } - ZipUtil.addEntry(tmpZip, pathInZIP, license.data, source) + ZipUtil.addEntry(tmpZip, pathInZIP, license.toByteArray(), source) tmpZip.delete() } catch (e: Exception) { throw LcpException.Container.WriteFailed(pathInZIP) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt index ea3b6d7733..7df6487d0b 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/model/LicenseDocument.kt @@ -25,17 +25,67 @@ import org.readium.r2.shared.extensions.iso8601ToDate import org.readium.r2.shared.extensions.optNullableString import org.readium.r2.shared.util.mediatype.MediaType -public class LicenseDocument(public val data: ByteArray) { - public val provider: String - public val id: String - public val issued: Date - public val updated: Date - public val encryption: Encryption - public val links: Links - public val user: User - public val rights: Rights - public val signature: Signature - public val json: JSONObject +public class LicenseDocument internal constructor(public val json: JSONObject) { + + public val provider: String = + json.optNullableString("provider") + ?: throw LcpException.Parsing.LicenseDocument + + public val id: String = + json.optNullableString("id") + ?: throw LcpException.Parsing.LicenseDocument + + public val issued: Date = + json.optNullableString("issued") + ?.iso8601ToDate() + ?: throw LcpException.Parsing.LicenseDocument + + public val updated: Date = + json.optNullableString("updated") + ?.iso8601ToDate() + ?: issued + + public val encryption: Encryption = + json.optJSONObject("encryption") + ?.let { Encryption(it) } + ?: throw LcpException.Parsing.LicenseDocument + + public val links: Links = + json.optJSONArray("links") + ?.let { Links(it) } + ?: throw LcpException.Parsing.LicenseDocument + + public val user: User = + User(json.optJSONObject("user") ?: JSONObject()) + + public val rights: Rights = + Rights(json.optJSONObject("rights") ?: JSONObject()) + + public val signature: Signature = + json.optJSONObject("signature") + ?.let { Signature(it) } + ?: throw LcpException.Parsing.LicenseDocument + + init { + if (link(Rel.Hint) == null || link(Rel.Publication) == null) { + throw LcpException.Parsing.LicenseDocument + } + + // Check that the acquisition link has a valid URL. + try { + link(Rel.Publication)!!.url + } catch (e: Exception) { + throw LcpException.Parsing.Url(rel = LicenseDocument.Rel.Publication.value) + } + } + + public constructor(data: ByteArray) : this( + try { + JSONObject(data.decodeToString()) + } catch (e: Exception) { + throw LcpException.Parsing.MalformedJSON + } + ) public enum class Rel(public val value: String) { Hint("hint"), @@ -52,27 +102,8 @@ public class LicenseDocument(public val data: ByteArray) { } } - init { - try { - json = JSONObject(data.toString(Charset.defaultCharset())) - } catch (e: Exception) { - throw LcpException.Parsing.MalformedJSON - } - - provider = json.optNullableString("provider") ?: throw LcpException.Parsing.LicenseDocument - id = json.optNullableString("id") ?: throw LcpException.Parsing.LicenseDocument - issued = json.optNullableString("issued")?.iso8601ToDate() ?: throw LcpException.Parsing.LicenseDocument - encryption = json.optJSONObject("encryption")?.let { Encryption(it) } ?: throw LcpException.Parsing.LicenseDocument - signature = json.optJSONObject("signature")?.let { Signature(it) } ?: throw LcpException.Parsing.LicenseDocument - links = json.optJSONArray("links")?.let { Links(it) } ?: throw LcpException.Parsing.LicenseDocument - updated = json.optNullableString("updated")?.iso8601ToDate() ?: issued - user = User(json.optJSONObject("user") ?: JSONObject()) - rights = Rights(json.optJSONObject("rights") ?: JSONObject()) - - if (link(Rel.Hint) == null || link(Rel.Publication) == null) { - throw LcpException.Parsing.LicenseDocument - } - } + public val publicationLink: Link + get() = link(Rel.Publication)!! public fun link(rel: Rel, type: MediaType? = null): Link? = links.firstWithRel(rel.value, type) @@ -94,4 +125,7 @@ public class LicenseDocument(public val data: ByteArray) { public val description: String get() = "License($id)" + + public fun toByteArray(): ByteArray = + json.toString().toByteArray(Charset.defaultCharset()) } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index b70554299d..ddaabadabd 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -23,6 +23,7 @@ import org.readium.r2.lcp.LcpAuthenticating import org.readium.r2.lcp.LcpContentProtection import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.LcpLicense +import org.readium.r2.lcp.LcpPublicationRetriever import org.readium.r2.lcp.LcpService import org.readium.r2.lcp.license.License import org.readium.r2.lcp.license.LicenseValidation @@ -34,8 +35,10 @@ import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.extensions.tryOr import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.downloads.DownloadManager import org.readium.r2.shared.util.mediatype.FormatRegistry import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever import timber.log.Timber internal class LicensesService( @@ -45,7 +48,9 @@ internal class LicensesService( private val network: NetworkService, private val passphrases: PassphrasesService, private val context: Context, - private val assetRetriever: AssetRetriever + private val assetRetriever: AssetRetriever, + private val mediaTypeRetriever: MediaTypeRetriever, + private val downloadManager: DownloadManager ) : LcpService, CoroutineScope by MainScope() { override suspend fun isLcpProtected(file: File): Boolean { @@ -70,6 +75,19 @@ internal class LicensesService( ): ContentProtection = LcpContentProtection(this, authentication, assetRetriever) + override fun publicationRetriever(): LcpPublicationRetriever { + return LcpPublicationRetriever( + context, + downloadManager, + mediaTypeRetriever + ) + } + + @Deprecated( + "Use a LcpPublicationRetriever instead.", + ReplaceWith("publicationRetriever()"), + level = DeprecationLevel.ERROR + ) override suspend fun acquirePublication(lcpl: ByteArray, onProgress: (Double) -> Unit): Try = try { val licenseDocument = LicenseDocument(lcpl) @@ -190,7 +208,7 @@ internal class LicensesService( } catch (error: Error) { Timber.d("Failed to add the LCP License to the local database: $error") } - if (!licenseDocument.data.contentEquals(initialData)) { + if (!licenseDocument.toByteArray().contentEquals(initialData)) { try { container.write(licenseDocument) Timber.d("licenseDocument ${licenseDocument.json}") diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/CoroutineQueue.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/CoroutineQueue.kt new file mode 100644 index 0000000000..55c149803e --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/CoroutineQueue.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util + +import kotlin.coroutines.resume +import kotlinx.coroutines.CancellableContinuation +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine +import org.readium.r2.shared.InternalReadiumApi + +/** + * Executes coroutines in a sequential order (FIFO). + */ +@InternalReadiumApi +public class CoroutineQueue( + public val scope: CoroutineScope = MainScope() +) { + init { + scope.launch { + for (task in tasks) { + task() + } + } + } + + /** + * Launches a coroutine in the queue. + */ + public fun launch(task: suspend () -> Unit) { + tasks.trySendBlocking(Task(task)).getOrThrow() + } + + /** + * Launches a coroutine in the queue, and waits for its result. + */ + public suspend fun await(task: suspend () -> T): T = + suspendCancellableCoroutine { cont -> + tasks.trySendBlocking(Task(task, cont)).getOrThrow() + } + + /** + * Cancels all the coroutines in the queue. + */ + public fun cancel(cause: CancellationException? = null) { + scope.cancel(cause) + } + + private val tasks: Channel> = Channel(Channel.UNLIMITED) + + private class Task( + val task: suspend () -> T, + val continuation: CancellableContinuation? = null + ) { + suspend operator fun invoke() { + val result = task() + continuation?.resume(result) + } + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt index 5d0e13d260..65adee3494 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/MapCompanion.kt @@ -9,6 +9,8 @@ package org.readium.r2.shared.util +import org.readium.r2.shared.InternalReadiumApi + /** * Encapsulates a [Map] into a more limited query API. * @@ -24,6 +26,7 @@ package org.readium.r2.shared.util * val layout: Layout? = Layout("reflowable") * ``` */ +@InternalReadiumApi public open class MapCompanion(protected val map: Map) { public constructor(elements: Array, keySelector: (E) -> K) : @@ -60,6 +63,7 @@ public open class MapCompanion(protected val map: Map) { /** * Extends a [MapCompanion] by adding a [default] value as a fallback. */ +@InternalReadiumApi public open class MapWithDefaultCompanion(map: Map, public val default: E) : MapCompanion( map ) { diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/DownloadManager.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/DownloadManager.kt new file mode 100644 index 0000000000..2db34a68e7 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/DownloadManager.kt @@ -0,0 +1,139 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.downloads + +import java.io.File +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.downloads.android.AndroidDownloadManager +import org.readium.r2.shared.util.downloads.foreground.ForegroundDownloadManager +import org.readium.r2.shared.util.mediatype.MediaType + +/** + * Manages a set of concurrent files downloaded through HTTP. + * + * Choose the implementation that best fits your needs: + * - [AndroidDownloadManager] for downloading files in the background with the Android system + * service, even if the app is stopped. + * - [ForegroundDownloadManager] for a simpler implementation based on HttpClient which cancels + * the on-going download when the app is closed. + */ +public interface DownloadManager { + + public data class Request( + val url: Url, + val headers: Map> = emptyMap() + ) + + public data class Download( + val file: File, + val mediaType: MediaType + ) + + @JvmInline + public value class RequestId(public val value: String) + + public sealed class Error( + override val message: String, + override val cause: org.readium.r2.shared.util.Error? = null + ) : org.readium.r2.shared.util.Error { + + public class NotFound( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("File not found.", cause) + + public class Unreachable( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("Server is not reachable.", cause) + + public class Server( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("An error occurred on the server-side.", cause) + + public class Forbidden( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("Access to the resource was denied.", cause) + + public class DeviceNotFound( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("The storage device is missing.", cause) + + public class CannotResume( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("Download couldn't be resumed.", cause) + + public class InsufficientSpace( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("There is not enough space to complete the download.", cause) + + public class FileError( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("IO error on the local device.", cause) + + public class HttpData( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("A data error occurred at the HTTP level.", cause) + + public class TooManyRedirects( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("Too many redirects.", cause) + + public class Unknown( + cause: org.readium.r2.shared.util.Error? = null + ) : Error("An unknown error occurred.", cause) + } + + public interface Listener { + + /** + * The download with ID [requestId] has been successfully completed. + */ + public fun onDownloadCompleted(requestId: RequestId, download: Download) + + /** + * The request with ID [requestId] has downloaded [downloaded] out of [expected] bytes. + */ + public fun onDownloadProgressed(requestId: RequestId, downloaded: Long, expected: Long?) + + /** + * The download with ID [requestId] failed due to [error]. + */ + public fun onDownloadFailed(requestId: RequestId, error: Error) + + /** + * The download with ID [requestId] has been cancelled. + */ + public fun onDownloadCancelled(requestId: RequestId) + } + + /** + * Submits a new request to this [DownloadManager]. The given [listener] will automatically be + * registered. + * + * Returns the ID of the download request, which can be used to cancel it. + */ + public fun submit(request: Request, listener: Listener): RequestId + + /** + * Registers a listener for the download with the given [requestId]. + * + * If your [DownloadManager] supports background downloading, this should typically be used when + * you create a new instance after the app restarted. + */ + public fun register(requestId: RequestId, listener: Listener) + + /** + * Cancels the download with the given [requestId]. + */ + public fun cancel(requestId: RequestId) + + /** + * Releases any in-memory resource associated with this [DownloadManager]. + * + * If the pending downloads cannot continue in the background, they will be cancelled. + */ + public fun close() +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/AndroidDownloadManager.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/AndroidDownloadManager.kt new file mode 100644 index 0000000000..d50dfa33e7 --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/AndroidDownloadManager.kt @@ -0,0 +1,311 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.downloads.android + +import android.app.DownloadManager as SystemDownloadManager +import android.content.Context +import android.database.Cursor +import android.net.Uri +import android.os.Environment +import java.io.File +import java.util.UUID +import kotlin.time.Duration.Companion.seconds +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import org.readium.r2.shared.resource.FileResource +import org.readium.r2.shared.units.Hz +import org.readium.r2.shared.units.hz +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.downloads.DownloadManager +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.mediatype.MediaTypeRetriever +import org.readium.r2.shared.util.toUri +import org.readium.r2.shared.util.use + +/** + * A [DownloadManager] implementation using the Android download service. + */ +public class AndroidDownloadManager internal constructor( + private val context: Context, + private val mediaTypeRetriever: MediaTypeRetriever, + private val destStorage: Storage, + private val dirType: String, + private val refreshRate: Hz, + private val allowDownloadsOverMetered: Boolean +) : DownloadManager { + + /** + * Creates a new instance of [AndroidDownloadManager]. + * + * Because of discrepancies across different devices, default notifications are disabled. + * If you want to use this [DownloadManager], you will need permission + * android.permission.DOWNLOAD_WITHOUT_NOTIFICATION. + * + * @param context Android context + * @param destStorage Location where downloads should be stored + * @param refreshRate Frequency with which download status will be checked and + * listeners notified + * @param allowDownloadsOverMetered If downloads must be paused when only metered connexions + * are available + */ + public constructor( + context: Context, + mediaTypeRetriever: MediaTypeRetriever, + destStorage: Storage = Storage.App, + refreshRate: Hz = 60.0.hz, + allowDownloadsOverMetered: Boolean = true + ) : this( + context = context, + mediaTypeRetriever = mediaTypeRetriever, + destStorage = destStorage, + dirType = Environment.DIRECTORY_DOWNLOADS, + refreshRate = refreshRate, + allowDownloadsOverMetered = allowDownloadsOverMetered + ) + + public enum class Storage { + /** + * App internal storage. + */ + App, + + /** + * Shared storage, accessible by users. + */ + Shared; + } + + private val coroutineScope: CoroutineScope = + MainScope() + + private val downloadManager: SystemDownloadManager = + context.getSystemService(Context.DOWNLOAD_SERVICE) as SystemDownloadManager + + private var observeProgressJob: Job? = + null + + private val listeners: MutableMap> = + mutableMapOf() + + public override fun register( + requestId: DownloadManager.RequestId, + listener: DownloadManager.Listener + ) { + listeners.getOrPut(requestId) { mutableListOf() }.add(listener) + + if (observeProgressJob == null) { + maybeStartObservingProgress() + } + } + + public override fun submit( + request: DownloadManager.Request, + listener: DownloadManager.Listener + ): DownloadManager.RequestId { + maybeStartObservingProgress() + + val androidRequest = createRequest( + uri = request.url.toUri(), + filename = generateFileName(extension = request.url.extension), + headers = request.headers + ) + val downloadId = downloadManager.enqueue(androidRequest) + val requestId = DownloadManager.RequestId(downloadId.toString()) + register(requestId, listener) + return requestId + } + + private fun generateFileName(extension: String?): String { + val dottedExtension = extension + ?.let { ".$it" } + .orEmpty() + return "${UUID.randomUUID()}$dottedExtension}" + } + + public override fun cancel(requestId: DownloadManager.RequestId) { + val longId = requestId.value.toLong() + downloadManager.remove(longId) + val listenersForId = listeners[requestId].orEmpty() + listenersForId.forEach { it.onDownloadCancelled(requestId) } + listeners.remove(requestId) + if (!listeners.any { it.value.isNotEmpty() }) { + maybeStopObservingProgress() + } + } + + private fun createRequest( + uri: Uri, + filename: String, + headers: Map> + ): SystemDownloadManager.Request = + SystemDownloadManager.Request(uri) + .setNotificationVisibility(SystemDownloadManager.Request.VISIBILITY_HIDDEN) + .setDestination(filename) + .setHeaders(headers) + .setAllowedOverMetered(allowDownloadsOverMetered) + + private fun SystemDownloadManager.Request.setHeaders( + headers: Map> + ): SystemDownloadManager.Request { + for (header in headers) { + for (value in header.value) { + addRequestHeader(header.key, value) + } + } + return this + } + + private fun SystemDownloadManager.Request.setDestination( + filename: String + ): SystemDownloadManager.Request { + when (destStorage) { + Storage.App -> + setDestinationInExternalFilesDir(context, dirType, filename) + + Storage.Shared -> + setDestinationInExternalPublicDir(dirType, filename) + } + return this + } + + private fun maybeStartObservingProgress() { + if (observeProgressJob != null || listeners.all { it.value.isEmpty() }) { + return + } + + observeProgressJob = coroutineScope.launch { + while (true) { + val cursor = downloadManager.query(SystemDownloadManager.Query()) + notify(cursor) + delay((1.0 / refreshRate.value).seconds) + } + } + } + + private fun maybeStopObservingProgress() { + if (listeners.all { it.value.isEmpty() }) { + observeProgressJob?.cancel() + observeProgressJob = null + } + } + + private fun notify(cursor: Cursor) = cursor.use { + val knownDownloads = mutableSetOf() + + // Notify about known downloads + while (cursor.moveToNext()) { + val facade = DownloadCursorFacade(cursor) + val id = DownloadManager.RequestId(facade.id.toString()) + val listenersForId = listeners[id].orEmpty() + if (listenersForId.isNotEmpty()) { + notifyDownload(id, facade, listenersForId) + } + knownDownloads.add(id) + } + + // Missing downloads have been cancelled. + val unknownDownloads = listeners - knownDownloads + unknownDownloads.forEach { entry -> + entry.value.forEach { it.onDownloadCancelled(entry.key) } + listeners.remove(entry.key) + } + maybeStopObservingProgress() + } + + private fun notifyDownload( + id: DownloadManager.RequestId, + facade: DownloadCursorFacade, + listenersForId: List + ) { + when (facade.status) { + SystemDownloadManager.STATUS_FAILED -> { + listenersForId.forEach { + it.onDownloadFailed(id, mapErrorCode(facade.reason!!)) + } + downloadManager.remove(facade.id) + listeners.remove(id) + maybeStopObservingProgress() + } + SystemDownloadManager.STATUS_PAUSED -> {} + SystemDownloadManager.STATUS_PENDING -> {} + SystemDownloadManager.STATUS_SUCCESSFUL -> { + coroutineScope.launch { + prepareResult(Uri.parse(facade.localUri)!!) + .onSuccess { download -> + listenersForId.forEach { it.onDownloadCompleted(id, download) } + }.onFailure { error -> + listenersForId.forEach { it.onDownloadFailed(id, error) } + } + } + downloadManager.remove(facade.id) + listeners.remove(id) + maybeStopObservingProgress() + } + SystemDownloadManager.STATUS_RUNNING -> { + listenersForId.forEach { + it.onDownloadProgressed(id, facade.downloadedSoFar, facade.expected) + } + } + } + } + + private suspend fun prepareResult(destUri: Uri): Try { + val destFile = File(destUri.path!!) + val mediaType = FileResource(destFile, mediaTypeRetriever).use { + it.mediaType().getOrElse { return Try.failure(DownloadManager.Error.FileError()) } + } + val newDest = File(destFile.parent, generateFileName(destFile.extension)) + return if (destFile.renameTo(newDest)) { + val download = DownloadManager.Download( + file = newDest, + mediaType = mediaType + ) + Try.success(download) + } else { + Try.failure(DownloadManager.Error.FileError()) + } + } + + private fun mapErrorCode(code: Int): DownloadManager.Error = + when (code) { + 401, 403 -> + DownloadManager.Error.Forbidden() + 404 -> + DownloadManager.Error.NotFound() + 500, 501 -> + DownloadManager.Error.Server() + 502, 503, 504 -> + DownloadManager.Error.Unreachable() + SystemDownloadManager.ERROR_CANNOT_RESUME -> + DownloadManager.Error.CannotResume() + SystemDownloadManager.ERROR_DEVICE_NOT_FOUND -> + DownloadManager.Error.DeviceNotFound() + SystemDownloadManager.ERROR_FILE_ERROR -> + DownloadManager.Error.FileError() + SystemDownloadManager.ERROR_HTTP_DATA_ERROR -> + DownloadManager.Error.HttpData() + SystemDownloadManager.ERROR_INSUFFICIENT_SPACE -> + DownloadManager.Error.InsufficientSpace() + SystemDownloadManager.ERROR_TOO_MANY_REDIRECTS -> + DownloadManager.Error.TooManyRedirects() + SystemDownloadManager.ERROR_UNHANDLED_HTTP_CODE -> + DownloadManager.Error.Unknown() + SystemDownloadManager.ERROR_UNKNOWN -> + DownloadManager.Error.Unknown() + else -> + DownloadManager.Error.Unknown() + } + + public override fun close() { + listeners.clear() + coroutineScope.cancel() + } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/DownloadCursorFacade.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/DownloadCursorFacade.kt new file mode 100644 index 0000000000..9096032cba --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/android/DownloadCursorFacade.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.downloads.android + +import android.app.DownloadManager +import android.database.Cursor + +internal class DownloadCursorFacade( + private val cursor: Cursor +) { + + val id: Long = cursor + .getColumnIndex(DownloadManager.COLUMN_ID) + .also { require(it != -1) } + .let { cursor.getLong(it) } + + val localUri: String? = cursor + .getColumnIndex(DownloadManager.COLUMN_LOCAL_URI) + .also { require(it != -1) } + .takeUnless { cursor.isNull(it) } + ?.let { cursor.getString(it) } + + val status: Int = cursor + .getColumnIndex(DownloadManager.COLUMN_STATUS) + .also { require(it != -1) } + .let { cursor.getInt(it) } + + val expected: Long? = cursor + .getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES) + .also { require(it != -1) } + .takeUnless { cursor.isNull(it) } + ?.let { cursor.getLong(it) } + ?.takeUnless { it == -1L } + + val downloadedSoFar: Long = cursor + .getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR) + .also { require(it != -1) } + .let { cursor.getLong(it) } + + val mediaType: String? = cursor + .getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE) + .also { require(it != -1) } + .takeUnless { cursor.isNull(it) } + ?.let { cursor.getString(it) } + + val reason: Int? = cursor + .getColumnIndex(DownloadManager.COLUMN_REASON) + .also { require(it != -1) } + .takeIf { status == DownloadManager.STATUS_FAILED || status == DownloadManager.STATUS_PAUSED } + ?.let { cursor.getInt(it) } +} diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/foreground/ForegroundDownloadManager.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/foreground/ForegroundDownloadManager.kt new file mode 100644 index 0000000000..dd1c493f0f --- /dev/null +++ b/readium/shared/src/main/java/org/readium/r2/shared/util/downloads/foreground/ForegroundDownloadManager.kt @@ -0,0 +1,194 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.shared.util.downloads.foreground + +import java.io.File +import java.io.FileOutputStream +import java.util.UUID +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.readium.r2.shared.extensions.tryOrLog +import org.readium.r2.shared.util.ThrowableError +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.downloads.DownloadManager +import org.readium.r2.shared.util.flatMap +import org.readium.r2.shared.util.http.HttpClient +import org.readium.r2.shared.util.http.HttpException +import org.readium.r2.shared.util.http.HttpRequest +import org.readium.r2.shared.util.http.HttpResponse +import org.readium.r2.shared.util.http.HttpTry + +/** + * A [DownloadManager] implementation using a [HttpClient]. + * + * If the app is killed, downloads will stop and you won't be able to resume them later. + */ +public class ForegroundDownloadManager( + private val httpClient: HttpClient, + private val bufferLength: Int = 1024 * 8 +) : DownloadManager { + + private val coroutineScope: CoroutineScope = + MainScope() + + private val jobs: MutableMap = + mutableMapOf() + + private val listeners: MutableMap> = + mutableMapOf() + + public override fun submit( + request: DownloadManager.Request, + listener: DownloadManager.Listener + ): DownloadManager.RequestId { + val requestId = DownloadManager.RequestId(UUID.randomUUID().toString()) + register(requestId, listener) + jobs[requestId] = coroutineScope.launch { doRequest(request, requestId) } + return requestId + } + + private suspend fun doRequest(request: DownloadManager.Request, id: DownloadManager.RequestId) { + val destination = withContext(Dispatchers.IO) { + File.createTempFile(UUID.randomUUID().toString(), null) + } + + httpClient + .download( + request = HttpRequest( + url = request.url.toString(), + headers = request.headers.mapValues { it.value.joinToString(",") } + ), + destination = destination, + onProgress = { downloaded, expected -> + forEachListener(id) { + onDownloadProgressed(id, downloaded = downloaded, expected = expected) + } + } + ) + .onSuccess { response -> + forEachListener(id) { + onDownloadCompleted( + id, + DownloadManager.Download( + file = destination, + mediaType = response.mediaType + ) + ) + } + } + .onFailure { error -> + forEachListener(id) { + onDownloadFailed(id, mapError(error)) + } + } + + listeners.remove(id) + } + + private fun forEachListener( + id: DownloadManager.RequestId, + task: DownloadManager.Listener.() -> Unit + ) { + listeners[id].orEmpty().forEach { + tryOrLog { it.task() } + } + } + + public override fun cancel(requestId: DownloadManager.RequestId) { + jobs.remove(requestId)?.cancel() + forEachListener(requestId) { onDownloadCancelled(requestId) } + listeners.remove(requestId) + } + + public override fun register( + requestId: DownloadManager.RequestId, + listener: DownloadManager.Listener + ) { + listeners.getOrPut(requestId) { mutableListOf() }.add(listener) + } + + public override fun close() { + jobs.forEach { cancel(it.key) } + } + + private suspend fun HttpClient.download( + request: HttpRequest, + destination: File, + onProgress: (downloaded: Long, expected: Long?) -> Unit + ): HttpTry = + try { + stream(request).flatMap { res -> + withContext(Dispatchers.IO) { + val expected = res.response.contentLength?.takeIf { it > 0 } + + res.body.use { input -> + FileOutputStream(destination).use { output -> + val buf = ByteArray(bufferLength) + var n: Int + var downloadedBytes = 0L + while (-1 != input.read(buf).also { n = it }) { + ensureActive() + downloadedBytes += n + output.write(buf, 0, n) + onProgress(downloadedBytes, expected) + } + } + } + + Try.success(res.response) + } + } + } catch (e: Exception) { + Try.failure(HttpException.wrap(e)) + } + + private fun mapError(httpException: HttpException): DownloadManager.Error { + val httpError = ThrowableError(httpException) + return when (httpException.kind) { + HttpException.Kind.MalformedRequest -> + DownloadManager.Error.Unknown(httpError) + + HttpException.Kind.MalformedResponse -> + DownloadManager.Error.HttpData(httpError) + + HttpException.Kind.Timeout -> + DownloadManager.Error.Unreachable(httpError) + + HttpException.Kind.BadRequest -> + DownloadManager.Error.Unknown(httpError) + + HttpException.Kind.Unauthorized -> + DownloadManager.Error.Forbidden(httpError) + + HttpException.Kind.Forbidden -> + DownloadManager.Error.Forbidden(httpError) + + HttpException.Kind.NotFound -> + DownloadManager.Error.NotFound(httpError) + + HttpException.Kind.ClientError -> + DownloadManager.Error.HttpData(httpError) + + HttpException.Kind.ServerError -> + DownloadManager.Error.Server(httpError) + + HttpException.Kind.Offline -> + DownloadManager.Error.Unreachable(httpError) + + HttpException.Kind.Cancelled -> + DownloadManager.Error.Unknown(httpError) + + HttpException.Kind.Other -> + DownloadManager.Error.Unknown(httpError) + } + } +} diff --git a/test-app/src/main/AndroidManifest.xml b/test-app/src/main/AndroidManifest.xml index 5865b76456..157f4461e2 100644 --- a/test-app/src/main/AndroidManifest.xml +++ b/test-app/src/main/AndroidManifest.xml @@ -13,6 +13,7 @@ + diff --git a/test-app/src/main/java/org/readium/r2/testapp/Application.kt b/test-app/src/main/java/org/readium/r2/testapp/Application.kt index 9b2f24ac04..0b050f14fa 100755 --- a/test-app/src/main/java/org/readium/r2/testapp/Application.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/Application.kt @@ -6,17 +6,28 @@ package org.readium.r2.testapp -import android.content.* +import android.content.Context import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.preferencesDataStore import com.google.android.material.color.DynamicColors import java.io.File -import java.util.* -import kotlinx.coroutines.* +import java.util.Properties +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.async import org.readium.r2.testapp.BuildConfig.DEBUG -import org.readium.r2.testapp.bookshelf.BookRepository -import org.readium.r2.testapp.db.BookDatabase +import org.readium.r2.testapp.data.BookRepository +import org.readium.r2.testapp.data.DownloadRepository +import org.readium.r2.testapp.data.db.AppDatabase +import org.readium.r2.testapp.data.model.Download +import org.readium.r2.testapp.domain.Bookshelf +import org.readium.r2.testapp.domain.CoverStorage +import org.readium.r2.testapp.domain.LcpPublicationRetriever +import org.readium.r2.testapp.domain.LocalPublicationRetriever +import org.readium.r2.testapp.domain.OpdsPublicationRetriever +import org.readium.r2.testapp.domain.PublicationRetriever import org.readium.r2.testapp.reader.ReaderRepository import timber.log.Timber @@ -30,6 +41,9 @@ class Application : android.app.Application() { lateinit var bookRepository: BookRepository private set + lateinit var bookshelf: Bookshelf + private set + lateinit var readerRepository: Deferred private set @@ -48,23 +62,55 @@ class Application : android.app.Application() { storageDir = computeStorageDir() - /* - * Initializing repositories - */ - bookRepository = - BookDatabase.getDatabase(this).booksDao() - .let { dao -> - BookRepository( - applicationContext, - dao, - storageDir, - readium.lcpService, - readium.publicationFactory, - readium.assetRetriever, - readium.protectionRetriever, - readium.formatRegistry + val database = AppDatabase.getDatabase(this) + + bookRepository = BookRepository(database.booksDao()) + + bookshelf = + Bookshelf( + bookRepository, + CoverStorage(storageDir), + readium.publicationFactory, + readium.assetRetriever, + readium.protectionRetriever, + createPublicationRetriever = { listener -> + PublicationRetriever( + listener = listener, + createLocalPublicationRetriever = { localListener -> + LocalPublicationRetriever( + listener = localListener, + context = applicationContext, + storageDir = storageDir, + assetRetriever = readium.assetRetriever, + formatRegistry = readium.formatRegistry, + createLcpPublicationRetriever = { lcpListener -> + readium.lcpService.getOrNull()?.publicationRetriever() + ?.let { retriever -> + LcpPublicationRetriever( + listener = lcpListener, + downloadRepository = DownloadRepository( + Download.Type.LCP, + database.downloadsDao() + ), + lcpPublicationRetriever = retriever + ) + } + } + ) + }, + createOpdsPublicationRetriever = { opdsListener -> + OpdsPublicationRetriever( + listener = opdsListener, + downloadManager = readium.downloadManager, + downloadRepository = DownloadRepository( + Download.Type.OPDS, + database.downloadsDao() + ) + ) + } ) } + ) readerRepository = coroutineScope.async { diff --git a/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt b/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt index 219afb408d..f82908b690 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt @@ -15,19 +15,19 @@ import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController import com.google.android.material.bottomnavigation.BottomNavigationView -import org.readium.r2.testapp.bookshelf.BookshelfViewModel +import com.google.android.material.snackbar.Snackbar class MainActivity : AppCompatActivity() { private lateinit var navController: NavController - private val viewModel: BookshelfViewModel by viewModels() + private val viewModel: MainViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) intent.data?.let { - viewModel.importPublicationFromUri(it) + viewModel.importPublicationFromStorage(it) } val navView: BottomNavigationView = findViewById(R.id.nav_view) @@ -44,9 +44,28 @@ class MainActivity : AppCompatActivity() { ) setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) + + viewModel.channel.receive(this) { handleEvent(it) } } override fun onSupportNavigateUp(): Boolean { return navController.navigateUp() || super.onSupportNavigateUp() } + + private fun handleEvent(event: MainViewModel.Event) { + val message = + when (event) { + is MainViewModel.Event.ImportPublicationSuccess -> + getString(R.string.import_publication_success) + + is MainViewModel.Event.ImportPublicationError -> { + event.errorMessage + } + } + Snackbar.make( + findViewById(android.R.id.content), + message, + Snackbar.LENGTH_LONG + ).show() + } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/MainViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/MainViewModel.kt new file mode 100644 index 0000000000..81e0a5ced0 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/MainViewModel.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp + +import android.app.Application +import android.net.Uri +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch +import org.readium.r2.testapp.domain.Bookshelf +import org.readium.r2.testapp.utils.EventChannel + +class MainViewModel( + application: Application +) : AndroidViewModel(application) { + + private val app = + getApplication() + + val channel: EventChannel = + EventChannel(Channel(Channel.UNLIMITED), viewModelScope) + + init { + app.bookshelf.channel.receiveAsFlow() + .onEach { sendImportFeedback(it) } + .launchIn(viewModelScope) + } + fun importPublicationFromStorage(uri: Uri) = + viewModelScope.launch { + app.bookshelf.importPublicationFromStorage(uri) + } + + private fun sendImportFeedback(event: Bookshelf.Event) { + when (event) { + is Bookshelf.Event.ImportPublicationError -> { + val errorMessage = event.error.getUserMessage(app) + channel.send(Event.ImportPublicationError(errorMessage)) + } + Bookshelf.Event.ImportPublicationSuccess -> { + channel.send(Event.ImportPublicationSuccess) + } + } + } + + sealed class Event { + + object ImportPublicationSuccess : + Event() + + class ImportPublicationError( + val errorMessage: String + ) : Event() + } +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt index 82b1c0a1d4..d3f5741111 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/Readium.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/Readium.kt @@ -8,10 +8,10 @@ package org.readium.r2.testapp import android.content.Context import org.readium.adapters.pdfium.document.PdfiumDocumentFactory +import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.LcpService import org.readium.r2.navigator.preferences.FontFamily import org.readium.r2.shared.ExperimentalReadiumApi -import org.readium.r2.shared.UserException import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.publication.protection.ContentProtectionSchemeRetriever import org.readium.r2.shared.resource.CompositeArchiveFactory @@ -22,6 +22,7 @@ import org.readium.r2.shared.resource.DirectoryContainerFactory import org.readium.r2.shared.resource.FileResourceFactory import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.archive.channel.ChannelZipArchiveFactory +import org.readium.r2.shared.util.downloads.android.AndroidDownloadManager import org.readium.r2.shared.util.http.DefaultHttpClient import org.readium.r2.shared.util.http.HttpResourceFactory import org.readium.r2.shared.util.mediatype.FormatRegistry @@ -66,13 +67,23 @@ class Readium(context: Context) { context.contentResolver ) + val downloadManager = AndroidDownloadManager( + context = context, + mediaTypeRetriever = mediaTypeRetriever, + destStorage = AndroidDownloadManager.Storage.App + ) + /** * The LCP service decrypts LCP-protected publication and acquire publications from a * license file. */ - val lcpService = LcpService(context, assetRetriever, mediaTypeRetriever) - ?.let { Try.success(it) } - ?: Try.failure(UserException("liblcp is missing on the classpath")) + val lcpService = LcpService( + context, + assetRetriever, + mediaTypeRetriever, + downloadManager + )?.let { Try.success(it) } + ?: Try.failure(LcpException.Unknown(Exception("liblcp is missing on the classpath"))) private val contentProtections = listOfNotNull( lcpService.getOrNull()?.contentProtection() diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt deleted file mode 100644 index 326aa67497..0000000000 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookRepository.kt +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright 2021 Readium Foundation. All rights reserved. - * Use of this source code is governed by the BSD-style license - * available in the top-level LICENSE file of the project. - */ - -package org.readium.r2.testapp.bookshelf - -import android.content.Context -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.net.Uri -import androidx.annotation.ColorInt -import androidx.annotation.StringRes -import androidx.lifecycle.LiveData -import java.io.File -import java.io.FileOutputStream -import java.io.IOException -import java.net.HttpURLConnection -import java.net.URL -import java.util.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.withContext -import org.joda.time.DateTime -import org.readium.r2.lcp.LcpService -import org.readium.r2.shared.UserException -import org.readium.r2.shared.asset.Asset -import org.readium.r2.shared.asset.AssetRetriever -import org.readium.r2.shared.asset.AssetType -import org.readium.r2.shared.publication.Locator -import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.indexOfFirstWithHref -import org.readium.r2.shared.publication.protection.ContentProtection -import org.readium.r2.shared.publication.protection.ContentProtectionSchemeRetriever -import org.readium.r2.shared.publication.services.cover -import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.flatMap -import org.readium.r2.shared.util.getOrElse -import org.readium.r2.shared.util.mediatype.FormatRegistry -import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.shared.util.toUrl -import org.readium.r2.streamer.PublicationFactory -import org.readium.r2.testapp.PublicationError -import org.readium.r2.testapp.R -import org.readium.r2.testapp.db.BooksDao -import org.readium.r2.testapp.domain.model.Book -import org.readium.r2.testapp.domain.model.Bookmark -import org.readium.r2.testapp.domain.model.Highlight -import org.readium.r2.testapp.utils.extensions.authorName -import org.readium.r2.testapp.utils.extensions.copyToTempFile -import org.readium.r2.testapp.utils.extensions.moveTo -import org.readium.r2.testapp.utils.tryOrLog -import org.readium.r2.testapp.utils.tryOrNull -import timber.log.Timber - -class BookRepository( - private val context: Context, - private val booksDao: BooksDao, - private val storageDir: File, - private val lcpService: Try, - private val publicationFactory: PublicationFactory, - private val assetRetriever: AssetRetriever, - private val protectionRetriever: ContentProtectionSchemeRetriever, - private val formatRegistry: FormatRegistry -) { - private val coverDir: File = - File(storageDir, "covers/") - .apply { if (!exists()) mkdirs() } - - fun books(): LiveData> = booksDao.getAllBooks() - - suspend fun get(id: Long) = booksDao.get(id) - - suspend fun saveProgression(locator: Locator, bookId: Long) = - booksDao.saveProgression(locator.toJSON().toString(), bookId) - - suspend fun insertBookmark(bookId: Long, publication: Publication, locator: Locator): Long { - val resource = publication.readingOrder.indexOfFirstWithHref(locator.href)!! - val bookmark = Bookmark( - creation = DateTime().toDate().time, - bookId = bookId, - resourceIndex = resource.toLong(), - resourceHref = locator.href, - resourceType = locator.type, - resourceTitle = locator.title.orEmpty(), - location = locator.locations.toJSON().toString(), - locatorText = Locator.Text().toJSON().toString() - ) - - return booksDao.insertBookmark(bookmark) - } - - fun bookmarksForBook(bookId: Long): LiveData> = - booksDao.getBookmarksForBook(bookId) - - suspend fun deleteBookmark(bookmarkId: Long) = booksDao.deleteBookmark(bookmarkId) - - suspend fun highlightById(id: Long): Highlight? = - booksDao.getHighlightById(id) - - fun highlightsForBook(bookId: Long): Flow> = - booksDao.getHighlightsForBook(bookId) - - suspend fun addHighlight( - bookId: Long, - style: Highlight.Style, - @ColorInt tint: Int, - locator: Locator, - annotation: String - ): Long = - booksDao.insertHighlight(Highlight(bookId, style, tint, locator, annotation)) - - suspend fun deleteHighlight(id: Long) = booksDao.deleteHighlight(id) - - suspend fun updateHighlightAnnotation(id: Long, annotation: String) { - booksDao.updateHighlightAnnotation(id, annotation) - } - - suspend fun updateHighlightStyle(id: Long, style: Highlight.Style, @ColorInt tint: Int) { - booksDao.updateHighlightStyle(id, style, tint) - } - - private suspend fun insertBookIntoDatabase( - href: String, - mediaType: MediaType, - assetType: AssetType, - drm: ContentProtection.Scheme?, - publication: Publication, - cover: String - ): Long { - val book = Book( - creation = DateTime().toDate().time, - title = publication.metadata.title, - author = publication.metadata.authorName, - href = href, - identifier = publication.metadata.identifier ?: "", - mediaType = mediaType, - assetType = assetType, - drm = drm, - progression = "{}", - cover = cover - ) - return booksDao.insertBook(book) - } - - private suspend fun deleteBookFromDatabase(id: Long) = - booksDao.deleteBook(id) - - sealed class ImportError( - content: Content, - cause: Exception? - ) : UserException(content, cause) { - - constructor(@StringRes userMessageId: Int) : - this(Content(userMessageId), null) - - constructor(cause: UserException) : - this(Content(cause), cause) - - class LcpAcquisitionFailed( - override val cause: UserException - ) : ImportError(cause) - - class PublicationError( - override val cause: UserException - ) : ImportError(cause) { - - companion object { - - operator fun invoke( - error: AssetRetriever.Error - ): ImportError = PublicationError(org.readium.r2.testapp.PublicationError(error)) - - operator fun invoke( - error: Publication.OpeningException - ): ImportError = PublicationError(org.readium.r2.testapp.PublicationError(error)) - } - } - - class ImportBookFailed( - override val cause: Throwable - ) : ImportError(R.string.import_publication_unexpected_io_exception) - - class ImportDatabaseFailed : - ImportError(R.string.import_publication_unable_add_pub_database) - } - - suspend fun importBook( - contentUri: Uri - ): Try = - contentUri.copyToTempFile(context, storageDir) - .mapFailure { ImportError.ImportBookFailed(it) } - .flatMap { addLocalBook(it) } - - suspend fun addRemoteBook( - url: Url - ): Try { - val asset = assetRetriever.retrieve(url) - ?: return Try.failure( - ImportError.PublicationError( - PublicationError.UnsupportedPublication( - Publication.OpeningException.UnsupportedAsset() - ) - ) - ) - return addBook(url, asset) - } - - suspend fun addSharedStorageBook( - url: Url, - coverUrl: String? = null - ): Try { - val asset = assetRetriever.retrieve(url) - ?: return Try.failure( - ImportError.PublicationError( - PublicationError.UnsupportedPublication( - Publication.OpeningException.UnsupportedAsset("Unsupported media type") - ) - ) - ) - - return addBook(url, asset, coverUrl) - } - - suspend fun addLocalBook( - tempFile: File, - coverUrl: String? = null - ): Try { - val sourceAsset = assetRetriever.retrieve(tempFile) - ?: return Try.failure( - ImportError.PublicationError( - PublicationError.UnsupportedPublication( - Publication.OpeningException.UnsupportedAsset() - ) - ) - ) - - val (publicationTempFile, publicationTempAsset) = - if (sourceAsset.mediaType != MediaType.LCP_LICENSE_DOCUMENT) { - tempFile to sourceAsset - } else { - lcpService - .flatMap { - sourceAsset.close() - it.acquirePublication(tempFile) - } - .fold( - { - val file = it.localFile - val asset = assetRetriever.retrieve( - file.toUrl(), - assetType = AssetType.Archive, - mediaType = it.mediaType - ).getOrElse { error -> - return Try.failure(ImportError.PublicationError(error)) - } - file to asset - }, - { - tryOrNull { tempFile.delete() } - return Try.failure(ImportError.LcpAcquisitionFailed(it)) - } - ) - } - - val fileExtension = formatRegistry.fileExtension(publicationTempAsset.mediaType) ?: "epub" - val fileName = "${UUID.randomUUID()}.$fileExtension" - val libraryFile = File(storageDir, fileName) - val libraryUrl = libraryFile.toUrl() - - try { - publicationTempFile.moveTo(libraryFile) - } catch (e: Exception) { - Timber.d(e) - tryOrNull { libraryFile.delete() } - return Try.failure(ImportError.ImportBookFailed(e)) - } - - val libraryAsset = assetRetriever.retrieve( - libraryUrl, - publicationTempAsset.mediaType, - publicationTempAsset.assetType - ).getOrElse { return Try.failure(ImportError.PublicationError(it)) } - - return addBook( - libraryUrl, - libraryAsset, - coverUrl - ).onFailure { - tryOrNull { libraryFile.delete() } - } - } - - private suspend fun addBook( - url: Url, - asset: Asset, - coverUrl: String? = null - ): Try { - val drmScheme = - protectionRetriever.retrieve(asset) - - publicationFactory.open( - asset, - contentProtectionScheme = drmScheme, - allowUserInteraction = false - ).onSuccess { publication -> - val coverBitmap: Bitmap? = coverUrl - ?.let { getBitmapFromURL(it) } - ?: publication.cover() - val coverFile = - try { - storeCover(coverBitmap) - } catch (e: Exception) { - return Try.failure(ImportError.ImportBookFailed(e)) - } - - val id = insertBookIntoDatabase( - url.toString(), - asset.mediaType, - asset.assetType, - drmScheme, - publication, - coverFile.path - ) - if (id == -1L) { - coverFile.delete() - return Try.failure(ImportError.ImportDatabaseFailed()) - } - } - .onFailure { - Timber.d("Cannot open publication: $it.") - return Try.failure( - ImportError.PublicationError(PublicationError(it)) - ) - } - - return Try.success(Unit) - } - - private suspend fun storeCover(cover: Bitmap?): File = - withContext(Dispatchers.IO) { - val coverImageFile = File(coverDir, "${UUID.randomUUID()}.png") - val resized = cover?.let { Bitmap.createScaledBitmap(it, 120, 200, true) } - val fos = FileOutputStream(coverImageFile) - resized?.compress(Bitmap.CompressFormat.PNG, 80, fos) - fos.flush() - fos.close() - coverImageFile - } - - private suspend fun getBitmapFromURL(src: String): Bitmap? = - withContext(Dispatchers.IO) { - try { - val url = URL(src) - val connection = url.openConnection() as HttpURLConnection - connection.doInput = true - connection.connect() - val input = connection.inputStream - BitmapFactory.decodeStream(input) - } catch (e: IOException) { - e.printStackTrace() - null - } - } - - suspend fun deleteBook(book: Book) { - val id = book.id!! - val url = Url(book.href)!! - if (url.scheme == "file") { - tryOrLog { File(url.path).delete() } - } - File(book.cover).delete() - deleteBookFromDatabase(id) - } -} diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt index 47d3af18d8..4d1016a3be 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfAdapter.kt @@ -14,8 +14,8 @@ import androidx.recyclerview.widget.RecyclerView import com.squareup.picasso.Picasso import java.io.File import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Book import org.readium.r2.testapp.databinding.ItemRecycleBookBinding -import org.readium.r2.testapp.domain.model.Book import org.readium.r2.testapp.utils.singleClick class BookshelfAdapter( diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt index e6b3bc1f3f..02b8c2b4c5 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfFragment.kt @@ -17,7 +17,6 @@ import android.webkit.URLUtil import android.widget.EditText import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.RecyclerView @@ -25,8 +24,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import org.readium.r2.shared.util.Url import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Book import org.readium.r2.testapp.databinding.FragmentBookshelfBinding -import org.readium.r2.testapp.domain.model.Book import org.readium.r2.testapp.opds.GridAutoFitLayoutManager import org.readium.r2.testapp.reader.ReaderActivityContract import org.readium.r2.testapp.utils.viewLifecycle @@ -68,8 +67,7 @@ class BookshelfFragment : Fragment() { appStoragePickerLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? -> uri?.let { - binding.bookshelfProgressBar.visibility = View.VISIBLE - bookshelfViewModel.importPublicationFromUri(it) + bookshelfViewModel.importPublicationFromStorage(it) } } @@ -78,8 +76,7 @@ class BookshelfFragment : Fragment() { uri?.let { val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION requireContext().contentResolver.takePersistableUriPermission(uri, takeFlags) - binding.bookshelfProgressBar.visibility = View.VISIBLE - bookshelfViewModel.addSharedStoragePublication(it) + bookshelfViewModel.addPublicationFromStorage(it) } } @@ -98,7 +95,6 @@ class BookshelfFragment : Fragment() { bookshelfAdapter.submitList(it) } - // FIXME embedded dialogs like this are ugly binding.bookshelfAddBookFab.setOnClickListener { var selected = 0 MaterialAlertDialogBuilder(requireContext()) @@ -107,33 +103,10 @@ class BookshelfFragment : Fragment() { dialog.cancel() } .setPositiveButton(getString(R.string.ok)) { _, _ -> - when (selected) { 0 -> appStoragePickerLauncher.launch("*/*") 1 -> sharedStoragePickerLauncher.launch(arrayOf("*/*")) - else -> { - val urlEditText = EditText(requireContext()) - val urlDialog = MaterialAlertDialogBuilder(requireContext()) - .setTitle(getString(R.string.add_book)) - .setMessage(R.string.enter_url) - .setView(urlEditText) - .setNegativeButton(R.string.cancel) { dialog, _ -> - dialog.cancel() - } - .setPositiveButton(getString(R.string.ok), null) - .show() - urlDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - val url = Url(urlEditText.text.toString()) - if (url == null || !URLUtil.isValidUrl(urlEditText.text.toString())) { - urlEditText.error = getString(R.string.invalid_url) - return@setOnClickListener - } - - binding.bookshelfProgressBar.visibility = View.VISIBLE - bookshelfViewModel.addRemotePublication(url) - urlDialog.dismiss() - } - } + else -> askForRemoteUrl() } } .setSingleChoiceItems(R.array.documentSelectorArray, 0) { _, which -> @@ -143,16 +116,30 @@ class BookshelfFragment : Fragment() { } } + private fun askForRemoteUrl() { + val urlEditText = EditText(requireContext()) + MaterialAlertDialogBuilder(requireContext()) + .setTitle(getString(R.string.add_book)) + .setMessage(R.string.enter_url) + .setView(urlEditText) + .setNegativeButton(R.string.cancel) { dialog, _ -> + dialog.cancel() + } + .setPositiveButton(getString(R.string.ok)) { _, _ -> + val url = Url(urlEditText.text.toString()) + if (url == null || !URLUtil.isValidUrl(urlEditText.text.toString())) { + urlEditText.error = getString(R.string.invalid_url) + return@setPositiveButton + } + + bookshelfViewModel.addPublicationFromWeb(url) + } + .show() + } + private fun handleEvent(event: BookshelfViewModel.Event) { val message = when (event) { - is BookshelfViewModel.Event.ImportPublicationSuccess -> - getString(R.string.import_publication_success) - - is BookshelfViewModel.Event.ImportPublicationError -> { - event.errorMessage - } - is BookshelfViewModel.Event.OpenPublicationError -> { event.errorMessage } @@ -166,7 +153,6 @@ class BookshelfFragment : Fragment() { null } } - binding.bookshelfProgressBar.visibility = View.GONE message?.let { Snackbar.make( requireView(), diff --git a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt index 30896da39d..0ea35d3fc2 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/bookshelf/BookshelfViewModel.kt @@ -8,122 +8,62 @@ package org.readium.r2.testapp.bookshelf import android.app.Activity import android.app.Application -import android.content.Context import android.net.Uri import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import org.readium.r2.shared.util.Url -import org.readium.r2.testapp.BuildConfig -import org.readium.r2.testapp.domain.model.Book +import org.readium.r2.shared.util.toUrl +import org.readium.r2.testapp.data.model.Book import org.readium.r2.testapp.reader.ReaderActivityContract import org.readium.r2.testapp.utils.EventChannel -import org.readium.r2.testapp.utils.extensions.copyToTempFile class BookshelfViewModel(application: Application) : AndroidViewModel(application) { private val app get() = getApplication() - private val preferences = - application.getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE) - val channel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) val books = app.bookRepository.books() - init { - copySamplesFromAssetsToStorage() - } - - private fun copySamplesFromAssetsToStorage() = viewModelScope.launch(Dispatchers.IO) { - withContext(Dispatchers.IO) { - if (!preferences.contains("samples")) { - val dir = app.storageDir - if (!dir.exists()) { - dir.mkdirs() - } - val samples = app.assets.list("Samples")?.filterNotNull().orEmpty() - for (element in samples) { - val file = - app.assets.open("Samples/$element").copyToTempFile(app.storageDir) - if (file != null) { - app.bookRepository.addLocalBook(file) - } else if (BuildConfig.DEBUG) { - error("Unable to load sample into the library") - } - } - preferences.edit().putBoolean("samples", true).apply() - } - } - } - fun deletePublication(book: Book) = viewModelScope.launch { - app.bookRepository.deleteBook(book) - } - - fun importPublicationFromUri(uri: Uri) = - viewModelScope.launch { - app.bookRepository - .importBook(uri) - .failureOrNull() - .let { sendImportFeedback(it) } + app.bookshelf.deleteBook(book) } - fun addSharedStoragePublication(uri: Uri) = - viewModelScope.launch { - app.bookRepository - .addSharedStorageBook(Url(uri.toString())!!) - .failureOrNull() - .let { sendImportFeedback(it) } - } + fun importPublicationFromStorage(uri: Uri) { + app.bookshelf.importPublicationFromStorage(uri) + } - fun addRemotePublication(url: Url) { - viewModelScope.launch { - val exception = app.bookRepository - .addRemoteBook(url) - .failureOrNull() - sendImportFeedback(exception) - } + fun addPublicationFromStorage(uri: Uri) { + app.bookshelf.addPublicationFromStorage(uri.toUrl()!!) } - private fun sendImportFeedback(error: BookRepository.ImportError?) { - if (error == null) { - channel.send(Event.ImportPublicationSuccess) - } else { - val errorMessage = error.getUserMessage(app) - channel.send(Event.ImportPublicationError(errorMessage)) - } + fun addPublicationFromWeb(url: Url) { + app.bookshelf.addPublicationFromWeb(url) } fun openPublication( bookId: Long, activity: Activity - ) = viewModelScope.launch { - val readerRepository = app.readerRepository.await() - readerRepository.open(bookId, activity) - .onFailure { error -> - val message = error.getUserMessage(app) - channel.send(Event.OpenPublicationError(message)) - } - .onSuccess { - val arguments = ReaderActivityContract.Arguments(bookId) - channel.send(Event.LaunchReader(arguments)) - } + ) { + viewModelScope.launch { + val readerRepository = app.readerRepository.await() + readerRepository.open(bookId, activity) + .onFailure { error -> + val message = error.getUserMessage(app) + channel.send(Event.OpenPublicationError(message)) + } + .onSuccess { + val arguments = ReaderActivityContract.Arguments(bookId) + channel.send(Event.LaunchReader(arguments)) + } + } } sealed class Event { - object ImportPublicationSuccess : - Event() - - class ImportPublicationError( - val errorMessage: String - ) : Event() - class OpenPublicationError( val errorMessage: String ) : Event() diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt index 954bd194c2..93251e2369 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListAdapter.kt @@ -14,8 +14,8 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Catalog import org.readium.r2.testapp.databinding.ItemRecycleButtonBinding -import org.readium.r2.testapp.domain.model.Catalog class CatalogFeedListAdapter(private val onLongClick: (Catalog) -> Unit) : ListAdapter(CatalogListDiff()) { diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt index f812c7d320..bc298b3e36 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListFragment.kt @@ -23,8 +23,8 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Catalog import org.readium.r2.testapp.databinding.FragmentCatalogFeedListBinding -import org.readium.r2.testapp.domain.model.Catalog import org.readium.r2.testapp.utils.viewLifecycle class CatalogFeedListFragment : Fragment() { diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt index 1078dd30e0..ad89cf92e5 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFeedListViewModel.kt @@ -19,14 +19,15 @@ import org.readium.r2.shared.opds.ParseData import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.http.HttpRequest import org.readium.r2.shared.util.http.fetchWithDecoder -import org.readium.r2.testapp.db.BookDatabase -import org.readium.r2.testapp.domain.model.Catalog +import org.readium.r2.testapp.data.CatalogRepository +import org.readium.r2.testapp.data.db.AppDatabase +import org.readium.r2.testapp.data.model.Catalog import org.readium.r2.testapp.utils.EventChannel class CatalogFeedListViewModel(application: Application) : AndroidViewModel(application) { private val httpClient = getApplication().readium.httpClient - private val catalogDao = BookDatabase.getDatabase(application).catalogDao() + private val catalogDao = AppDatabase.getDatabase(application).catalogDao() private val repository = CatalogRepository(catalogDao) val eventChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt index e22619b4ca..6d8df60390 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogFragment.kt @@ -28,8 +28,8 @@ import org.readium.r2.testapp.MainActivity import org.readium.r2.testapp.R import org.readium.r2.testapp.bookshelf.BookshelfFragment import org.readium.r2.testapp.catalogs.CatalogFeedListAdapter.Companion.CATALOGFEED +import org.readium.r2.testapp.data.model.Catalog import org.readium.r2.testapp.databinding.FragmentCatalogBinding -import org.readium.r2.testapp.domain.model.Catalog import org.readium.r2.testapp.opds.GridAutoFitLayoutManager import org.readium.r2.testapp.utils.viewLifecycle @@ -49,7 +49,7 @@ class CatalogFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - catalogViewModel.eventChannel.receive(this) { handleEvent(it) } + catalogViewModel.channel.receive(this) { handleEvent(it) } catalog = arguments?.let { BundleCompat.getParcelable(it, CATALOGFEED, Catalog::class.java) }!! binding = FragmentCatalogBinding.inflate(inflater, container, false) @@ -130,9 +130,9 @@ class CatalogFragment : Fragment() { ) } - private fun handleEvent(event: CatalogViewModel.Event.FeedEvent) { + private fun handleEvent(event: CatalogViewModel.Event) { when (event) { - is CatalogViewModel.Event.FeedEvent.CatalogParseFailed -> { + is CatalogViewModel.Event.CatalogParseFailed -> { Snackbar.make( requireView(), getString(R.string.failed_parsing_catalog), @@ -140,7 +140,7 @@ class CatalogFragment : Fragment() { ).show() } - is CatalogViewModel.Event.FeedEvent.CatalogParseSuccess -> { + is CatalogViewModel.Event.CatalogParseSuccess -> { facets = event.result.feed?.facets ?: mutableListOf() if (facets.size > 0) { diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt index 15d86482c0..3d9c271563 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogViewModel.kt @@ -9,30 +9,23 @@ package org.readium.r2.testapp.catalogs import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope -import java.io.File import java.net.MalformedURLException -import java.net.URL -import java.util.* import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.launch import org.readium.r2.opds.OPDS1Parser import org.readium.r2.opds.OPDS2Parser import org.readium.r2.shared.opds.ParseData import org.readium.r2.shared.publication.Publication -import org.readium.r2.shared.publication.opds.images import org.readium.r2.shared.util.Try -import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.http.HttpRequest -import org.readium.r2.shared.util.mediatype.MediaType -import org.readium.r2.testapp.domain.model.Catalog +import org.readium.r2.testapp.data.model.Catalog import org.readium.r2.testapp.utils.EventChannel -import org.readium.r2.testapp.utils.extensions.downloadTo import timber.log.Timber class CatalogViewModel(application: Application) : AndroidViewModel(application) { - val detailChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) - val eventChannel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) + val channel = EventChannel(Channel(Channel.BUFFERED), viewModelScope) + lateinit var publication: Publication private val app = getApplication() @@ -47,64 +40,26 @@ class CatalogViewModel(application: Application) : AndroidViewModel(application) OPDS2Parser.parseRequest(request, app.readium.httpClient) } } catch (e: MalformedURLException) { - eventChannel.send(Event.FeedEvent.CatalogParseFailed) + channel.send(Event.CatalogParseFailed) } } parseRequest?.onSuccess { - eventChannel.send(Event.FeedEvent.CatalogParseSuccess(it)) + channel.send(Event.CatalogParseSuccess(it)) } parseRequest?.onFailure { Timber.e(it) - eventChannel.send(Event.FeedEvent.CatalogParseFailed) + channel.send(Event.CatalogParseFailed) } } fun downloadPublication(publication: Publication) = viewModelScope.launch { - val filename = UUID.randomUUID().toString() - val dest = File(app.storageDir, filename) - - getDownloadURL(publication) - .flatMap { url -> - url.downloadTo( - dest, - httpClient = app.readium.httpClient, - assetRetriever = app.readium.assetRetriever - ) - }.flatMap { - val opdsCover = publication.images.firstOrNull()?.href - app.bookRepository.addLocalBook(dest, opdsCover) - }.onSuccess { - detailChannel.send(Event.DetailEvent.ImportPublicationSuccess) - }.onFailure { - detailChannel.send(Event.DetailEvent.ImportPublicationFailed) - } + app.bookshelf.importPublicationFromOpds(publication) } - private fun getDownloadURL(publication: Publication): Try = - publication.links - .firstOrNull { it.mediaType?.isPublication == true || it.mediaType == MediaType.LCP_LICENSE_DOCUMENT } - ?.let { - try { - Try.success(URL(it.href)) - } catch (e: Exception) { - Try.failure(e) - } - } ?: Try.failure(Exception("No supported link to acquire publication.")) - sealed class Event { - sealed class FeedEvent : Event() { - - object CatalogParseFailed : FeedEvent() + object CatalogParseFailed : Event() - class CatalogParseSuccess(val result: ParseData) : FeedEvent() - } - - sealed class DetailEvent : Event() { - - object ImportPublicationSuccess : DetailEvent() - - object ImportPublicationFailed : DetailEvent() - } + class CatalogParseSuccess(val result: ParseData) : Event() } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt index dbf0764271..6b94e603b2 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/GroupAdapter.kt @@ -18,8 +18,8 @@ import androidx.recyclerview.widget.RecyclerView import org.readium.r2.shared.opds.Group import org.readium.r2.shared.publication.Publication import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Catalog import org.readium.r2.testapp.databinding.ItemGroupViewBinding -import org.readium.r2.testapp.domain.model.Catalog class GroupAdapter( val type: Int, diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt index 70f6b763fd..da41620eb2 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/NavigationAdapter.kt @@ -15,8 +15,8 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import org.readium.r2.shared.publication.Link import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Catalog import org.readium.r2.testapp.databinding.ItemRecycleButtonBinding -import org.readium.r2.testapp.domain.model.Catalog class NavigationAdapter(val type: Int) : ListAdapter(LinkDiff()) { diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt index a5ca3f2a7e..e0dccc8bca 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/catalogs/PublicationDetailFragment.kt @@ -12,12 +12,10 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import com.google.android.material.snackbar.Snackbar import com.squareup.picasso.Picasso import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.publication.opds.images import org.readium.r2.testapp.MainActivity -import org.readium.r2.testapp.R import org.readium.r2.testapp.databinding.FragmentPublicationDetailBinding class PublicationDetailFragment : Fragment() { @@ -38,7 +36,6 @@ class PublicationDetailFragment : Fragment() { container, false ) - catalogViewModel.detailChannel.receive(this) { handleEvent(it) } publication = catalogViewModel.publication return binding.root } @@ -56,29 +53,10 @@ class PublicationDetailFragment : Fragment() { binding.catalogDetailDownloadButton.setOnClickListener { publication?.let { it1 -> - binding.catalogDetailProgressBar.visibility = View.VISIBLE catalogViewModel.downloadPublication( it1 ) } } } - - private fun handleEvent(event: CatalogViewModel.Event.DetailEvent) { - val message = - when (event) { - is CatalogViewModel.Event.DetailEvent.ImportPublicationSuccess -> getString( - R.string.import_publication_success - ) - is CatalogViewModel.Event.DetailEvent.ImportPublicationFailed -> getString( - R.string.import_publication_unable_add_pub_database - ) - } - binding.catalogDetailProgressBar.visibility = View.GONE - Snackbar.make( - requireView(), - message, - Snackbar.LENGTH_LONG - ).show() - } } diff --git a/test-app/src/main/java/org/readium/r2/testapp/data/BookRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/data/BookRepository.kt new file mode 100644 index 0000000000..4429322ac1 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/data/BookRepository.kt @@ -0,0 +1,106 @@ +/* + * Copyright 2021 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.data + +import androidx.annotation.ColorInt +import androidx.lifecycle.LiveData +import kotlinx.coroutines.flow.Flow +import org.joda.time.DateTime +import org.readium.r2.shared.asset.AssetType +import org.readium.r2.shared.publication.Locator +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.indexOfFirstWithHref +import org.readium.r2.shared.publication.protection.ContentProtection +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.testapp.data.db.BooksDao +import org.readium.r2.testapp.data.model.Book +import org.readium.r2.testapp.data.model.Bookmark +import org.readium.r2.testapp.data.model.Highlight +import org.readium.r2.testapp.utils.extensions.authorName + +class BookRepository( + private val booksDao: BooksDao +) { + fun books(): LiveData> = booksDao.getAllBooks() + + suspend fun get(id: Long) = booksDao.get(id) + + suspend fun saveProgression(locator: Locator, bookId: Long) = + booksDao.saveProgression(locator.toJSON().toString(), bookId) + + suspend fun insertBookmark(bookId: Long, publication: Publication, locator: Locator): Long { + val resource = publication.readingOrder.indexOfFirstWithHref(locator.href)!! + val bookmark = Bookmark( + creation = DateTime().toDate().time, + bookId = bookId, + resourceIndex = resource.toLong(), + resourceHref = locator.href, + resourceType = locator.type, + resourceTitle = locator.title.orEmpty(), + location = locator.locations.toJSON().toString(), + locatorText = Locator.Text().toJSON().toString() + ) + + return booksDao.insertBookmark(bookmark) + } + + fun bookmarksForBook(bookId: Long): LiveData> = + booksDao.getBookmarksForBook(bookId) + + suspend fun deleteBookmark(bookmarkId: Long) = booksDao.deleteBookmark(bookmarkId) + + suspend fun highlightById(id: Long): Highlight? = + booksDao.getHighlightById(id) + + fun highlightsForBook(bookId: Long): Flow> = + booksDao.getHighlightsForBook(bookId) + + suspend fun addHighlight( + bookId: Long, + style: Highlight.Style, + @ColorInt tint: Int, + locator: Locator, + annotation: String + ): Long = + booksDao.insertHighlight(Highlight(bookId, style, tint, locator, annotation)) + + suspend fun deleteHighlight(id: Long) = booksDao.deleteHighlight(id) + + suspend fun updateHighlightAnnotation(id: Long, annotation: String) { + booksDao.updateHighlightAnnotation(id, annotation) + } + + suspend fun updateHighlightStyle(id: Long, style: Highlight.Style, @ColorInt tint: Int) { + booksDao.updateHighlightStyle(id, style, tint) + } + + suspend fun insertBook( + href: String, + mediaType: MediaType, + assetType: AssetType, + drm: ContentProtection.Scheme?, + publication: Publication, + cover: String + ): Long { + val book = Book( + creation = DateTime().toDate().time, + title = publication.metadata.title, + author = publication.metadata.authorName, + href = href, + identifier = publication.metadata.identifier ?: "", + mediaType = mediaType, + assetType = assetType, + drm = drm, + progression = "{}", + cover = cover + ) + return booksDao.insertBook(book) + } + + suspend fun deleteBook(id: Long) = + booksDao.deleteBook(id) +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/data/CatalogRepository.kt similarity index 80% rename from test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogRepository.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/CatalogRepository.kt index c029699336..4f44f4a71c 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/catalogs/CatalogRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/CatalogRepository.kt @@ -4,11 +4,11 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.catalogs +package org.readium.r2.testapp.data import androidx.lifecycle.LiveData -import org.readium.r2.testapp.db.CatalogDao -import org.readium.r2.testapp.domain.model.Catalog +import org.readium.r2.testapp.data.db.CatalogDao +import org.readium.r2.testapp.data.model.Catalog class CatalogRepository(private val catalogDao: CatalogDao) { diff --git a/test-app/src/main/java/org/readium/r2/testapp/data/DownloadRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/data/DownloadRepository.kt new file mode 100644 index 0000000000..1879315f36 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/data/DownloadRepository.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.data + +import org.readium.r2.testapp.data.db.DownloadsDao +import org.readium.r2.testapp.data.model.Download + +class DownloadRepository( + private val type: Download.Type, + private val downloadsDao: DownloadsDao +) { + + suspend fun all(): List = + downloadsDao.getDownloads(type) + + suspend fun insert( + id: String, + cover: String? + ) { + downloadsDao.insert( + Download(id = id, type = type, cover = cover) + ) + } + + suspend fun remove( + id: String + ) { + downloadsDao.delete(id, type) + } + + suspend fun getCover(id: String): String? = + downloadsDao.get(id, type)?.cover +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/db/BookDatabase.kt b/test-app/src/main/java/org/readium/r2/testapp/data/db/AppDatabase.kt similarity index 59% rename from test-app/src/main/java/org/readium/r2/testapp/db/BookDatabase.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/db/AppDatabase.kt index d4562bad0c..4f19e64f87 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/db/BookDatabase.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/db/AppDatabase.kt @@ -4,32 +4,41 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.db +package org.readium.r2.testapp.data.db import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverters -import org.readium.r2.testapp.domain.model.* +import org.readium.r2.testapp.data.model.* +import org.readium.r2.testapp.data.model.Book +import org.readium.r2.testapp.data.model.Bookmark +import org.readium.r2.testapp.data.model.Catalog +import org.readium.r2.testapp.data.model.Highlight @Database( - entities = [Book::class, Bookmark::class, Highlight::class, Catalog::class], + entities = [Book::class, Bookmark::class, Highlight::class, Catalog::class, Download::class], version = 1, exportSchema = false ) -@TypeConverters(HighlightConverters::class) -abstract class BookDatabase : RoomDatabase() { +@TypeConverters( + HighlightConverters::class, + Download.Type.Converter::class +) +abstract class AppDatabase : RoomDatabase() { abstract fun booksDao(): BooksDao abstract fun catalogDao(): CatalogDao + abstract fun downloadsDao(): DownloadsDao + companion object { @Volatile - private var INSTANCE: BookDatabase? = null + private var INSTANCE: AppDatabase? = null - fun getDatabase(context: Context): BookDatabase { + fun getDatabase(context: Context): AppDatabase { val tempInstance = INSTANCE if (tempInstance != null) { return tempInstance @@ -37,8 +46,8 @@ abstract class BookDatabase : RoomDatabase() { synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, - BookDatabase::class.java, - "books_database" + AppDatabase::class.java, + "database" ).build() INSTANCE = instance return instance diff --git a/test-app/src/main/java/org/readium/r2/testapp/db/BooksDao.kt b/test-app/src/main/java/org/readium/r2/testapp/data/db/BooksDao.kt similarity index 95% rename from test-app/src/main/java/org/readium/r2/testapp/db/BooksDao.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/db/BooksDao.kt index ec53bc5328..af31e8a779 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/db/BooksDao.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/db/BooksDao.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.db +package org.readium.r2.testapp.data.db import androidx.annotation.ColorInt import androidx.lifecycle.LiveData @@ -13,9 +13,9 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import kotlinx.coroutines.flow.Flow -import org.readium.r2.testapp.domain.model.Book -import org.readium.r2.testapp.domain.model.Bookmark -import org.readium.r2.testapp.domain.model.Highlight +import org.readium.r2.testapp.data.model.Book +import org.readium.r2.testapp.data.model.Bookmark +import org.readium.r2.testapp.data.model.Highlight @Dao interface BooksDao { diff --git a/test-app/src/main/java/org/readium/r2/testapp/db/CatalogDao.kt b/test-app/src/main/java/org/readium/r2/testapp/data/db/CatalogDao.kt similarity index 94% rename from test-app/src/main/java/org/readium/r2/testapp/db/CatalogDao.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/db/CatalogDao.kt index 1298298c83..1d4051e3c7 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/db/CatalogDao.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/db/CatalogDao.kt @@ -4,14 +4,14 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.db +package org.readium.r2.testapp.data.db import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import org.readium.r2.testapp.domain.model.Catalog +import org.readium.r2.testapp.data.model.Catalog @Dao interface CatalogDao { diff --git a/test-app/src/main/java/org/readium/r2/testapp/data/db/DownloadsDao.kt b/test-app/src/main/java/org/readium/r2/testapp/data/db/DownloadsDao.kt new file mode 100644 index 0000000000..c8ed9aba9e --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/data/db/DownloadsDao.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.data.db + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import org.readium.r2.testapp.data.model.Download + +@Dao +interface DownloadsDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insert(download: Download) + + @Query( + "DELETE FROM " + Download.TABLE_NAME + + " WHERE " + Download.ID + " = :id AND " + Download.TYPE + " = :type" + ) + suspend fun delete(id: String, type: Download.Type) + + @Query( + "SELECT * FROM " + Download.TABLE_NAME + + " WHERE " + Download.ID + " = :id AND " + Download.TYPE + " = :type" + ) + suspend fun get(id: String, type: Download.Type): Download? + + @Query( + "SELECT * FROM " + Download.TABLE_NAME + + " WHERE " + Download.TYPE + " = :type" + ) + suspend fun getDownloads(type: Download.Type): List +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt b/test-app/src/main/java/org/readium/r2/testapp/data/model/Book.kt similarity index 98% rename from test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/model/Book.kt index 42206cb07d..d698564536 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Book.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/model/Book.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.domain.model +package org.readium.r2.testapp.data.model import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Bookmark.kt b/test-app/src/main/java/org/readium/r2/testapp/data/model/Bookmark.kt similarity index 97% rename from test-app/src/main/java/org/readium/r2/testapp/domain/model/Bookmark.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/model/Bookmark.kt index b2dd2cbb1a..e9161edeca 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Bookmark.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/model/Bookmark.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.domain.model +package org.readium.r2.testapp.data.model import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Catalog.kt b/test-app/src/main/java/org/readium/r2/testapp/data/model/Catalog.kt similarity index 95% rename from test-app/src/main/java/org/readium/r2/testapp/domain/model/Catalog.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/model/Catalog.kt index f04c61fe18..86ad9bbba6 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Catalog.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/model/Catalog.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.domain.model +package org.readium.r2.testapp.data.model import android.os.Parcelable import androidx.room.ColumnInfo diff --git a/test-app/src/main/java/org/readium/r2/testapp/data/model/Download.kt b/test-app/src/main/java/org/readium/r2/testapp/data/model/Download.kt new file mode 100644 index 0000000000..ad2e6296ea --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/data/model/Download.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.data.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.TypeConverter + +/** + * Represents an on-going publication download, either from an OPDS catalog or an LCP acquisition. + * + * The download [id] is unique relative to its [type] (OPDS or LCP). + */ +@Entity(tableName = Download.TABLE_NAME, primaryKeys = [Download.ID, Download.TYPE]) +data class Download( + @ColumnInfo(name = TYPE) + val type: Type, + @ColumnInfo(name = ID) + val id: String, + @ColumnInfo(name = COVER) + val cover: String? = null, + @ColumnInfo(name = CREATION_DATE, defaultValue = "CURRENT_TIMESTAMP") + val creation: Long? = null +) { + enum class Type(val value: String) { + OPDS("opds"), LCP("lcp"); + + class Converter { + private val values = values().associateBy(Type::value) + + @TypeConverter + fun fromString(value: String?): Type = values[value]!! + + @TypeConverter + fun toString(type: Type): String = type.value + } + } + + companion object { + const val TABLE_NAME = "downloads" + const val CREATION_DATE = "creation_date" + const val ID = "id" + const val TYPE = "type" + const val COVER = "cover" + } +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Highlight.kt b/test-app/src/main/java/org/readium/r2/testapp/data/model/Highlight.kt similarity index 99% rename from test-app/src/main/java/org/readium/r2/testapp/domain/model/Highlight.kt rename to test-app/src/main/java/org/readium/r2/testapp/data/model/Highlight.kt index 58d770c2e0..2142077042 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/domain/model/Highlight.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/data/model/Highlight.kt @@ -4,7 +4,7 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp.domain.model +package org.readium.r2.testapp.data.model import androidx.annotation.ColorInt import androidx.room.* diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/Bookshelf.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/Bookshelf.kt new file mode 100644 index 0000000000..003c1adb68 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/Bookshelf.kt @@ -0,0 +1,176 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.domain + +import android.net.Uri +import java.io.File +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.launch +import org.readium.r2.shared.asset.AssetRetriever +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.protection.ContentProtectionSchemeRetriever +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.toUrl +import org.readium.r2.streamer.PublicationFactory +import org.readium.r2.testapp.data.BookRepository +import org.readium.r2.testapp.data.model.Book +import org.readium.r2.testapp.utils.extensions.formatPercentage +import org.readium.r2.testapp.utils.tryOrLog +import timber.log.Timber + +/** + * The [Bookshelf] supports two different processes: + * - directly _adding_ the url to a remote asset or an asset from shared storage to the database + * - _importing_ an asset, that is downloading or copying the publication the asset points to to the app storage + * before adding it to the database + */ +class Bookshelf( + private val bookRepository: BookRepository, + private val coverStorage: CoverStorage, + private val publicationFactory: PublicationFactory, + private val assetRetriever: AssetRetriever, + private val protectionRetriever: ContentProtectionSchemeRetriever, + createPublicationRetriever: (PublicationRetriever.Listener) -> PublicationRetriever +) { + val channel: Channel = + Channel(Channel.UNLIMITED) + + private val publicationRetriever: PublicationRetriever + + init { + publicationRetriever = createPublicationRetriever(PublicationRetrieverListener()) + } + + sealed class Event { + data object ImportPublicationSuccess : + Event() + + class ImportPublicationError( + val error: ImportError + ) : Event() + } + + private val coroutineScope: CoroutineScope = + MainScope() + + private inner class PublicationRetrieverListener : PublicationRetriever.Listener { + override fun onSuccess(publication: File, coverUrl: String?) { + coroutineScope.launch { + val url = publication.toUrl() + addBookFeedback(url, coverUrl) + } + } + + override fun onProgressed(progress: Double) { + Timber.e("Downloaded ${progress.formatPercentage()}") + } + + override fun onError(error: ImportError) { + coroutineScope.launch { + channel.send(Event.ImportPublicationError(error)) + } + } + } + + fun importPublicationFromStorage( + uri: Uri + ) { + publicationRetriever.retrieveFromStorage(uri) + } + + fun importPublicationFromOpds( + publication: Publication + ) { + publicationRetriever.retrieveFromOpds(publication) + } + + fun addPublicationFromWeb( + url: Url + ) { + coroutineScope.launch { + addBookFeedback(url) + } + } + + fun addPublicationFromStorage( + url: Url + ) { + coroutineScope.launch { + addBookFeedback(url) + } + } + + private suspend fun addBookFeedback( + url: Url, + coverUrl: String? = null + ) { + addBook(url, coverUrl) + .onSuccess { channel.send(Event.ImportPublicationSuccess) } + .onFailure { channel.send(Event.ImportPublicationError(it)) } + } + + private suspend fun addBook( + url: Url, + coverUrl: String? = null + ): Try { + val asset = + assetRetriever.retrieve(url) + ?: return Try.failure( + ImportError.PublicationError(PublicationError.UnsupportedAsset()) + ) + + val drmScheme = + protectionRetriever.retrieve(asset) + + publicationFactory.open( + asset, + contentProtectionScheme = drmScheme, + allowUserInteraction = false + ).onSuccess { publication -> + val coverFile = + coverStorage.storeCover(publication, coverUrl) + .getOrElse { + return Try.failure(ImportError.StorageError(it)) + } + + val id = bookRepository.insertBook( + url.toString(), + asset.mediaType, + asset.assetType, + drmScheme, + publication, + coverFile.path + ) + if (id == -1L) { + coverFile.delete() + return Try.failure(ImportError.DatabaseError()) + } + } + .onFailure { + Timber.d("Cannot open publication: $it.") + return Try.failure( + ImportError.PublicationError(PublicationError(it)) + ) + } + + return Try.success(Unit) + } + + suspend fun deleteBook(book: Book) { + val id = book.id!! + bookRepository.deleteBook(id) + val url = Url(book.href)!! + if (url.scheme == "file") { + tryOrLog { File(url.path).delete() } + } + tryOrLog { File(book.cover).delete() } + } +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/CoverStorage.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/CoverStorage.kt new file mode 100644 index 0000000000..e3d2f45c75 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/CoverStorage.kt @@ -0,0 +1,61 @@ +package org.readium.r2.testapp.domain + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.net.HttpURLConnection +import java.net.URL +import java.util.UUID +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.services.cover +import org.readium.r2.shared.util.Try + +class CoverStorage( + appStorageDir: File +) { + + private val coverDir: File = + File(appStorageDir, "covers/") + .apply { if (!exists()) mkdirs() } + + suspend fun storeCover(publication: Publication, overrideUrl: String?): Try { + val coverBitmap: Bitmap? = overrideUrl + ?.let { getBitmapFromURL(it) } + ?: publication.cover() + return try { + Try.success(storeCover(coverBitmap)) + } catch (e: Exception) { + Try.failure(e) + } + } + + private suspend fun storeCover(cover: Bitmap?): File = + withContext(Dispatchers.IO) { + val coverImageFile = File(coverDir, "${UUID.randomUUID()}.png") + val resized = cover?.let { Bitmap.createScaledBitmap(it, 120, 200, true) } + val fos = FileOutputStream(coverImageFile) + resized?.compress(Bitmap.CompressFormat.PNG, 80, fos) + fos.flush() + fos.close() + coverImageFile + } + + private suspend fun getBitmapFromURL(src: String): Bitmap? = + withContext(Dispatchers.IO) { + try { + val url = URL(src) + val connection = url.openConnection() as HttpURLConnection + connection.doInput = true + connection.connect() + val input = connection.inputStream + BitmapFactory.decodeStream(input) + } catch (e: IOException) { + e.printStackTrace() + null + } + } +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/ImportError.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/ImportError.kt new file mode 100644 index 0000000000..137eafe7a7 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/ImportError.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.domain + +import androidx.annotation.StringRes +import org.readium.r2.shared.UserException +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.util.downloads.DownloadManager +import org.readium.r2.testapp.R + +sealed class ImportError( + content: Content, + cause: Exception? +) : UserException(content, cause) { + + constructor(@StringRes userMessageId: Int) : + this(Content(userMessageId), null) + + constructor(cause: UserException) : + this(Content(cause), cause) + + class LcpAcquisitionFailed( + override val cause: UserException + ) : ImportError(cause) + + class PublicationError( + override val cause: UserException + ) : ImportError(cause) { + + companion object { + + operator fun invoke( + error: Publication.OpeningException + ): ImportError = PublicationError( + org.readium.r2.testapp.domain.PublicationError( + error + ) + ) + } + } + + class StorageError( + override val cause: Throwable + ) : ImportError(R.string.import_publication_unexpected_io_exception) + + class DownloadFailed( + val error: DownloadManager.Error + ) : ImportError(R.string.import_publication_download_failed) + + class OpdsError( + override val cause: Throwable + ) : ImportError(R.string.import_publication_no_acquisition) + + class DatabaseError : + ImportError(R.string.import_publication_unable_add_pub_database) +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/PublicationError.kt similarity index 93% rename from test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt rename to test-app/src/main/java/org/readium/r2/testapp/domain/PublicationError.kt index c024a4ee3a..264f5f2aa7 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/PublicationError.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/PublicationError.kt @@ -4,13 +4,14 @@ * available in the top-level LICENSE file of the project. */ -package org.readium.r2.testapp +package org.readium.r2.testapp.domain import androidx.annotation.StringRes import org.readium.r2.shared.UserException import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.publication.Publication import org.readium.r2.shared.util.Error +import org.readium.r2.testapp.R sealed class PublicationError(@StringRes userMessageId: Int) : UserException(userMessageId) { @@ -24,7 +25,7 @@ sealed class PublicationError(@StringRes userMessageId: Int) : UserException(use R.string.publication_error_scheme_not_supported ) - class UnsupportedPublication(val error: Error? = null) : PublicationError( + class UnsupportedAsset(val error: Error? = null) : PublicationError( R.string.publication_error_unsupported_asset ) @@ -61,13 +62,13 @@ sealed class PublicationError(@StringRes userMessageId: Int) : UserException(use is Publication.OpeningException.Unexpected -> Unexpected(error) is Publication.OpeningException.UnsupportedAsset -> - SchemeNotSupported(error) + UnsupportedAsset(error) } operator fun invoke(error: AssetRetriever.Error): PublicationError = when (error) { is AssetRetriever.Error.ArchiveFormatNotSupported -> - UnsupportedPublication(error) + UnsupportedAsset(error) is AssetRetriever.Error.Forbidden -> Forbidden(error) is AssetRetriever.Error.NotFound -> diff --git a/test-app/src/main/java/org/readium/r2/testapp/domain/PublicationRetriever.kt b/test-app/src/main/java/org/readium/r2/testapp/domain/PublicationRetriever.kt new file mode 100644 index 0000000000..54cd1eab98 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/domain/PublicationRetriever.kt @@ -0,0 +1,409 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.testapp.domain + +import android.content.Context +import android.net.Uri +import java.io.File +import java.util.UUID +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import org.readium.r2.lcp.LcpException +import org.readium.r2.lcp.LcpPublicationRetriever as ReadiumLcpPublicationRetriever +import org.readium.r2.lcp.LcpService +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.asset.Asset +import org.readium.r2.shared.asset.AssetRetriever +import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.opds.images +import org.readium.r2.shared.util.Try +import org.readium.r2.shared.util.Url +import org.readium.r2.shared.util.downloads.DownloadManager +import org.readium.r2.shared.util.getOrElse +import org.readium.r2.shared.util.mediatype.FormatRegistry +import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.testapp.data.DownloadRepository +import org.readium.r2.testapp.utils.extensions.copyToTempFile +import org.readium.r2.testapp.utils.extensions.moveTo +import org.readium.r2.testapp.utils.tryOrNull +import timber.log.Timber + +/** + * Retrieves a publication from a remote or local source and import it into the bookshelf storage. + * + * If the source file is a LCP license document, the protected publication will be downloaded. + */ +class PublicationRetriever( + private val listener: Listener, + createLocalPublicationRetriever: (Listener) -> LocalPublicationRetriever, + createOpdsPublicationRetriever: (Listener) -> OpdsPublicationRetriever +) { + + private val localPublicationRetriever: LocalPublicationRetriever + private val opdsPublicationRetriever: OpdsPublicationRetriever + + interface Listener { + + fun onSuccess(publication: File, coverUrl: String?) + fun onProgressed(progress: Double) + fun onError(error: ImportError) + } + + init { + localPublicationRetriever = createLocalPublicationRetriever(object : Listener { + override fun onSuccess(publication: File, coverUrl: String?) { + listener.onSuccess(publication, coverUrl) + } + + override fun onProgressed(progress: Double) { + listener.onProgressed(progress) + } + + override fun onError(error: ImportError) { + listener.onError(error) + } + }) + + opdsPublicationRetriever = createOpdsPublicationRetriever(object : Listener { + override fun onSuccess(publication: File, coverUrl: String?) { + localPublicationRetriever.retrieve(publication, coverUrl) + } + + override fun onProgressed(progress: Double) { + listener.onProgressed(progress) + } + + override fun onError(error: ImportError) { + listener.onError(error) + } + }) + } + + fun retrieveFromStorage(uri: Uri) { + localPublicationRetriever.retrieve(uri) + } + + fun retrieveFromOpds(publication: Publication) { + opdsPublicationRetriever.retrieve(publication) + } +} + +/** + * Retrieves a publication from a file (publication or LCP license document) stored on the device. + */ +class LocalPublicationRetriever( + private val listener: PublicationRetriever.Listener, + private val context: Context, + private val storageDir: File, + private val assetRetriever: AssetRetriever, + private val formatRegistry: FormatRegistry, + createLcpPublicationRetriever: (PublicationRetriever.Listener) -> LcpPublicationRetriever? +) { + + private val lcpPublicationRetriever: LcpPublicationRetriever? + + private val coroutineScope: CoroutineScope = + MainScope() + + init { + lcpPublicationRetriever = createLcpPublicationRetriever(LcpListener()) + } + + /** + * Retrieves the publication from the given local [uri]. + */ + fun retrieve(uri: Uri) { + coroutineScope.launch { + val tempFile = uri.copyToTempFile(context, storageDir) + .getOrElse { + listener.onError(ImportError.StorageError(it)) + return@launch + } + + retrieveFromStorage(tempFile) + } + } + + /** + * Retrieves the publication stored at the given [tempFile]. + */ + fun retrieve( + tempFile: File, + coverUrl: String? = null + ) { + coroutineScope.launch { + retrieveFromStorage(tempFile, coverUrl) + } + } + + private suspend fun retrieveFromStorage( + tempFile: File, + coverUrl: String? = null + ) { + val sourceAsset = assetRetriever.retrieve(tempFile) + ?: run { + listener.onError( + ImportError.PublicationError(PublicationError.UnsupportedAsset()) + ) + return + } + + if ( + sourceAsset is Asset.Resource && + sourceAsset.mediaType.matches(MediaType.LCP_LICENSE_DOCUMENT) + ) { + if (lcpPublicationRetriever == null) { + listener.onError( + ImportError.PublicationError(PublicationError.UnsupportedAsset()) + ) + } else { + lcpPublicationRetriever.retrieve(sourceAsset, tempFile, coverUrl) + } + return + } + + val fileExtension = formatRegistry.fileExtension(sourceAsset.mediaType) ?: "epub" + val fileName = "${UUID.randomUUID()}.$fileExtension" + val libraryFile = File(storageDir, fileName) + + try { + tempFile.moveTo(libraryFile) + } catch (e: Exception) { + Timber.d(e) + tryOrNull { libraryFile.delete() } + listener.onError(ImportError.StorageError(e)) + return + } + + listener.onSuccess(libraryFile, coverUrl) + } + + private inner class LcpListener : PublicationRetriever.Listener { + override fun onSuccess(publication: File, coverUrl: String?) { + coroutineScope.launch { + retrieve(publication, coverUrl) + } + } + + override fun onProgressed(progress: Double) { + listener.onProgressed(progress) + } + + override fun onError(error: ImportError) { + listener.onError(error) + } + } +} + +/** + * Retrieves a publication from an OPDS entry. + */ +class OpdsPublicationRetriever( + private val listener: PublicationRetriever.Listener, + private val downloadManager: DownloadManager, + private val downloadRepository: DownloadRepository +) { + + private val coroutineScope: CoroutineScope = + MainScope() + + init { + coroutineScope.launch { + for (download in downloadRepository.all()) { + downloadManager.register( + DownloadManager.RequestId(download.id), + downloadListener + ) + } + } + } + + /** + * Retrieves the file of the given OPDS [publication]. + */ + fun retrieve(publication: Publication) { + coroutineScope.launch { + val publicationUrl = publication.acquisitionUrl() + .getOrElse { + listener.onError(ImportError.OpdsError(it)) + return@launch + } + + val coverUrl = publication + .images.firstOrNull()?.href + + val requestId = downloadManager.submit( + request = DownloadManager.Request( + publicationUrl, + headers = emptyMap() + ), + listener = downloadListener + ) + downloadRepository.insert( + id = requestId.value, + cover = coverUrl + ) + } + } + + private fun Publication.acquisitionUrl(): Try { + val acquisitionLink = links + .firstOrNull { it.mediaType?.isPublication == true || it.mediaType == MediaType.LCP_LICENSE_DOCUMENT } + ?: return Try.failure(Exception("No supported link to acquire publication.")) + + return Url(acquisitionLink.href) + ?.let { Try.success(it) } + ?: Try.failure(Exception("Invalid acquisition url.")) + } + + private val downloadListener: DownloadListener = + DownloadListener() + + private inner class DownloadListener : DownloadManager.Listener { + override fun onDownloadCompleted( + requestId: DownloadManager.RequestId, + download: DownloadManager.Download + ) { + coroutineScope.launch { + val coverUrl = downloadRepository.getCover(requestId.value) + downloadRepository.remove(requestId.value) + listener.onSuccess(download.file, coverUrl) + } + } + + override fun onDownloadProgressed( + requestId: DownloadManager.RequestId, + downloaded: Long, + expected: Long? + ) { + coroutineScope.launch { + val progression = expected?.let { downloaded.toDouble() / expected } ?: return@launch + listener.onProgressed(progression) + } + } + + override fun onDownloadFailed( + requestId: DownloadManager.RequestId, + error: DownloadManager.Error + ) { + coroutineScope.launch { + downloadRepository.remove(requestId.value) + listener.onError(ImportError.DownloadFailed(error)) + } + } + + override fun onDownloadCancelled(requestId: DownloadManager.RequestId) { + coroutineScope.launch { + Timber.v("Download ${requestId.value} has been cancelled.") + downloadRepository.remove(requestId.value) + } + } + } +} + +/** + * Retrieves a publication from an LCP license document. + */ +class LcpPublicationRetriever( + private val listener: PublicationRetriever.Listener, + private val downloadRepository: DownloadRepository, + private val lcpPublicationRetriever: ReadiumLcpPublicationRetriever +) { + + private val coroutineScope: CoroutineScope = + MainScope() + + init { + coroutineScope.launch { + for (download in downloadRepository.all()) { + lcpPublicationRetriever.register( + ReadiumLcpPublicationRetriever.RequestId(download.id), + lcpRetrieverListener + ) + } + } + } + + /** + * Retrieves a publication protected with the given license. + */ + fun retrieve( + licenceAsset: Asset.Resource, + licenceFile: File, + coverUrl: String? + ) { + coroutineScope.launch { + val license = licenceAsset.resource.read() + .getOrElse { + listener.onError(ImportError.StorageError(it)) + return@launch + } + .let { + try { + LicenseDocument(it) + } catch (e: LcpException) { + listener.onError(ImportError.LcpAcquisitionFailed(e)) + return@launch + } + } + + tryOrNull { licenceFile.delete() } + + val requestId = lcpPublicationRetriever.retrieve( + license, + lcpRetrieverListener + ) + + downloadRepository.insert(requestId.value, coverUrl) + } + } + + private val lcpRetrieverListener: LcpRetrieverListener = + LcpRetrieverListener() + + private inner class LcpRetrieverListener : ReadiumLcpPublicationRetriever.Listener { + override fun onAcquisitionCompleted( + requestId: ReadiumLcpPublicationRetriever.RequestId, + acquiredPublication: LcpService.AcquiredPublication + ) { + coroutineScope.launch { + val coverUrl = downloadRepository.getCover(requestId.value) + downloadRepository.remove(requestId.value) + listener.onSuccess(acquiredPublication.localFile, coverUrl) + } + } + + override fun onAcquisitionProgressed( + requestId: ReadiumLcpPublicationRetriever.RequestId, + downloaded: Long, + expected: Long? + ) { + coroutineScope.launch { + val progression = expected?.let { downloaded.toDouble() / expected } ?: return@launch + listener.onProgressed(progression) + } + } + + override fun onAcquisitionFailed( + requestId: ReadiumLcpPublicationRetriever.RequestId, + error: LcpException + ) { + coroutineScope.launch { + downloadRepository.remove(requestId.value) + listener.onError(ImportError.LcpAcquisitionFailed(error)) + } + } + + override fun onAcquisitionCancelled(requestId: ReadiumLcpPublicationRetriever.RequestId) { + coroutineScope.launch { + Timber.v("Acquisition ${requestId.value} has been cancelled.") + downloadRepository.remove(requestId.value) + } + } + } +} diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt index 8a23edfb71..842c41197c 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt @@ -23,9 +23,9 @@ import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat import org.readium.r2.shared.publication.Publication import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Bookmark import org.readium.r2.testapp.databinding.FragmentListviewBinding import org.readium.r2.testapp.databinding.ItemRecycleBookmarkBinding -import org.readium.r2.testapp.domain.model.Bookmark import org.readium.r2.testapp.reader.ReaderViewModel import org.readium.r2.testapp.utils.extensions.outlineTitle import org.readium.r2.testapp.utils.viewLifecycle diff --git a/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt index d34db2cb2c..f354c09853 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt @@ -25,9 +25,9 @@ import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat import org.readium.r2.shared.publication.Publication import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Highlight import org.readium.r2.testapp.databinding.FragmentListviewBinding import org.readium.r2.testapp.databinding.ItemRecycleHighlightBinding -import org.readium.r2.testapp.domain.model.Highlight import org.readium.r2.testapp.reader.ReaderViewModel import org.readium.r2.testapp.utils.viewLifecycle diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt index 2581f80b68..30cf0cc83d 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderRepository.kt @@ -28,9 +28,9 @@ import org.readium.r2.shared.publication.services.isRestricted import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.getOrElse -import org.readium.r2.testapp.PublicationError import org.readium.r2.testapp.Readium -import org.readium.r2.testapp.bookshelf.BookRepository +import org.readium.r2.testapp.data.BookRepository +import org.readium.r2.testapp.domain.PublicationError import org.readium.r2.testapp.reader.preferences.AndroidTtsPreferencesManagerFactory import org.readium.r2.testapp.reader.preferences.EpubPreferencesManagerFactory import org.readium.r2.testapp.reader.preferences.ExoPlayerPreferencesManagerFactory @@ -70,11 +70,19 @@ class ReaderRepository( operator fun invoke( error: AssetRetriever.Error - ): OpeningError = PublicationError(org.readium.r2.testapp.PublicationError(error)) + ): OpeningError = PublicationError( + org.readium.r2.testapp.domain.PublicationError( + error + ) + ) operator fun invoke( error: Publication.OpeningException - ): OpeningError = PublicationError(org.readium.r2.testapp.PublicationError(error)) + ): OpeningError = PublicationError( + org.readium.r2.testapp.domain.PublicationError( + error + ) + ) } } } @@ -127,7 +135,7 @@ class ReaderRepository( openImage(bookId, publication, initialLocator) else -> Try.failure( - OpeningError.PublicationError(PublicationError.UnsupportedPublication()) + OpeningError.PublicationError(PublicationError.UnsupportedAsset()) ) } @@ -147,14 +155,14 @@ class ReaderRepository( publication, ExoPlayerEngineProvider(application) ) ?: return Try.failure( - OpeningError.PublicationError(PublicationError.UnsupportedPublication()) + OpeningError.PublicationError(PublicationError.UnsupportedAsset()) ) val navigator = navigatorFactory.createNavigator( initialLocator, initialPreferences ) ?: return Try.failure( - OpeningError.PublicationError(PublicationError.UnsupportedPublication()) + OpeningError.PublicationError(PublicationError.UnsupportedAsset()) ) mediaServiceFacade.openSession(bookId, navigator) diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt index 3852b246da..8332e08adf 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/ReaderViewModel.kt @@ -30,8 +30,8 @@ import org.readium.r2.shared.publication.services.search.SearchTry import org.readium.r2.shared.publication.services.search.search import org.readium.r2.shared.util.Try import org.readium.r2.testapp.Application -import org.readium.r2.testapp.bookshelf.BookRepository -import org.readium.r2.testapp.domain.model.Highlight +import org.readium.r2.testapp.data.BookRepository +import org.readium.r2.testapp.data.model.Highlight import org.readium.r2.testapp.reader.preferences.UserPreferencesViewModel import org.readium.r2.testapp.reader.tts.TtsViewModel import org.readium.r2.testapp.search.SearchPagingSource diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt index 206b4eeec8..b0bbb61446 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/reader/VisualReaderFragment.kt @@ -51,8 +51,8 @@ import org.readium.r2.shared.ExperimentalReadiumApi import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.util.Language import org.readium.r2.testapp.R +import org.readium.r2.testapp.data.model.Highlight import org.readium.r2.testapp.databinding.FragmentReaderBinding -import org.readium.r2.testapp.domain.model.Highlight import org.readium.r2.testapp.reader.preferences.UserPreferencesBottomSheetDialogFragment import org.readium.r2.testapp.reader.tts.TtsControls import org.readium.r2.testapp.reader.tts.TtsViewModel diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt index 62bbb4d56b..b5c784da1a 100644 --- a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/File.kt @@ -12,7 +12,6 @@ package org.readium.r2.testapp.utils.extensions import java.io.File import java.io.FileFilter import java.io.FileOutputStream -import java.io.IOException import java.net.URL import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ensureActive @@ -30,9 +29,13 @@ import org.readium.r2.testapp.BuildConfig import timber.log.Timber suspend fun File.moveTo(target: File) = withContext(Dispatchers.IO) { - if (!this@moveTo.renameTo(target)) { - throw IOException() + if (this@moveTo.renameTo(target)) { + return@withContext } + + // renameTo might be unable to move a file from a filesystem to another. Copy instead. + copyTo(target) + delete() } /** diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Number.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Number.kt new file mode 100644 index 0000000000..467f90c359 --- /dev/null +++ b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Number.kt @@ -0,0 +1,9 @@ +package org.readium.r2.testapp.utils.extensions + +import java.text.NumberFormat + +fun Number.formatPercentage(maximumFractionDigits: Int = 0): String { + val format = NumberFormat.getPercentInstance() + format.maximumFractionDigits = maximumFractionDigits + return format.format(this) +} diff --git a/test-app/src/main/res/values/arrays.xml b/test-app/src/main/res/values/arrays.xml index 8cb4f5dc9a..aeb66d5a55 100644 --- a/test-app/src/main/res/values/arrays.xml +++ b/test-app/src/main/res/values/arrays.xml @@ -1,7 +1,7 @@ - Copy to app storage + Import to app storage Read from shared storage Stream from the Web diff --git a/test-app/src/main/res/values/strings.xml b/test-app/src/main/res/values/strings.xml index 6425f936cc..8d2a7eb769 100644 --- a/test-app/src/main/res/values/strings.xml +++ b/test-app/src/main/res/values/strings.xml @@ -94,10 +94,13 @@ Return Unable to add publication due to an unexpected error on your device + Publication download failed. + Acquisition is not possible. + Publication added to your library Unable to add publication to the database - Publication format is not supported + Asset format is not supported Publication has not been found. Publication is temporarily unavailable. Provided credentials were incorrect From 4f4fec191a5c46355632f00462ed68964a8cfb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Fri, 15 Sep 2023 17:55:29 +0200 Subject: [PATCH 29/65] Bugfixes for TTS (#391) --- .../iterators/HtmlResourceContentIterator.kt | 91 ++++++++++++--- .../HtmlResourceContentIteratorTest.kt | 109 +++++++++++++++++- 2 files changed, 181 insertions(+), 19 deletions(-) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index c692988761..29c2bb3117 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -7,7 +7,6 @@ package org.readium.r2.shared.publication.services.content.iterators import org.jsoup.Jsoup -import org.jsoup.internal.StringUtil import org.jsoup.nodes.Element import org.jsoup.nodes.Node import org.jsoup.nodes.TextNode @@ -37,8 +36,6 @@ import org.readium.r2.shared.util.getOrThrow import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.use -// FIXME: Support custom skipped elements? - /** * Iterates an HTML [resource], starting from the given [locator]. * @@ -249,16 +246,22 @@ public class HtmlResourceContentIterator internal constructor( /** Language of the current segment. */ private var currentLanguage: String? = null - /** CSS selector of the current element. */ - private var currentCssSelector: String? = null - /** LIFO stack of the current element's block ancestors. */ - private val breadcrumbs = mutableListOf() + private val breadcrumbs = mutableListOf() + + private data class ParentElement( + val element: Element, + val cssSelector: String + ) { + constructor(element: Element) : this(element, element.cssSelector()) + } override fun head(node: Node, depth: Int) { if (node is Element) { + val parent = ParentElement(node) if (node.isBlock) { - breadcrumbs.add(node) + flushText() + breadcrumbs.add(parent) } val tag = node.normalName() @@ -267,7 +270,7 @@ public class HtmlResourceContentIterator internal constructor( baseLocator.copy( locations = Locator.Locations( otherLocations = buildMap { - put("cssSelector", node.cssSelector() as Any) + put("cssSelector", parent.cssSelector as Any) } ) ) @@ -342,7 +345,6 @@ public class HtmlResourceContentIterator internal constructor( node.isBlock -> { flushText() - currentCssSelector = node.cssSelector() } } } @@ -361,7 +363,7 @@ public class HtmlResourceContentIterator internal constructor( appendNormalisedText(text) } else if (node is Element) { if (node.isBlock) { - assert(breadcrumbs.last() == node) + assert(breadcrumbs.last().element == node) flushText() breadcrumbs.removeLast() } @@ -369,7 +371,7 @@ public class HtmlResourceContentIterator internal constructor( } private fun appendNormalisedText(text: String) { - StringUtil.appendNormalisedWhitespace(textAcc, text, lastCharIsWhitespace()) + textAcc.appendNormalisedWhitespace(text, lastCharIsWhitespace()) } private fun lastCharIsWhitespace(): Boolean = @@ -378,7 +380,9 @@ public class HtmlResourceContentIterator internal constructor( private fun flushText() { flushSegment() - if (startIndex == 0 && startElement != null && breadcrumbs.lastOrNull() == startElement) { + val parent = breadcrumbs.lastOrNull() + + if (startIndex == 0 && startElement != null && parent?.element == startElement) { startIndex = elements.size } @@ -393,8 +397,8 @@ public class HtmlResourceContentIterator internal constructor( locator = baseLocator.copy( locations = Locator.Locations( otherLocations = buildMap { - currentCssSelector?.let { - put("cssSelector", it as Any) + parent?.let { + put("cssSelector", it.cssSelector as Any) } } ), @@ -426,13 +430,15 @@ public class HtmlResourceContentIterator internal constructor( text = trimmedText + whitespaceSuffix } + val parent = breadcrumbs.lastOrNull() + segmentsAcc.add( TextElement.Segment( locator = baseLocator.copy( locations = Locator.Locations( otherLocations = buildMap { - currentCssSelector?.let { - put("cssSelector", it as Any) + parent?.let { + put("cssSelector", it.cssSelector as Any) } } ), @@ -483,3 +489,54 @@ private fun Node.srcRelativeToHref(baseHref: String): String? = attr("src") .takeIf { it.isNotBlank() } ?.let { Href(it, baseHref).string } + +/** + * After normalizing the whitespace within a string, appends it to a string builder. + * + * Largely inspired by JSoup's `StringUtil.appendNormalisedWhitespace`. + * + * Note that we don't use directly JSoup's method because we need to keep the non-breaking + * spaces in the text. Otherwise, they will be lost post-text tokenization and Hypothesis won't + * match the results. + * + * @param string String to normalize whitespace within. + * @param stripLeading Set to true if you wish to remove any leading whitespace. + */ +private fun StringBuilder.appendNormalisedWhitespace( + string: String, + stripLeading: Boolean +) { + var lastWasWhite = false + var reachedNonWhite = false + val len = string.length + var c: Int + var i = 0 + while (i < len) { + c = string.codePointAt(i) + if (isWhitespace(c)) { + if (stripLeading && !reachedNonWhite || lastWasWhite) { + i += Character.charCount(c) + continue + } + append(' ') + lastWasWhite = true + } else if (!isInvisibleChar(c)) { + appendCodePoint(c) + lastWasWhite = false + reachedNonWhite = true + } + i += Character.charCount(c) + } +} + +/** + * Tests if a code point is "whitespace" as defined in the HTML spec. + */ +private fun isWhitespace(c: Int): Boolean { + return c == ' '.code || c == '\t'.code || c == '\n'.code || c == '\u000c'.code || c == '\r'.code +} + +private fun isInvisibleChar(c: Int): Boolean { + return c == 8203 || c == 173 // zero width sp, soft hyphen + // previously also included zw non join, zw join - but removing those breaks semantic meaning of text +} diff --git a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt index 40544c9e11..c6247002c0 100644 --- a/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt +++ b/readium/shared/src/test/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIteratorTest.kt @@ -554,7 +554,7 @@ class HtmlResourceContentIteratorTest { TextElement( locator = locator( progression = 2 / 3.0, - selector = "#c06-para-0019", + selector = "#c06-li-0001 > aside", before = "e just described is very much a waterfall process.\n \n ", highlight = "Trailing text" ), @@ -563,7 +563,7 @@ class HtmlResourceContentIteratorTest { Segment( locator = locator( progression = 2 / 3.0, - selector = "#c06-para-0019", + selector = "#c06-li-0001 > aside", before = "e just described is very much a waterfall process.\n ", highlight = "Trailing text" ), @@ -577,4 +577,109 @@ class HtmlResourceContentIteratorTest { iterator(html).elements() ) } + + @Test + fun `iterating over text nodes located around a nested block element`() = runTest { + val html = """ + + + +

    begin a
    in b
    end a
    +
    in c
    + + + """ + + assertEquals( + listOf( + TextElement( + locator = locator( + progression = 0.0, + selector = "#a", + highlight = "begin a" + ), + role = TextElement.Role.Body, + segments = listOf( + Segment( + locator = locator( + progression = 0.0, + selector = "#a", + highlight = "begin a" + ), + text = "begin a", + attributes = emptyList() + ) + ), + attributes = emptyList() + ), + TextElement( + locator = locator( + progression = 0.25, + selector = "#b", + before = "begin a ", + highlight = "in b" + ), + role = TextElement.Role.Body, + segments = listOf( + Segment( + locator = locator( + progression = 0.25, + selector = "#b", + before = "begin a ", + highlight = "in b" + ), + text = "in b", + attributes = emptyList() + ) + ), + attributes = emptyList() + ), + TextElement( + locator = locator( + progression = 0.5, + selector = "#a", + before = "begin a in b ", + highlight = "end a" + ), + role = TextElement.Role.Body, + segments = listOf( + Segment( + locator = locator( + progression = 0.5, + selector = "#a", + before = "begin a in b ", + highlight = "end a" + ), + text = "end a", + attributes = emptyList() + ) + ), + attributes = emptyList() + ), + TextElement( + locator = locator( + progression = 0.75, + selector = "#c", + before = "begin a in b end a", + highlight = "in c" + ), + role = TextElement.Role.Body, + segments = listOf( + Segment( + locator = locator( + progression = 0.75, + selector = "#c", + before = "begin a in b end a", + highlight = "in c" + ), + text = "in c", + attributes = emptyList() + ) + ), + attributes = emptyList() + ) + ), + iterator(html).elements() + ) + } } From e09da402c519b902c87310e79b222e0ae260362d Mon Sep 17 00:00:00 2001 From: qnga <32197639+qnga@users.noreply.github.com> Date: Mon, 18 Sep 2023 15:41:17 +0200 Subject: [PATCH 30/65] Write licenses into ZIP through shared storage (#389) --- readium/lcp/build.gradle.kts | 2 +- .../readium/r2/lcp/LcpContentProtection.kt | 17 +- .../java/org/readium/r2/lcp/LcpService.kt | 7 +- .../container/BytesLicenseContainer.kt | 2 +- .../container/ContainerLicenseContainer.kt | 5 - .../container/ContentZipLicenseContainer.kt | 60 +++++++ .../r2/lcp/license/container/FileUtil.kt | 15 ++ ...ontainer.kt => FileZipLicenseContainer.kt} | 24 +-- ...seContainer.kt => LcplLicenseContainer.kt} | 8 +- .../container/LcplResourceLicenseContainer.kt | 5 - .../lcp/license/container/LicenseContainer.kt | 41 ++++- .../r2/lcp/license/container/ZipUtil.kt | 95 ++++++++++ .../readium/r2/lcp/service/LicensesService.kt | 30 ++-- .../r2/lcp/license/container/ZipUtilTest.kt | 113 ++++++++++++ .../readium/r2/lcp/license/container/a-fc.jpg | Bin 0 -> 150202 bytes .../license/container/futuristic_tales.cbz | Bin 0 -> 719861 bytes .../archive/channel/ChannelZipContainer.kt | 6 +- .../util/archive/channel/HttpChannel.kt | 7 +- .../shared/util/downloads/DownloadManager.kt | 3 +- .../android/AndroidDownloadManager.kt | 77 +++++---- .../foreground/ForegroundDownloadManager.kt | 3 + .../r2/shared/util/http/DefaultHttpClient.kt | 42 ++++- .../readium/r2/shared/util/http/HttpClient.kt | 162 +++++++++++------- .../r2/shared/util/http/HttpException.kt | 6 +- .../r2/shared/util/http/HttpRequest.kt | 3 + .../r2/shared/util/http/HttpResource.kt | 9 +- .../shared/src/main/res/values/strings.xml | 1 + .../java/org/readium/r2/testapp/Readium.kt | 1 + .../r2/testapp/bookshelf/BookshelfFragment.kt | 2 +- 29 files changed, 574 insertions(+), 172 deletions(-) create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContentZipLicenseContainer.kt create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileUtil.kt rename readium/lcp/src/main/java/org/readium/r2/lcp/license/container/{ZIPLicenseContainer.kt => FileZipLicenseContainer.kt} (75%) rename readium/lcp/src/main/java/org/readium/r2/lcp/license/container/{LCPLLicenseContainer.kt => LcplLicenseContainer.kt} (76%) create mode 100644 readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZipUtil.kt create mode 100644 readium/lcp/src/test/java/org/readium/r2/lcp/license/container/ZipUtilTest.kt create mode 100644 readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/a-fc.jpg create mode 100644 readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/futuristic_tales.cbz diff --git a/readium/lcp/build.gradle.kts b/readium/lcp/build.gradle.kts index 6dc38bd2ec..57da92b017 100644 --- a/readium/lcp/build.gradle.kts +++ b/readium/lcp/build.gradle.kts @@ -67,7 +67,6 @@ dependencies { exclude(module = "support-v4") } implementation(libs.joda.time) - implementation("org.zeroturnaround:zt-zip:1.15") implementation(libs.androidx.browser) implementation(libs.bundles.room) @@ -75,6 +74,7 @@ dependencies { // Tests testImplementation(libs.junit) + testImplementation(libs.kotlin.junit) androidTestImplementation(libs.androidx.ext.junit) androidTestImplementation(libs.androidx.expresso.core) diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt index c42d03cc05..b396a71154 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpContentProtection.kt @@ -25,7 +25,6 @@ import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.Url import org.readium.r2.shared.util.flatMap import org.readium.r2.shared.util.getOrElse -import org.readium.r2.shared.util.toFile internal class LcpContentProtection( private val lcpService: LcpService, @@ -73,21 +72,7 @@ internal class LcpContentProtection( ?.let { LcpPassphraseAuthentication(it, fallback = this.authentication) } ?: this.authentication - val file = (asset as? Asset.Resource)?.resource?.source?.toFile() - ?: (asset as? Asset.Container)?.container?.source?.toFile() - - return file - // This is less restrictive with regard to network availability. - ?.let { - lcpService.retrieveLicense( - it, - asset.mediaType, - authentication, - allowUserInteraction, - sender - ) - } - ?: lcpService.retrieveLicense(asset, authentication, allowUserInteraction, sender) + return lcpService.retrieveLicense(asset, authentication, allowUserInteraction, sender) } private fun createResultAsset( diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt index 4669a239d2..7fab4f67b8 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/LcpService.kt @@ -102,10 +102,13 @@ public interface LcpService { /** * Opens the LCP license of a protected publication, to access its DRM metadata and decipher - * its content. As the updated license cannot be stored through a [Asset], - * you'll get an exception if the license points to a LSD server that cannot be reached, + * its content. If the updated license cannot be stored into the [Asset], you'll get + * an exception if the license points to a LSD server that cannot be reached, * for instance because no Internet gateway is available. * + * Updated licenses can currently be stored only into [Asset]s whose source property points to + * a URL with scheme _file_ or _content_. + * * @param authentication Used to retrieve the user passphrase if it is not already known. * The request will be cancelled if no passphrase is found in the LCP passphrase storage * and the provided [authentication]. diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt index 13af2b2bfe..a512348179 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt @@ -14,7 +14,7 @@ import org.readium.r2.lcp.license.model.LicenseDocument /** * Access a License Document from its raw bytes. */ -internal class BytesLicenseContainer(private var bytes: ByteArray) : LicenseContainer { +internal class BytesLicenseContainer(private var bytes: ByteArray) : WritableLicenseContainer { override fun read(): ByteArray = bytes diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt index abe514bcf5..97e9899291 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContainerLicenseContainer.kt @@ -8,7 +8,6 @@ package org.readium.r2.lcp.license.container import kotlinx.coroutines.runBlocking import org.readium.r2.lcp.LcpException -import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.getOrThrow @@ -37,8 +36,4 @@ internal class ContainerLicenseContainer( .getOrThrow() } } - - override fun write(license: LicenseDocument) { - throw LcpException.Container.WriteFailed(entryPath) - } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContentZipLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContentZipLicenseContainer.kt new file mode 100644 index 0000000000..e232eec598 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ContentZipLicenseContainer.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.license.container + +import android.content.ContentResolver +import android.content.Context +import android.net.Uri +import java.io.ByteArrayInputStream +import java.io.File +import java.io.FileOutputStream +import java.util.UUID +import java.util.zip.ZipFile +import org.readium.r2.lcp.LcpException +import org.readium.r2.lcp.license.model.LicenseDocument +import org.readium.r2.shared.resource.Container +import org.readium.r2.shared.util.toUri + +internal class ContentZipLicenseContainer( + context: Context, + private val container: Container, + private val pathInZip: String +) : LicenseContainer by ContainerLicenseContainer(container, pathInZip), WritableLicenseContainer { + + private val zipUri: Uri = + requireNotNull(container.source).toUri() + + private val contentResolver: ContentResolver = + context.contentResolver + + private val cache: File = + context.externalCacheDir ?: context.cacheDir + + override fun write(license: LicenseDocument) { + try { + val tmpZip = File(cache, UUID.randomUUID().toString()) + contentResolver.openInputStream(zipUri) + ?.use { it.copyTo(FileOutputStream(tmpZip)) } + ?: throw LcpException.Container.WriteFailed(pathInZip) + val tmpZipFile = ZipFile(tmpZip) + + val outStream = contentResolver.openOutputStream(zipUri, "wt") + ?: throw LcpException.Container.WriteFailed(pathInZip) + tmpZipFile.addOrReplaceEntry( + pathInZip, + ByteArrayInputStream(license.toByteArray()), + outStream + ) + + outStream.close() + tmpZipFile.close() + tmpZip.delete() + } catch (e: Exception) { + throw LcpException.Container.WriteFailed(pathInZip) + } + } +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileUtil.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileUtil.kt new file mode 100644 index 0000000000..31b389fed0 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileUtil.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.license.container + +import java.io.File +internal fun File.moveTo(target: File) { + if (!this.renameTo(target)) { + this.copyTo(target, overwrite = true) + this.delete() + } +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileZipLicenseContainer.kt similarity index 75% rename from readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt rename to readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileZipLicenseContainer.kt index 3ad2096548..a6ec9309f3 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZIPLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileZipLicenseContainer.kt @@ -9,19 +9,19 @@ package org.readium.r2.lcp.license.container +import java.io.ByteArrayInputStream import java.io.File import java.util.zip.ZipFile import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.license.model.LicenseDocument -import org.zeroturnaround.zip.ZipUtil /** * Access to a License Document stored in a ZIP archive. */ -internal class ZIPLicenseContainer( +internal class FileZipLicenseContainer( private val zip: String, private val pathInZIP: String -) : LicenseContainer { +) : WritableLicenseContainer { override fun read(): ByteArray { val archive = try { @@ -30,7 +30,7 @@ internal class ZIPLicenseContainer( throw LcpException.Container.OpenFailed } val entry = try { - archive.getEntry(pathInZIP) + archive.getEntry(pathInZIP)!! } catch (e: Exception) { throw LcpException.Container.FileNotFound(pathInZIP) } @@ -46,14 +46,14 @@ internal class ZIPLicenseContainer( try { val source = File(zip) val tmpZip = File("$zip.tmp") - tmpZip.delete() - source.copyTo(tmpZip) - source.delete() - if (ZipUtil.containsEntry(tmpZip, pathInZIP)) { - ZipUtil.removeEntry(tmpZip, pathInZIP) - } - ZipUtil.addEntry(tmpZip, pathInZIP, license.toByteArray(), source) - tmpZip.delete() + val zipFile = ZipFile(source) + zipFile.addOrReplaceEntry( + pathInZIP, + ByteArrayInputStream(license.toByteArray()), + tmpZip + ) + zipFile.close() + tmpZip.moveTo(source) } catch (e: Exception) { throw LcpException.Container.WriteFailed(pathInZIP) } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplLicenseContainer.kt similarity index 76% rename from readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt rename to readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplLicenseContainer.kt index a5c81de802..a71279489c 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LCPLLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplLicenseContainer.kt @@ -16,20 +16,20 @@ import org.readium.r2.lcp.license.model.LicenseDocument /** * Access a License Document stored in an LCP License Document file (LCPL). */ -internal class LCPLLicenseContainer(private val lcpl: String) : LicenseContainer { +internal class LcplLicenseContainer(private val licenseFile: File) : WritableLicenseContainer { override fun read(): ByteArray = try { - File(lcpl).readBytes() + licenseFile.readBytes() } catch (e: Exception) { throw LcpException.Container.OpenFailed } override fun write(license: LicenseDocument) { try { - File(lcpl).writeBytes(license.toByteArray()) + licenseFile.writeBytes(license.toByteArray()) } catch (e: Exception) { - throw LcpException.Container.WriteFailed(lcpl) + throw LcpException.Container.WriteFailed(licenseFile.path) } } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt index e5ea792fee..bb1760a9ce 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LcplResourceLicenseContainer.kt @@ -11,7 +11,6 @@ package org.readium.r2.lcp.license.container import kotlinx.coroutines.runBlocking import org.readium.r2.lcp.LcpException -import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.util.getOrThrow @@ -27,8 +26,4 @@ internal class LcplResourceLicenseContainer(private val resource: Resource) : Li } catch (e: Exception) { throw LcpException.Container.OpenFailed } - - override fun write(license: LicenseDocument) { - throw LcpException.Container.WriteFailed("") - } } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt index a9b3893e01..9aeb73e694 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/LicenseContainer.kt @@ -9,6 +9,8 @@ package org.readium.r2.lcp.license.container +import android.content.ContentResolver +import android.content.Context import java.io.File import org.readium.r2.lcp.LcpException import org.readium.r2.lcp.license.model.LicenseDocument @@ -16,7 +18,9 @@ import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.extensions.addPrefix import org.readium.r2.shared.resource.Container import org.readium.r2.shared.resource.Resource +import org.readium.r2.shared.util.isFile import org.readium.r2.shared.util.mediatype.MediaType +import org.readium.r2.shared.util.toFile private const val LICENSE_IN_EPUB = "META-INF/license.lcpl" @@ -28,26 +32,30 @@ private const val LICENSE_IN_RPF = "license.lcpl" */ internal interface LicenseContainer { fun read(): ByteArray +} + +internal interface WritableLicenseContainer : LicenseContainer { fun write(license: LicenseDocument) } internal fun createLicenseContainer( file: File, mediaType: MediaType -): LicenseContainer = +): WritableLicenseContainer = when (mediaType) { - MediaType.EPUB -> ZIPLicenseContainer(file.path, LICENSE_IN_EPUB) - MediaType.LCP_LICENSE_DOCUMENT -> LCPLLicenseContainer(file.path) + MediaType.EPUB -> FileZipLicenseContainer(file.path, LICENSE_IN_EPUB) + MediaType.LCP_LICENSE_DOCUMENT -> LcplLicenseContainer(file) // Assuming it's a Readium WebPub package (e.g. audiobook, LCPDF, etc.) as a fallback - else -> ZIPLicenseContainer(file.path, LICENSE_IN_RPF) + else -> FileZipLicenseContainer(file.path, LICENSE_IN_RPF) } internal fun createLicenseContainer( + context: Context, asset: Asset ): LicenseContainer = when (asset) { is Asset.Resource -> createLicenseContainer(asset.resource, asset.mediaType) - is Asset.Container -> createLicenseContainer(asset.container, asset.mediaType) + is Asset.Container -> createLicenseContainer(context, asset.container, asset.mediaType) } internal fun createLicenseContainer( @@ -57,17 +65,32 @@ internal fun createLicenseContainer( if (mediaType != MediaType.LCP_LICENSE_DOCUMENT) { throw LcpException.Container.OpenFailed } - return LcplResourceLicenseContainer(resource) + + return when { + resource.source?.isFile() == true -> + LcplLicenseContainer(resource.source!!.toFile()!!) + else -> + LcplResourceLicenseContainer(resource) + } } internal fun createLicenseContainer( + context: Context, container: Container, mediaType: MediaType ): LicenseContainer { val licensePath = when (mediaType) { - MediaType.EPUB -> LICENSE_IN_EPUB.addPrefix("/") + MediaType.EPUB -> LICENSE_IN_EPUB // Assuming it's a Readium WebPub package (e.g. audiobook, LCPDF, etc.) as a fallback - else -> LICENSE_IN_RPF.addPrefix("/") + else -> LICENSE_IN_RPF + } + + return when { + container.source?.isFile() == true -> + FileZipLicenseContainer(container.source!!.path, licensePath) + container.source?.scheme == ContentResolver.SCHEME_CONTENT -> + ContentZipLicenseContainer(context, container, licensePath) + else -> + ContainerLicenseContainer(container, licensePath.addPrefix("/")) } - return ContainerLicenseContainer(container, licensePath) } diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZipUtil.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZipUtil.kt new file mode 100644 index 0000000000..fdcfc35c57 --- /dev/null +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/license/container/ZipUtil.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.license.container + +import java.io.File +import java.io.FileOutputStream +import java.io.InputStream +import java.io.OutputStream +import java.util.zip.ZipEntry +import java.util.zip.ZipFile +import java.util.zip.ZipOutputStream + +internal fun ZipFile.addOrReplaceEntry( + name: String, + inputStream: InputStream, + dest: File +) { + addOrReplaceEntry(name, inputStream, FileOutputStream(dest)) +} + +internal fun ZipFile.addOrReplaceEntry( + name: String, + inputStream: InputStream, + dest: OutputStream +) { + val outZip = ZipOutputStream(dest) + var entryAdded = false + + val newEntry = ZipEntry(name) + newEntry.method = ZipEntry.DEFLATED + getEntry(name)?.let { originalEntry -> + newEntry.extra = originalEntry.extra + newEntry.comment = originalEntry.comment + } + + for (entry in entries()) { + if (entry.name == name) { + addEntry(newEntry, inputStream, outZip) + entryAdded = true + } else { + copyEntry(entry.copy(), this, outZip) + } + } + + if (!entryAdded) { + addEntry(newEntry, inputStream, outZip) + } + + outZip.finish() + outZip.close() +} + +private fun ZipEntry.copy(): ZipEntry { + val copy = ZipEntry(name) + if (crc != -1L) { + copy.crc = crc + } + if (method != -1) { + copy.method = method + } + if (size >= 0) { + copy.size = size + } + if (extra != null) { + copy.extra = extra + } + copy.comment = comment + copy.time = time + return copy +} + +/** + * If STORED method is used, entry must contain CRC and size. + */ +private fun addEntry( + entry: ZipEntry, + source: InputStream, + outStream: ZipOutputStream +) { + outStream.putNextEntry(entry) + source.copyTo(outStream) + outStream.closeEntry() +} + +private fun copyEntry( + entry: ZipEntry, + srcZip: ZipFile, + outStream: ZipOutputStream +) { + addEntry(entry, srcZip.getInputStream(entry), outStream) +} diff --git a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt index ddaabadabd..1d3398c443 100644 --- a/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt +++ b/readium/lcp/src/main/java/org/readium/r2/lcp/service/LicensesService.kt @@ -28,11 +28,13 @@ import org.readium.r2.lcp.LcpService import org.readium.r2.lcp.license.License import org.readium.r2.lcp.license.LicenseValidation import org.readium.r2.lcp.license.container.LicenseContainer +import org.readium.r2.lcp.license.container.WritableLicenseContainer import org.readium.r2.lcp.license.container.createLicenseContainer import org.readium.r2.lcp.license.model.LicenseDocument import org.readium.r2.shared.asset.Asset import org.readium.r2.shared.asset.AssetRetriever import org.readium.r2.shared.extensions.tryOr +import org.readium.r2.shared.extensions.tryOrLog import org.readium.r2.shared.publication.protection.ContentProtection import org.readium.r2.shared.util.Try import org.readium.r2.shared.util.downloads.DownloadManager @@ -64,7 +66,7 @@ internal class LicensesService( is Asset.Resource -> asset.mediaType == MediaType.LCP_LICENSE_DOCUMENT is Asset.Container -> { - createLicenseContainer(asset.container, asset.mediaType).read() + createLicenseContainer(context, asset.container, asset.mediaType).read() true } } @@ -110,7 +112,6 @@ internal class LicensesService( container, authentication, allowUserInteraction, - true, sender ) Try.success(license) @@ -125,12 +126,11 @@ internal class LicensesService( sender: Any? ): Try = try { - val licenseContainer = createLicenseContainer(asset) + val licenseContainer = createLicenseContainer(context, asset) val license = retrieveLicense( licenseContainer, authentication, allowUserInteraction, - false, sender ) Try.success(license) @@ -142,7 +142,6 @@ internal class LicensesService( container: LicenseContainer, authentication: LcpAuthenticating, allowUserInteraction: Boolean, - ignoreInternetErrors: Boolean, sender: Any? ): LcpLicense { // WARNING: Using the Default dispatcher in the state machine code is critical. If we were using the Main Dispatcher, @@ -154,7 +153,6 @@ internal class LicensesService( container, authentication, allowUserInteraction, - ignoreInternetErrors, sender ) } @@ -167,7 +165,6 @@ internal class LicensesService( container: LicenseContainer, authentication: LcpAuthenticating?, allowUserInteraction: Boolean, - ignoreInternetErrors: Boolean, sender: Any? ): License = suspendCancellableCoroutine { cont -> @@ -175,7 +172,6 @@ internal class LicensesService( container, authentication, allowUserInteraction, - ignoreInternetErrors, sender ) { license -> if (cont.isActive) { @@ -188,7 +184,6 @@ internal class LicensesService( container: LicenseContainer, authentication: LcpAuthenticating?, allowUserInteraction: Boolean, - ignoreInternetErrors: Boolean, sender: Any?, completion: (License) -> Unit ) { @@ -198,7 +193,7 @@ internal class LicensesService( val validation = LicenseValidation( authentication = authentication, crl = this.crl, device = this.device, network = this.network, passphrases = this.passphrases, context = this.context, - allowUserInteraction = allowUserInteraction, ignoreInternetErrors = ignoreInternetErrors, + allowUserInteraction = allowUserInteraction, ignoreInternetErrors = container is WritableLicenseContainer, sender = sender ) { licenseDocument -> try { @@ -210,7 +205,9 @@ internal class LicensesService( } if (!licenseDocument.toByteArray().contentEquals(initialData)) { try { - container.write(licenseDocument) + (container as? WritableLicenseContainer) + ?.let { container.write(licenseDocument) } + Timber.d("licenseDocument ${licenseDocument.json}") initialData = container.read() @@ -266,9 +263,14 @@ internal class LicensesService( onProgress = onProgress ) ?: link.mediaType - // Saves the License Document into the downloaded publication - val container = createLicenseContainer(destination, mediaType) - container.write(license) + try { + // Saves the License Document into the downloaded publication + val container = createLicenseContainer(destination, mediaType) + container.write(license) + } catch (e: Exception) { + tryOrLog { destination.delete() } + throw e + } return LcpService.AcquiredPublication( localFile = destination, diff --git a/readium/lcp/src/test/java/org/readium/r2/lcp/license/container/ZipUtilTest.kt b/readium/lcp/src/test/java/org/readium/r2/lcp/license/container/ZipUtilTest.kt new file mode 100644 index 0000000000..8b461df4b0 --- /dev/null +++ b/readium/lcp/src/test/java/org/readium/r2/lcp/license/container/ZipUtilTest.kt @@ -0,0 +1,113 @@ +/* + * Copyright 2023 Readium Foundation. All rights reserved. + * Use of this source code is governed by the BSD-style license + * available in the top-level LICENSE file of the project. + */ + +package org.readium.r2.lcp.license.container + +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.FileInputStream +import java.util.zip.ZipFile +import java.util.zip.ZipInputStream +import kotlin.test.Test +import kotlin.test.assertContentEquals +import kotlin.test.assertNotNull + +class ZipUtilTest { + + private val zipPath: String = + ZipUtilTest::class.java.getResource("futuristic_tales.cbz")!!.path + + private val zipFile: ZipFile = + ZipFile(zipPath) + + private val entryNames: List = listOf( + "Cory Doctorow's Futuristic Tales of the Here and Now/a-fc.jpg", + "Cory Doctorow's Futuristic Tales of the Here and Now/x-002.jpg", + "Cory Doctorow's Futuristic Tales of the Here and Now/x-003.jpg", + "Cory Doctorow's Futuristic Tales of the Here and Now/x-004.jpg" + ) + + private val aFcPath: String = + ZipUtilTest::class.java.getResource("a-fc.jpg")!!.path + + private fun ZipFile.readEntry(name: String): ByteArray? { + val entry = getEntry(name) ?: return null + val stream = getInputStream(entry) + return stream.readBytes() + } + + private fun ZipInputStream.readEntries(): Map { + val modifiedEntries = mutableMapOf() + + do { + val entry = nextEntry + if (entry != null) { + modifiedEntries[entry.name] = readBytes() + } + } while (entry != null) + + return modifiedEntries + } + + @Test + fun addEntryWorks() { + val entryToAdd = "Cory Doctorow's Futuristic Tales of the Here and Now/x-005.jpg" + + val modifiedZip = run { + val outStream = ByteArrayOutputStream() + zipFile.addOrReplaceEntry( + entryToAdd, + FileInputStream(aFcPath), + outStream + ) + outStream.toByteArray() + } + + val modifiedZipStream = ZipInputStream(ByteArrayInputStream(modifiedZip)) + val modifiedEntries = modifiedZipStream.readEntries() + + for (name in entryNames) { + val modifiedEntry = assertNotNull(modifiedEntries[name]) + val expected = zipFile.readEntry(name) + assertContentEquals(expected, modifiedEntry) + } + + assert(entryToAdd in modifiedEntries.keys) + assertContentEquals( + zipFile.readEntry(entryNames[0]), + modifiedEntries[entryToAdd] + ) + } + + @Test + fun replaceEntryWorks() { + val entryToReplace = "Cory Doctorow's Futuristic Tales of the Here and Now/x-004.jpg" + + val modifiedZip = run { + val outStream = ByteArrayOutputStream() + zipFile.addOrReplaceEntry( + entryToReplace, + FileInputStream(aFcPath), + outStream + ) + outStream.toByteArray() + } + + val modifiedZipStream = ZipInputStream(ByteArrayInputStream(modifiedZip)) + val modifiedEntries = modifiedZipStream.readEntries() + + for (name in entryNames) { + val expected = if (name == entryToReplace) { + zipFile.readEntry(entryNames[0]) + } else { + zipFile.readEntry(name) + } + + val modifiedEntry = assertNotNull(modifiedEntries[name]) + assertContentEquals(expected, modifiedEntry) + } + } +} diff --git a/readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/a-fc.jpg b/readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/a-fc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8455b3d4ad45cf5b1210427219c87ad08579b98b GIT binary patch literal 150202 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�nk-lv}r*{-agx>imQjlV^up# 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 bwq)AUf-F;XyN2+VT7-2U~S@rZ)b|{ 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
    ro;JTw3U%?Dj}W=&ZS`q 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%0DgJximuRRQ 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≶Q|Zyse*l@J-9uFALGV5H5e@GgBH{8j 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